Beginning the Containerization Journey with Docker
Ease your development with Docker.
This article is written as a part of Individual Review competency for Software Projects course 2020 at Faculty of Computer Science, University of Indonesia.
Development phase is an integral part of a software construction. Most of the works done in building the software reside in the development phase. Before we can even put work in constructing the software, we need to prepare our local (PC/machine) environment by installing some required software, tools, etc. For small-scaled software, oftentimes the local environment preparation wouldn’t be too complex. But what if the complexity grows over time or more software are needed to be installed? More installed software means more cluttered our local environment would be. At some cases they could even introduce unnecessary complexity.
That’s when Docker comes to the rescue.
Before talking about Docker, we need to understand what technology Docker is based upon: containerization.
Containerization is a technique to bundle an application together with all of its dependencies. A containerized app can be run quickly without the need of installing its dependencies to our machine/computer, as they are bundled/encapsulated in their respective container.
For example, suppose we need to develop a Django application with Redis in a Windows machine (I know it’s a bad example, but it’s only for illustration purpose). The traditional way would be installing all the dependencies beforehand; that is, Python and Redis. There is a problem with this approach, though. We can’t install Redis properly because currently the latest version of Redis doesn’t support Windows. Sure, we could try a fairly out-of-date Windows port of Redis, but that doesn’t guarantee that it will work currently. Containerization takes care of this problem by making Python and Redis installed only in their respective containers, so this doesn’t affect our Windows machine.
Containerization also allows developers not only to create, but deploy an application faster. Without containerization, transferring a previously deployed application to an entirely new environment or server could result in problems related to that environment. For example, transferring an application from a Linux server to a Windows server could cause problems or bugs. Containerization eliminates this infamous problem.
How come? Each running container is abstracted away or isolated from the host operating system (OS), hence it becomes portable. This capability enables a container to be transferred from a single machine to another.
We know some good points about containerization, now let’s talk about Docker.
Docker is an open-source platform that uses containerization. Similar to containerization in general, Docker enables developers to package applications, along with their dependencies into containers. As Docker is an implementation of containerization, of course developers could containerize their applications without Docker at all, but Docker makes it easier, simpler, and safer to build, deploy, and manage containers. Since its initial release in 2013, Docker has become so popular that it is widely used by developers worldwide.
As a containerization platform, Docker’s objective is to provide:
- An easy and lightweight way to containerize applications in minutes.
- Making Developers care about their applications in the containers and Operations care about managing the containers.
- Fast and efficient development life cycle.
- Encouraging Service-Oriented Architecture (SOA).
Docker Community Edition (the free version of Docker) contains these core components:
- Docker Engine: the client and server part of Docker, which does all the work of core Docker operations.
- Docker Images: the building blocks of an application to be containerized. Basically, a Docker image is a series of steps defined on how to “build” a container. We can think of this as the “source code” for containers.
- Docker Registries: the place where Docker images are stored. Docker has Docker Hub as an official registry to store public images.
- Docker Containers: each container is an instance of running Docker image. A container can contain many types of software: web server, database, application server, etc.
An Example of Running Docker Containers
The example used in this section will be a Django-based application, which I happen to be using in Software Projects course.
I will start with a simple example of defining an image.
To define the steps of building the image, we can create a
I personally put these commands inside the
Dockerfile to the root of Django project:
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONBUFFERED 1
COPY requirements/. /code/requirements/
RUN pip install -r requirements/base.txt
COPY . /code/
Some explanations to each command:
From python:3.7: Uses Python version 3.7 as the base image (the image comes from the Docker Hub). It is required since we need Python first to run a Django application. With this command, we don’t have to install Python locally on our machine.
ENV PYTHONDONTWRITEBYTECODE 1: Prevents Python from writing
.pycfiles when the container is ran.
ENV PYTHONBUFFERED 1: Prevents Python from buffering
WORKDIR /code: Sets the working directory to
/codewhile inside the container (not on the host machine).
COPY requirements/. /code/requirements/: Copy all contents from
requirementsdirectory (inside the host machine) to
/code/requirements/directory (inside the container).
RUN pip install -r requirements/base.txt: Install the dependencies (packages) listed on
base.txt. With this, if we have a local installation of Python on my machine, no packages will be installed there, since this command only affects the Python installation on the container.
COPY . /code/: Copy all Django source code from the current working directory (inside the host machine) to
/code/directory (inside the container).
The content of
Dockerfile above is enough to create a Docker image containing a Django application.
Now comes the next requirement: use PostgreSQL as the database.
Since we use Docker, we don’t need to actually install PostgreSQL to our machine. We can just “pull” the official PostgreSQL image from the Docker Hub then use it alongside the containerized Django application.
But how do we exactly “connect” the two containers? We can use Docker Compose.
Basically, Docker Compose is a tool to define and run multi-container application on a single host machine. With this, we can coordinate the Django and PostgreSQL containers to work with each other.
Compose configuration differs than the basic
Dockerfile since it is configured from a
command: python /code/manage.py runserver 0.0.0.0:8000
Some important points from the above Compose configuration:
- We defined two containers, defined as services, web (Django application) and db (PostgreSQL).
- To build the web container, the previous
Dockerfileis used. The db doesn’t need one since we only need the base image of PostgreSQL.
- The web container depends on the db because we need to make sure that the db container is build and run first.
And we are done. We have containerized Django + PostgreSQL application with Docker.
Docker is so popular for good reasons. It prevents developers from the hassle of configuring development environment, enables easy software shipping and transfer, and more. Docker can be quite hard to digest at first, but it pays off in the long run because of its benefits and potentials.
This wraps up the article. If you have any suggestions, don’t hesitate to comment :)
Thanks for reading!
The Docker Book: Containerization is the New Virtualization — James Turnbull
Explore the history of containerization technology, the benefits and advantages of utilizing the technology, and how it…
What is a Container? | Docker
A container is a standard unit of software that packages up code and all its dependencies so the application runs…
This page describes the commands you can use in a Dockerfile. When you are done reading this page, refer to…