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.