Build a Django Docker Image with Cx-Oracle

Posted by in Software, Tutorial

TL;DR: Don’t use alpine images. There’s a glibc issue.

We added a cx-oracle dependency to one of our django apps. As the previous image was just an alpine basic (python) image we needed to put in place a process to build the new image.

Initially, I’ve tried to use the same alpine image (oh, the slimmed down size is sooo tempting), but then I’ve hit a bunch of “Unknown symbol” messages when I’ve ran the install of cx-oracle in the docker build process. Subsequently, I’ve had to switch to python:3.6-slim-jessie.

The dependencies

Oracle doesn’t play nice with automated downloads (you need to accept licenses etc.), so it’s advisable to download the instaclient binaries and store them locally for consumption. The minimum set of dependencies required for cx-oacle I found to be:

  • instaclinet-basic
  • instaclient-odbc
  • instaclient-sdk
  • instaclient-sqlplus
  • instaclient-tools

To these, you need to add the suffix for platform and version. In my case, it is linux.64-12.2.0.1.0.zip

The Dockerfile

We start the Dockerfile with the base image and the maintainer:

We also have a corporate proxy to go through:

Then we define some environment variables:

And we prepare the work directory:

We copy the docker-entrypoint.sh, the django sources and the oracle instaclinet binaries:

We update the apt indeices and install dependent libaio1:

We then unpack the binaries and install them:

We set up the instaclient environment variables:

We install the necessary python requirements:

We make sure the startup script is UNIX-terminated:

Then, we finish the configuration:

The docker-entrypoint.sh is a simple file starting up the django server on port 8000. It can be as simple as running python manage.py runserver 8000. We found gunicorn more performant though :)

Footnotes

  • This describes a way to do this dependency. Alternatives can include volume-mounted binaries, building an intermediarry image with the binaries (we do this for another app with numpy).
  • As each docker command creates another layer, you may want to squish multiple commands (like the ones unpacking instaclient and the python installation) into a single one.
  • Check the various licenses!

HTH,


A little experiment: If you find this post and ad below useful, please check the ad out :-)