Note: All commands and scripts in this post are based on working with WSL, and are therefore written in Bash.
The goal is to quickly set up an Oracle AI Database 26ai environment on a local machine using Docker, and reach a point where we can connect to the database and start working.
The focus is on:
There are three main approaches:
For fast hands-on work, Docker was chosen for the following reasons:
Before running the command, make sure you have an Oracle (SSO) account and that you have accepted the repository terms in Oracle Container Registry (OCR). Without this, the docker pull will fail.
Registration and terms acceptance (login and click Accept on database/free repo): https://container-registry.oracle.com/
Then login using your Oracle SSO credentials:
docker login container-registry.oracle.com
You will be prompted for:
Downloads the Oracle Database image from OCR. T The first pull may take several minutes.
docker pull container-registry.oracle.com/database/free:latest
A volume is required to persist database data outside the container. Without it, deleting the container may result in data loss, and recreating it will not reuse previous data automatically.
Create a managed volume named oracle26ai-data:
docker volume create oracle26ai-data
To verify the volume exists and inspect it:
docker volume ls
docker volume inspect oracle26ai-data
Important note: Volumes do not have an explicit size limit at creation time. They are limited by available disk space or Docker Desktop configuration. Ensure sufficient space if you plan to load data or build indexes.
This command:
docker run -d \ # Run container in detached mode
--name oracle26ai \ # Assign a friendly container name
-p 1521:1521 \ # Expose Oracle Net port locally
-e ORACLE_PWD=Oracle123 \ # Set initial password for admin users
-v oracle26ai-data:/opt/oracle/oradata \ # Attach volume for persistent data storage
container-registry.oracle.com/database/free:latest # Source image
Official documentation: https://docs.oracle.com/en/database/oracle/oracle-database/26/deeck/
Oracle Container Registry: https://container-registry.oracle.com/
docker logs -f oracle26ai
docker logs -f oracle26ai | grep 'DATABASE IS READY TO USE!'
docker ps
sql "system/Oracle123#@//localhost:1521/FREEPDB1"
select banner_full from v$version;
-- Expected output:
-- Oracle AI Database 26ai Free Release 23.26.1.0.0
show pdbs;
-- Expected output:
-- FREEPDB1 in READ WRITE mode
Once created, the container does not need to be recreated every time.
| Command | What it does |
|—|—|
| docker start oracle26ai | Starts the existing oracle26ai container with the same persisted data. |
| docker stop oracle26ai | Stops the oracle26ai container. The data remains stored and is not removed. |
| docker ps | Shows only the containers that are currently running. |
| docker ps -a | Shows all containers, including running and stopped ones. |
| docker logs oracle26ai | Displays the logs of the oracle26ai container. |
| docker logs -f oracle26ai | Displays the container logs in real time and keeps following new log output. |
—
For a small demo environment, a simple approach works well: back up both configuration and data.
This includes:
Always stop the container before backing up the volume to ensure consistency.
#!/bin/bash
# Backup script for the oracle26ai Docker environment.
# It saves container metadata, volume metadata, and the image name,
# then stops the container, archives the Docker volume data,
# and starts the container again.
# Sagiv Barhoom 2026
set -e # Exit immediately if a command fails.
CONTAINER_NAME=oracle26ai
VOLUME_NAME=oracle26ai-data
BACKUP_ROOT=./backups
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR=${BACKUP_ROOT}/${TIMESTAMP}
mkdir -p "${BACKUP_DIR}" # Creates the timestamped backup directory if it does not already exist.
# Save container configuration and metadata to a JSON file.
docker inspect "${CONTAINER_NAME}" > "${BACKUP_DIR}/container_inspect.json"
# Save Docker volume configuration and metadata to a JSON file.
docker volume inspect "${VOLUME_NAME}" > "${BACKUP_DIR}/volume_inspect.json"
# Save the image name used by the container to a text file.
docker inspect --format='' "${CONTAINER_NAME}" > "${BACKUP_DIR}/image_name.txt"
# Stop the container before backing up the volume data.
docker stop "${CONTAINER_NAME}"
if docker run --rm \ # Runs a temporary container and removes it automatically when finished.
-v "${VOLUME_NAME}":/volume \ # Mounts the Docker volume into the temporary container at /volume.
-v "$(pwd)/${BACKUP_DIR}":/backup \ # Mounts the local backup directory into the temporary container at /backup.
alpine sh -c 'tar czf /backup/oradata.tar.gz -C /volume .'
# Uses Alpine Linux to create a compressed tar.gz archive
# of all data inside /volume and saves it into /backup.
then
# Print success status and the backup file location.
echo "Backup completed successfully. Backup file: $(pwd)/${BACKUP_DIR}/oradata.tar.gz"
else
# Print failure status and the backup directory location.
echo "Backup failed. Check backup directory: $(pwd)/${BACKUP_DIR}"
exit 1
fi
# Start the container again after the backup is complete.
docker start "${CONTAINER_NAME}"
#!/bin/bash
# Restore script for the oracle26ai Docker environment.
# It reads the image name from the backup folder, creates the Docker volume,
# restores the archived Oracle data into the volume,
# and starts a new oracle26ai container using the restored data.
# Sagiv Barhoom 2026
set -e # Exit immediately if a command fails.
BACKUP_DIR=$1
NEW_VOLUME_NAME=oracle26ai-data
# Validate that a backup directory argument was provided.
if [ -z "${BACKUP_DIR}" ]; then
echo "Restore failed. Usage: $0 <backup_directory>"
exit 1
fi
# Read the Docker image name from the backup metadata file.
IMAGE_NAME=$(cat "${BACKUP_DIR}/image_name.txt")
# Create the Docker volume that will hold the restored Oracle data.
docker volume create "${NEW_VOLUME_NAME}"
if docker run --rm \ # Runs a temporary container and removes it automatically when finished.
-v "${NEW_VOLUME_NAME}":/volume \ # Mounts the target Docker volume into the temporary container at /volume.
-v "$(pwd)/${BACKUP_DIR}":/backup \ # Mounts the selected backup directory into the temporary container at /backup.
alpine sh -c 'cd /volume && tar xzf /backup/oradata.tar.gz'
# Uses Alpine Linux to extract the compressed backup archive
# from /backup into the restored Docker volume at /volume.
then
# Print restore success status and the restored volume name.
echo "Restore data extraction completed successfully. Restored volume: ${NEW_VOLUME_NAME}"
else
# Print restore failure status and the backup archive location.
echo "Restore failed during data extraction. Backup file: $(pwd)/${BACKUP_DIR}/oradata.tar.gz"
exit 1
fi
# Start a new oracle26ai container using the restored volume and saved image name.
docker run -d \
--name oracle26ai \ # Creates and starts a container named oracle26ai.
-p 1521:1521 \ # Maps port 1521 from the container to port 1521 on the host.
-e ORACLE_PWD=Oracle123 \ # Sets the Oracle password inside the container.
-v "${NEW_VOLUME_NAME}":/opt/oracle/oradata \ # Mounts the restored Docker volume as the Oracle data directory.
"${IMAGE_NAME}"
# Print final restore status after the container starts.
echo "Restore completed successfully. Container: oracle26ai, Volume: ${NEW_VOLUME_NAME}"