How to create an Oracle 18c client image in Docker

Posted in: Oracle, Technical Track

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.

email

Interested in working with Jared? Schedule a tech call.

About the Author

Oracle experience: started with Oracle 7.0.13 Programming Experience: Perl, PL/SQL, Shell, SQL Also some other odds and ends that are no longer useful Systems: Networking, Storage, OS to varying degrees. Have fond memories of DG/UX

No comments

Leave a Reply

Your email address will not be published. Required fields are marked *