As a developer, I like to have all my dependencies available locally. When the development environment has a database dependency, my preference has been to connect to a local database. As a developer, this gives me the flexibility to try out just about anything without worrying about the impact it might have on others. It is a lot easier when the backend is a mysql or postgresql as getting a local database is a breeze. However, if the backend happens to be a heavy weight database like Oracle – it becomes challenging.
Installing and having Oracle services run on windows is painful. Using the enterprise version maintained by the DBA’s and shared with others in the organization can restrict our freedom. When it comes to software development, we find better ways of doing things when we have the liberty to try out weird stuff. Thomas A Edison said “I have not failed. I’ve just found 10,000 ways that won’t work.”. I never shy away from trying things when playing with technology. This is where Docker comes in handy. I so badly wanted to have my own database that I can twist and turn the way I want during development. I wanted to create an Oracle 12C Docker image that I can use for my development. It took a bit of time to get this to work. So, here’s a blog for those who are interested.
Step1: Download base image from docker hub
There is a decent image to start out with in docker hub at:
https://hub.docker.com/r/laboratoriobridge/oracle-12c
First we need to pull this image. From your linux VM open a terminal and run below command:
1 2 3 4 5 6 7 |
mkdir docker cd docker docker pull laboratoriobridge/oracle-12c |
We could certainly use the base image and get started. However, our need is to have our own userid, with rights to execute DDL’s and DML’s against the database. Even though enterprise manager is available for this version of Oracle and you can create users through enterprise manager – the users you create will be valid only for the specific session. Also, connecting with the new user created after the database service has started running doesn’t work very well with some applications. Best practice in Docker setup is to have the user created and rights assigned during the initial Docker container creation. I took the below steps to get this working:
Step1: Create a db_init.sql
1 2 3 4 5 |
vi db_init.sql |
Add below content to the file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
- user CREATE USER SURESH IDENTIFIED BY password DEFAULT TABLESPACE USERS TEMPORARY TABLESPACE TEMP QUOTA UNLIMITED ON USERS PROFILE DEFAULT ACCOUNT UNLOCK; -- perms GRANT CREATE SEQUENCE TO SURESH; GRANT CREATE SESSION TO SURESH; GRANT CREATE TABLE TO SURESH; GRANT CREATE TRIGGER TO SURESH; GRANT CREATE VIEW TO SURESH; GRANT CREATE PROCEDURE TO SURESH; GRANT CREATE SYNONYM TO SURESH; GRANT CREATE MATERIALIZED VIEW TO SURESH; … … |
You could of course go on to add your DDL’s and table creation scripts in here. The plan is to have this sql executed as part of the container creation so that the database is ready to go for our application when the container is initialized.
Step2: Create sqlnet.ora file
If you plan on connecting to the database using JDBC driver, I noticed that it works only if you have the SQLNET.ALLOWED_LOGON_VERSION=8 configuration setting in your sqlnet.ora file. The docker image we just downloaded does not have this configuration. So, we need to create a sqlnet.ora file and add the setting to it.
1 2 3 4 5 |
vi sqlnet.ora |
Add below line
1 2 3 4 5 |
SQLNET.ALLOWED_LOGON_VERSION=8 |
Save and exit.
Step3: Create a Dockerfile
What is a Dockerfile?
Docker can build images automatically by reading the instructions from a Dockerfile. A Dockerfile is a text document that contains all the commands a user could call on the command line to assemble an image. Using docker build users can create an automated build that executes several command-line instructions in succession. Let us create our own Dockerfile and add commands to copy the sqlnet.ora as well as the db_init.sql into the container. Follow below steps:
1 2 3 4 5 |
vi Dockerfile |
Add below contents:
1 2 3 4 5 6 7 8 9 |
FROM laboratoriobridge/oracle-12c COPY sqlnet.ora /u01/app/oracle-product/12.1.0/xe/network/admin COPY db_init.sql /docker-entrypoint-initdb.d ENV IMPORT_FROM_VOLUME true ENTRYPOINT ["/entrypoint.sh"] |
Above, we are saying that create this image from the docker hub.
Second line we are requesting the sqlnet.ora in our current folder be copied into the network/admin location within the docker container.
Then we are requesting our version of db_init.sql be copied into the docker-endrypoint-initdb.d folder. Why? Because as part of starting up, the image’s entrypoint.sh will look for sql files in this location and execute them against the database. If you so desire to split up your database setup into multiple sql files, you could do that. Just ensure that you are copying them all into the docker-entrypoint-initdb.d folder.
In the last line, we are informing the container that it has to execute the entrypoint.sh file from the root of the image.
Step 4: Build your version of the oracle12 image by running below command from the terminal:
1 2 3 4 5 |
docker build -t oracle12c . |
You should see output like below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
Sending build context to Docker daemon 4.096kB Step 1/5 : FROM laboratoriobridge/oracle-12c ---> 6b168c7ea592 Step 2/5 : COPY sqlnet.ora /u01/app/oracle-product/12.1.0/xe/network/admin ---> Using cache ---> 4cfdb7edb0b3 Step 3/5 : COPY db_init.sql /docker-entrypoint-initdb.d ---> 586d782c29ab Step 4/5 : ENV IMPORT_FROM_VOLUME true ---> Running in 6adc7f3d6c71 Removing intermediate container 6adc7f3d6c71 ---> fb3cf1287222 Step 5/5 : ENTRYPOINT ["/entrypoint.sh"] ---> Running in 4b023f0c5082 Removing intermediate container 4b023f0c5082 ---> 510e9fbff078 Successfully built 510e9fbff078 Successfully tagged oracle12c:latest |
Step5: Verify your docker image has been created by running below command:
1 2 3 4 5 |
docker images |
This should list oracle12 image you created above.
Step 6: Run your docker container
1 2 3 4 5 |
docker run -d -p 8888:8080 -p 1521:1521 oracle12c |
It should produce output like below:
5313e07644c71af14d88ff281c499bb9fa3c634b802a3d43fedc1c9b191757ec
Above you are running the docker container. You are also mapping the container port 8080 and 1521 to the VM hosts port 8888/1521 respectively.
Step 7: Connect to and access your Oracle 12C database from Windows
In order to connect to this database from the windows host, you need to first find the IP of your Ubuntu vm. There are multiple ways of figuring this out. You can run ipconfig on Windows or ifconfig on the Ubuntu vm. But the easiest way I use is to just open a browser from the Ubuntu VM and google for what is my local IP address. The second search result detects and tells me that my IP is 192.168.1.112. So, that is the IP I will connect to.
I update my jdbc setting as:
jdbc:oracle:thin:@//192.168.1.112:1521/xe
With Suresh and password as credentials. Try to connect and voila I am connected. Have my own oracle database to play with and start development. Give it a try and send me your feedback.