Oracle DB12c in Docker

by Seth Miller

Docker has been making a lot of noise in the last couple of years. It piqued my interest recently when I came across a tweet saying that Oracle had recently uploaded an Oracle Linux 7 image to the Docker repository. Containers are nothing new in the Unix space but they are relatively new in Linux. Docker was built to take advantage of Linux Containers.

I asked on Twitter if anyone had successfully installed and run the Oracle Database inside of a Linux Container using Docker. I got a couple of responses that it has been done. I looked around for a blog post or documentation on how to do it and couldn’t find one so, here it is. This is also my first use of Linux Containers and Docker so feel free to comment if there are things that I missed or could do more efficiently.

Note: These instructions presume the user is familiar with VirtualBox and at least an intermediate user of Linux.

Create a small VM. Oracle Linux 7 doesn’t need a lot of horsepower to run. However, Oracle Database will run better with more resources. My VM has 4GB of memory and 25GB of dynamically added disk space. Add a second disk of the same size that will be used for the Docker images. Make sure to include a network adapter that will be able to access the internet.

Start the VM. Since there is no OS on the VM and no mounted ISO, you should be presented with a screen asking which ISO you want to use as a start-up disk.

2015-02-06 23_15_41-OL7 [Powered Off] - Oracle VM VirtualBox


Press enter when the install screen comes up.

2015-02-06 23_17_46-OL7 [Running] - Oracle VM VirtualBox


Choose the language.

2015-02-06 23_19_31-OL7 [Running] - Oracle VM VirtualBox


There should only be one exclamation mark on the screen for the installation destination. Click on the exclamation mark to choose the disk layout. Select the first disk and click Done.

2015-02-11 21_10_52-OL7 [Running] - Oracle VM VirtualBox


Click Begin Installation.

2015-02-06 23_22_35-OL7 [Running] - Oracle VM VirtualBox


The Oracle Linux 7 install is completely different from previous installs. The tasks have become much more parallelized. You may notice that the installation has already begun at this point. While the OS installs, click Root Password.

2015-02-06 23_22_52-OL7 [Running] - Oracle VM VirtualBox


Enter a password for root and click Done.

2015-02-06 23_23_02-OL7 [Running] - Oracle VM VirtualBox


The OS installation will now finish.

2015-02-06 23_23_22-OL7 [Running] - Oracle VM VirtualBox


Once the install is done, click Reboot.

2015-02-06 23_27_10-OL7 [Running] - Oracle VM VirtualBox


Install additional packages that will be needed in the VM to support running Docker.

yum -y --enablerepo=ol7_addons install docker btrfs-progs vim bzip2 kernel-uek-devel-$(uname -r) tigervnc-server xterm xorg-x11-xauth


Add the Guest Additions ISO to the VM by clicking the Devices menu on the VM and clicking Insert Guest Additions CD image.

2015-02-12 17_28_33-OL7 [Running] - Oracle VM VirtualBox


Mount the Guest Additions ISO and install.

mount /dev/cdrom /mnt


Format the second disk in the VM with btrfs. This will be used for the docker images.

mkfs.btrfs /dev/sdb


Query the UUID of /dev/sdb. This will be used in the next step.

blkid /dev/sdb


Create the Docker mount config file /etc/systemd/system/var-lib-docker.mount. Change the UUID to match that of /dev/sdb from the previous step.

Description = Docker Image Store

What = UUID=<UUID from previous step>
Where = /var/lib/docker
Type = btrfs

WantedBy =


Enable the Docker mount.

systemctl enable var-lib-docker.mount


Create the Docker configuration file.

echo 'OPTIONS=-s btrfs' > /etc/sysconfig/docker


Copy the Docker service to systemd to allow you to start and stop the service with systemctl.

cp /usr/lib/systemd/system/docker.service /etc/systemd/system/docker.service


Enable and then start Docker.

systemctl enable docker
systemctl start docker


Pull down the Oracle Linux Docker image. This will require a connection to the internet.

docker pull oraclelinux


View the images currently stored on the VM. This may include more than one since the Oracle Linux Docker image is versioned.

docker images


Install the necessary packages in a container to support the database. The docker run command will create a new container from the image and start it. It will only run as long as the command takes to complete. After it completes. The container will still exist but will not be running.

MYCOMMAND='yum -y --enablerepo=ol7_addons install oracle-rdbms-server-12cR1-preinstall vim bzip2 xorg-x11-xauth xeyes xhost'
docker run --name oraol7 oraclelinux $MYCOMMAND


List the container that was just created. Running the docker ps command without the -a parameter will only show the running containers. Since the container we created is no longer running, it would not show up with only the docker ps command.

docker ps -a


Commit the container just created to a new image. The new image will be a copy of the container but can also be used to create new containers.

docker commit oraol7 oraol7


Now you can see an additional image available in the Docker images. Notice the virtual size of the image just created is significantly larger than the original oraclelinux images.

docker images


The container has been committed to an image so the changes made to the original image have been saved. You can now delete the container.

docker rm oraol7


Notice the container no longer exists.

docker ps -a


Load the Oracle DB12c binaries onto the VM or mount through a shared folder. The files in this case are in the /mnt directory.

Start vncserver on the host VM. Connect to the vnc session on your PC or directly on the VM.



Create a container from the oraol7 image and run it in interactive mode with a bash shell. Give the container a hostname of db12c. Create two directory mappings between the host and the container; one for the DB12c binaries and the other to forward the X11 traffic.

docker run -it --name oraol7 -h db12c -v /mnt:/mnt -v /tmp/.X11-unix:/tmp/.X11-unix oraol7 /bin/bash


You are now at a prompt inside of the running container.

[root@db12c /]$ hostname


Confirm that an X11 application started inside of the container appears in the VNC session.

export DISPLAY=:1.0


Give the rest of the users in the container OS permission to use X11 applications. This is necessary because we need to launch the database installer as oracle. By default, only root has permissions to launch X11 applications.

xhost +


Create a directory in the container for the DB12c install and change the ownership.

mkdir /u01
chown oracle:oinstall /u01


Change user to oracle and start the DB12c installer. The installer application will appear in the VNC session.

su - oracle
export DISPLAY=:1.0


When the install is complete, the database should be running inside of the container.

[oracle@db12c /]$ ps -ef | grep [p]mon
oracle      23     1  0 20:04 ?        00:00:00 ora_pmon_orcl


Shut down the database.

While connected to the container and still the oracle user, create two scripts in the /home/oracle directory called and


export ORACLE_SID=orcl
. oraenv

lsnrctl start
sqlplus / as sysdba << EOF
select status from v\$instance;
select status from v\$instance;

while test $(pgrep ora_pmon_orcl); do
sleep 5


export ORACLE_SID=orcl
. oraenv

lsnrctl stop
sqlplus / as sysdba &lt;&lt; EOF
select status from v\$instance;
shutdown immediate;
select status from v\$instance;


Exit from the container and commit the container to an image.

docker ps -a
docker commit oraol7 oraol7


The oraol7 image virtual size is now close to 12GB.

docker images


Remove the oraol7 container. This is a necessary step because the next step creates a new container with different settings.

docker rm oraol7


Create a new container from the saved oraol7 image. This container will run in the background and start up the database instance. As long as the database instance is running, the container will continue to be active.

docker run -it -d --name oraol7 -h db12c -u oracle oraol7 /home/oracle/


List the containers. Notice there is one container that has a status of Up.

docker ps


The database is running inside of the oraol7 container. You can now connect to that running container in a separate interactive session.

docker exec -it oraol7 /bin/bash


While connected to the oraol7 container, try connecting to the database to confirm it is running.

. oraenv
ORACLE_SID = [] ? orcl
sqlplus system/welcome1@localhost/orcl


Containers can be stopped and started. Stop the oraol7 container.

docker stop oraol7


Now try starting it again.

docker start oraol7


You may run into an error having to do with systemctl when trying to start an existing container. This is a bug. The workaround is to stop the systemd scope listed in the error message.

systemctl stop docker-ebe362b4a4cd81fbf7fa5fef4870a32a423f8586ff187679bebb7e9c77c8f3de.scope


Then try starting the container again.

docker start oraol7


When you want to stop the database and the container it is running in, you could simply kill the container. However, killing the container would cause the database to be in an inconsistent state. The container can be closed cleanly with a consistent database using the script. When the instance is stopped, the original session which ran the /home/oracle/ will stop automatically.

docker exec -it oraol7 /home/oracle/


Keep in mind that any changes that have been made are currently in the container, not the original image. In order to preserve those changes, you would need to commit the container to an image once again. To continue to use the same image name without overwriting the current image as we did previously, you can use a tag.

docker commit oraol7 oraol7:load1


Now you have a container with a database that you can start and stop but it doesn’t do you a lot of good if you can only access it from within the container so we need to make the database (more specifically the listener) accessible from outside the container.

Remove the existing container and start a new one based on the last saved image but this time expose port 1521 on the container to the host OS.

docker rm oraol7
docker run -it -d --name oraol7 -h db12c -u oracle -p 1521 oraol7:load1 /home/oracle/


Find the IP address of the running container.

[root@localhost ~]# docker inspect oraol7 | grep [I]PAddress
        "IPAddress": "",


Connect to the container and add the IP address of the container to the listener.ora.

docker exec -it oraol7 /bin/bash
vim /u01/app/oracle/product/12.1.0/dbhome_1/network/admin/listener.ora


(ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))


Restart the database listener.

. oraenv
ORACLE_SID = [] ? orcl
lsnrctl stop; lsnrctl start


You may need to re-register the database service to the listener.

sqlplus / as sysdba
alter system register;


Back out on the host OS, I can now connect to the database through port 1521. In this case, I downloaded the Oracle Instant Client and connected to the IP address of the container using EZ Connect.

sqlplus64 system/welcome1@