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.