Dockerize your Python Modules

4 min read
Dockerize your Python Modules

You probably have heard of Docker. Docker is a virtualization software which isolates environments in OS-level. Think of it as running another operating system on your computer. Docker is very useful when building applications because it creates an isolated environment. It solves one common issue in computer programming:

Client: It is not working.
Developer: It works on my machine!

This is true. Development environments are most of the time different from staging environments and production environments. You are probably writing your software on MacOS or Windows but you're deploying it on Linux. Because of the differences on these operating systems, we end up with a broken software.

Docker helps to consistently develop, test and deploy software in one single operating system. In addition, because it is an isolated environment, we can prevent unnecessary changes both to our development machines and to the docker containers. Docker also reduces the cost of buying multiple hardware just to host different operating systems.

This article focuses on how to use docker on a MacOS.

Download VirtualBox

I recommend to download and install VirtualBox manually from their website because it is easier than installing it from terminal. Download and install VirtualBox for MacOS from https://www.virtualbox.org/wiki/Downloads.

After running the installer, you will probably notice that it will fail.

To fix the issue above, open System Preferences > Security & Privacy. Click the lock on the bottom left corner of the window to make changes. Click the Allow button to allow the installation. You may now again run the VirtualBox installer.

Install Homebrew

Let us use Homebrew to install docker. Installing libraries and applications in Homebrew is simpler as we will only be using the terminal. Note that we did not use Homebrew to install VirtualBox because there will be additional commands that we need to run and it will be simpler by running the installer.

To install Homebrew, open the terminal and run the following command:

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"

Install docker and docker-compose

Using Homebrew, install docker and docker-compose in the terminal. These are the utilities that we will need to setup our docker containers.

brew install docker docker-compose

Create environment

To create an environment, run the following in the terminal:

docker-machine create default --driver virtualbox

The above command creates a virtual machine named default in VirtualBox. docker-machine sets up everything that we need in a docker container.

Start environment

To start the virtual machine, simply run the following command in the terminal:

eval $(docker-machine env default)

Example module

Let us use the amortization module which I often use on my blogs. The first step is to clone the source code from Github.

git clone https://github.com/roniemartinez/amortization.git
cd amortization

Next step is to create a file named Dockerfile and write the following:

FROM python:3.7
MAINTAINER Ronie Martinez <ronmarti18@gmail.com>

WORKDIR /app
COPY . /app

RUN pip install pipenv
RUN pipenv install --dev --skip-lock -v

In the above, the FROM instruction uses the python:3.7 image as the base image. It means that whatever is installed in the base image will also be copied into our docker image. To read more on the python images available, visit the Docker Hub.

The MAINTAINER instruction indicates the name of the maintainer. This is optional.

The WORKDIR instruction sets up the working directory in the container.

COPY . /app copies all the contents in our current project directory to the container folder /app. Note that if you want to ignore files and folders like .pyc files and __pycache__ folders, simply write a .dockerignore file containing all the files that you do not want to copy into the docker image.

The RUN instruction is used to execute commands.

Building docker image

To create a docker image, run the following:

docker build -t amortization .

The command above creates a docker image named amortization. You can check if the docker image has been built by running docker image ls. In the example below, we can see 2 images. The python image was downloaded when we used it as a base image.

% docker image ls    
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
amortization        latest              6e515e76956c        3 minutes ago       1.01GB
python              3.7                 f66befd33669        10 days ago         919MB

Testing your module

The module uses pytest for testing. Simply run the following:

docker run amortization pipenv run pytest -vv

Simplifying your Dockerfile

You probably do not want to use pipenv because it will just create another virtual environment inside your container. amortization uses pipenv for development only. To simplify your Dockerfile, strip the pipenv installation and just use pip.

FROM python:3.7
MAINTAINER Ronie Martinez <ronmarti18@gmail.com>

WORKDIR /app
COPY . /app

# install dependencies
RUN pip install tabulate pytest

You can now again rebuild the docker image:

docker build -t amortization .

The removal of pipenv removed another layer from our docker image. To test using pytest, you can simply run the following:

docker run amortization pytest -vv

Stopping environment

To stop our virtual machine, simply run the command:

docker-machine stop

Conclusion

Docker simplifies development, testing and deployment using a single operating system consistently. It also reduces the cost of buying hardware by using virtualization. With docker containers, it is easier to migrate our applications from classic on-premise hardware to cloud infrastructure.

Read more articles like this in the future by buying me a coffee!

Buy me a coffeeBuy me a coffee