Docker : Oracle Database on Docker
This article describes a simple build for running an Oracle database on Docker.
- Build the Image
- Run a Container
- Persistent Storage
- start.sh Script
- healthcheck.sh Script
- Managing the Container
This article assumes the following.
- You already have a suitable installation of the Docker Engine. Oracle products are supported on Docker if the host OS is Oracle Linux 7, but you don't need to use an OL7 host for this to work. You can see how to install Docker on OL7 here.
- You have a basic understanding of Docker and Dockerfiles. You can read an introduction to Docker here, and some basics about writing Dockerfiles here.
- You understand this is an example of a Dockerfile to build an image to run an Oracle database. It's not meant to be a definitive or supported build. If you want something more generic, you might was to check out the builds and images from Oracle here.
Build the Image
The Dockerfile and scripts this article is based upon can be found here. The build expects the following file system. You will have to download the Oracle 19c database and APEX software yourself and place it in the "software" directory.
$ tree . ├── Dockerfile ├── README.md ├── scripts │ ├── healthcheck.sh │ └── start.sh └── software ├── apex_20.2_en.zip ├── LINUX.X64_193000_db_home.zip └── put_software_here.txt $
The Dockerfile contains some basic instructions, which will be described further here.
With all the files in place you can build the image using the following command.
$ #Docker $ docker build -t ol7_19:latest . $ #Podman $ docker build --format docker -t ol7_19:latest .
The build performs the following actions.
- The build starts by defining some environment variables. The first section contains fixed environment variables. If you want to alter any paths or software versions they need to be reflected here. The
PATHenvironment variable is set based on the value of the
ORACLE_HOMEenvironment variable. The next section defines those environment variables that can be set at runtime to alter the database running in a container.
- The software and scripts are copied to the correct locations in the image, "/u01/software" and "/u01/scripts" respectively.
- The first
RUNoperation creates the "oinstall" group and "oracle" user, installs the prerequisite software and creates the required directories with the correct permissions.
- After switching to the "oracle" user the database software is unzipped, the original media deleted to save space in the image, and a silent software-only installation of the database is performed.
- The default APEX software under the
ORACLE_HOMEis removed and replaced by the version copied to the "/u01/software" directory.
- After switching to the "root" user the "orainstRoot.sh" and "root.sh" scripts are run to complete the Oracle software-only installation.
- After switching to the "oracle" user, we mark "/u02" as a volume, expose the ports to allow external connections to the database, and reference the "healthcheck.sh" and "start.sh" scripts for use when a container is run based on this image.
You will notice the build phase doesn't create a database. That is done on the first run of a container.
Run a Container
The database is created the first time the container is started, which means it can take some time for the container to be fully operational, especially because we are also doing an APEX installation into the database.
The simplest way to run a container based on this image is to accept all the defaults and run the following command. It gives the container a name (ol7_19_con), binds a host port to the exposed container port.
$ docker run -dit --name ol7_19_con \ -p 1521:1521 \ --shm-size="1G" \ ol7_19:latest
In the previous example the storage is not persistent, so if the container were removed the database files would be lost. We can solve this problem by creating a directory on the host file system and mounting it to "/u02" in the container. Now the data files reside outside the container. See the Persistent Storage section about the setup of the host volume.
$ mkdir -p ~/volumes/ol7_19_con_u02/ $ docker run -dit --name ol7_19_con \ -p 1521:1521 \ --shm-size="1G" \ -v /u01/volumes/ol7_19_con_u02/:/u02 \ ol7_19:latest
We could have used a managed volume or a data volume container instead. These approaches are described here.
In the previous examples we've exposed the database to the outside world, but if we want other containers to speak directly to it, we must create a Docker network and associate the container with that network.
$ docker network create my_network $ docker run -dit --name ol7_19_con \ -p 1521:1521 -p 5500:5500 \ --shm-size="1G" \ --network=my_network \ -v /u01/volumes/ol7_19_con_u02/:/u02 \ ol7_19:latest
So far we have relied on the default settings for the database creation, but we can influence this by setting the appropriate environment variables in the run command.
$ docker run -dit --name ol7_19_con \ -p 1521:1521 -p 5500:5500 \ --shm-size="1G" \ -v /u01/volumes/ol7_19_con_u02/:/u02 \ -e "ORACLE_SID=cdb2" \ -e "SYS_PASSWORD=SysPassword2" \ -e "PDB_NAME=pdb2" \ -e "PDB_PASSWORD=PdbPassword2" \ -e "APEX_EMAILfirstname.lastname@example.org" \ -e "APEX_PASSWORD=ApexPassword2" \ ol7_19:latest
If you are using an external host volume for persistent storage, the build expects it to owned by a group with the group ID of 1042. This is described here.
The start.sh script is responsible for creating the database on the first run of the container. It performs the following actions.
- Defines the "gracefulshutdown" function to turn off the database and associates it with the
- Defines the "fixConfig" function to create symbolic links to important config files from persistent storage. This will become obvious later.
- Check if the database already exists under the "/u02/oradata" location. If not, create the database.
- Start the listener.
- Use the DBCA to silently create a database.
- Turn on Oracle Managed Files (OMF) and make sure the PDB automatically starts on restart.
- Copy some important config files to the "/u02/config" directory and run the "fixConfig" function to create symbolic links to the new locations where possible. The "/etc/oratab" file must be copied, not linked.
- Perform a silent installation of APEX
- If the database was already present, it means this could be a new run of the base image, pointing at a persistent volume already containing the database. In this case, run the "fixConfig" function to recreate the symbolic links and copy back the "/etc/oratab" file, then start the database.
- Tails the alert log as a background process and waits on the resulting process ID. If this tail ends the container will be turned off.
The healthcheck.sh script is really simple. It connects to the database and runs a query. If the query is successful it returns "0", otherwise it returns "1".
Managing the Container
Once the container is running you can connect to a bash shell using the following command.
$ docker exec -it ol7_19_con bash
The container can be stopped and started using the following commands. The "--time" parameter give the database a chance to shutdown gracefully. Restarting the container has no impact on ephemeral storage, so no data will be lost, even if you are not using persistent storage.
$ docker stop --time=30 ol7_19_con $ docker start ol7_19_con
The following command removes the container and the associated volumes. If you are not using persistent storage this will result in the loss of the database files.
$ docker rm -vf ol7_19_con
For more information see:
Hope this helps. Regards Tim...