Pythian Blog: Technical Track

How to create an Oracle 18c client image in Docker

In a previous blog How to use Oracle instant client docker images, I described how to obtain and customize an Oracle 12.2 Instant Client Docker Image. At the end of the article, I wistfully stated an 18c client would also be nice. As it turns out, Oracle has published the Dockerfile used to create an 18c Instant Client Image. In this blog, I will modify that Dockerfile and add some customizations, then build and test an 18c Instant client Docker will need to login to the Oracle Container Registry to get the Docker Image oraclelinux:7-slim. If you have not already set up your account at the Oracle Container Registry, please refer to the previous article as noted earlier. The first thing to do is get the Oracle Docker Images repo:
$ cd
 $ mkdir -p ~/docker/oracle
 $ cd ~/docker/oracle
 $ git clone git://github.com/oracle/docker-images.git
 $ cd OracleInstantClient/dockerfiles/18.3.0
 $ pwd
 /home/jkstill/docker/oracle/docker-images/OracleInstantClient/dockerfiles/18.3.0
 

Dockerfile

There are some minor customizations I will add to the Docker image:
  • some additions to ~root/.bashrc
    • I find these useful should I log in to the image with /bin/bash
  • configure ldap.ora
  • configure TNS_ADMIN
  • configure SQLPATH
Following that, I will build the Docker image for 18.3 as per Oracle Instructions in docker-images/OracleInstantClient, with some modifications. First, back up the Dockerfile, and then add the text as directed. You will, of course, need to modify this as per your own preference, or you may choose not to do this at all.
$ cp Dockerfile Dockerfile.save
 
Add the following to the end of Dockerfile:
run echo "alias l='ls -la'" >> /root/.bashrc
 run echo "unalias ls 2>/dev/null" >> /root/.bashrc
 run echo "set -o vi" >> /root/.bashrc
 
 # optionally set the working directory
 workdir /usr/lib/oracle/18.3/client64
 
 run mkdir -p /opt/sql-lib
 run mkdir -p /opt/sql
 
 env SQLPATH=/opt/sql-lib:/opt/sql
 
 env TNS_ADMIN=/usr/lib/oracle/18.3/client64
 run mkdir -p ${TNS_ADMIN}
 
 run touch ${TNS_ADMIN}/ldap.ora
 run echo 'DIRECTORY_SERVERS=(192.168.1.2:389:636)' > ${TNS_ADMIN}/ldap.ora
 run echo 'DEFAULT_ADMIN_CONTEXT = "dc=jks,dc=com"' >> ${TNS_ADMIN}/ldap.ora
 run echo 'DIRECTORY_SERVER_TYPE = OID' >> ${TNS_ADMIN}/ldap.ora
 
 
Rather than the specified oracle/instantclient:18.3.0 I will build the image as jkstill/oracle-18.3-instantclient:latest. This may take a few minutes as Docker downloads the required files.
$ docker build --tag jkstill/oracle-18.3-instantclient:latest .
  
  ...
  
 $ docker image ls
 REPOSITORY TAG IMAGE ID CREATED SIZE
 jkstill/oracle-18.3-instantclient latest a4c5d73339f3 4 minutes ago 362MB
 oracle/instantclient 18.3.0 21876880691f About an hour ago 362MB
 jkstill/oracle-12.2-instantclient latest 58891599275e 5 days ago 407MB
 ...
 
 
Now to test the image:
$ docker run --dns=192.168.1.2 --dns-search=jks.com -ti --rm jkstill/oracle-18.3-instantclient sqlplus -L jkstill/XXX@p1
 
 SQL*Plus: Release 18.0.0.0.0 - Production on Wed Jan 2 21:08:21 2019
 Version 18.3.0.0.0
 
 Copyright (c) 1982, 2018, Oracle. All rights reserved.
 
 Last Successful login time: Wed Jan 02 2019 21:00:09 +00:00
 
 Connected to:
 Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
 
 SQL>
 
 
Success! ## An enhanced Bash driver The following is a Bash script _do.sh_ that I use to connect via the 12.2 or 18c. clients:
#!/usr/bin/env bash
 
 : << 'COMMENTS'
 
  do.sh - Docker Oracle sqlplus driver
 
  get usage with 'usage=1 do.sh'
 
 
 COMMENTS
 
 ###########################
 # Setup Default Vars
 ###########################
 declare -A defaults
 
 defaults[version]='12.2'
 defaults[instance]='p1'
 defaults[username]='jkstill'
 defaults[password]='grok'
 defaults[debug]=0
 defaults[noconnect]=0
 defaults[bash]=0
 defaults[login]=1
 defaults[script]=''
 
 debug=${debug:-${defaults[debug]}}
 usage=${usage:-${defaults[usage]}}
 noconnect=${noconnect:-${defaults[noconnect]}}
 bash=${bash:-${defaults[bash]}}
 version=${version:-${defaults[version]}}
 password=${password:-${defaults[password]}}
 username=${username:-${defaults[username]}}
 instance=${instance:-${defaults[instance]}}
 login=${login:-${defaults[login]}}
 
 ###########################
 # Setup docker images
 ###########################
 
 declare -A dockerImages
 
 # there should be a 'latest' tag for these images
 # if not then the tag must be included
 # eg.
 # jkstill/oracle-12.2-instantclient:version10
 dockerImages[12.2]='jkstill/oracle-12.2-instantclient'
 dockerImages[18.3]='jkstill/oracle-18.3-instantclient'
 
 usage () {
 
  local cmdName=$(basename $0)
 
 cat <<-EOF
 
  ${cmdName}: Docker Oracle sqlplus driver
 
  Set the following variables as needed and call $cmdName
 
  debug: 0|1 - default is 0
  displays information to the terminal
 
  usage: 0|1 - default is 0
  display usage and exit
 
  version: 12.2|18.3 - default is 12.2
  set the client version - there must be a correpsonding Docker image
 
  username: scott|whatever
  password: tiger|whatever
  instance: orcl|whatever
 
  noconnect: 0|1
  exit the script before connecting
  automatically sets debug on
 
  login: run login.sql to start with - defaults to 1 (yes)
  script: script to run a login - prevents running login.sql
 
  bash: run bash instead of sqlplus
 
  default valued may be changed by editing the \$defaults array
 
 EOF
 
 }
 
 # set docker image name
 declare dockerImage=${dockerImages[$version]}
 
 # verify we know about it
 [[ -z $dockerImage ]] && {
  echo
  echo "Docker image not found for version $version"
  echo
  usage
  exit 1
 }
 
 if [[ $noconnect -ne 0 ]]; then
  debug=1
 fi
 
 if [[ $usage -ne 0 ]]; then
  usage
  exit 0
 fi
 
 
 if [ -n "$sysdba" ]; then
  sysdba=' as sysdba'
 else
  sysdba=''
 fi
 
 # run login script if login == 1 and script == ''
 
 declare scriptToRun='';
 
 if [[ -n "$script" ]]; then
  scriptToRun="@$script"
 else
  if [[ $login -ne 0 ]]; then
  scriptToRun='@./login.sql'
  fi
 fi
 
 # build the command to prompt for password if not supplied
 if [[ "$bash" -ne 0 ]]; then
  myCmd="/usr/bin/env bash"
 else
  if [[ -n "$password" ]]; then
  myCmd="sqlplus -L ${username}/${password}@${instance} ${sysdba} ${scriptToRun}"
  else
  myCmd="sqlplus -L ${username}@${instance} ${sysdba} ${scriptToRun}"
  fi
 fi
 
 
 [[ $debug -gt 0 ]] && {
  echo " Username: $username"
  echo " Password: $password"
  echo " Instance: $instance"
  echo " noconnect: $noconnect"
  echo " bash: $bash"
  echo " Sysdba: $sysdba"
  echo "dockerImage: $dockerImage"
  echo " CMD: $myCmd"
 }
 
 if [[ $noconnect -ne 0 ]]; then
  exit 0
 fi
 
 if [[ $debug -ne 0 ]]; then
  set -v
 fi
 
 docker run --dns=192.168.1.2 --dns-search=jks.com -ti --rm \
  --mount type=bind,source=/home/jkstill/oracle/oracle-script-lib/sql,target=/opt/sql-lib \
  --mount type=bind,source=/home/jkstill/oracle/admin/sql,target=/opt/sql \
  $dockerImage $myCmd
 
 
Test run:
$ debug=1 version=18.3 do.sh
  Username: jkstill
  Password: XXX
  Instance: p1
  Sysdba:
 dockerImage: jkstill/oracle-18.3-instantclient
  CMD: sqlplus -L jkstill/XXX@p1
 
 docker run --dns=192.168.1.2 --dns-search=jks.com -ti --rm \
  --mount type=bind,source=/home/jkstill/oracle/oracle-script-lib/sql,target=/opt/sql-lib \
  --mount type=bind,source=/home/jkstill/oracle/admin/sql,target=/opt/sql \
  $dockerImage $sqlCmd
 
 SQL*Plus: Release 18.0.0.0.0 - Production on Wed Jan 2 21:29:31 2019
 Version 18.3.0.0.0
 
 Copyright (c) 1982, 2018, Oracle. All rights reserved.
 
 Last Successful login time: Wed Jan 02 2019 21:24:33 +00:00
 
 Connected to:
 Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
 
 SQL> @who
 
 USERS LOGGED ON SESSIONS
 --------------- ----------
 JKSTILL 1
 SYS 1
 
 SQL>
 
 
 
Building the image directly by modifying the Dockerfile was much simpler than modifying the existing image as seen in my previous blog on this topic. In any case, you can see that obtaining and using the latest release of an Oracle client is greatly simplified by the use of Docker.

No Comments Yet

Let us know what you think

Subscribe by email