Bot

Docker Essentials

A guide to Container Architecture and utilizing Docker to ‘build, ship and run’ your applications.

Especially nowadays, if you are a software developer or planning on becoming one, it is essential to understand and have experience with Docker and the fundamentals of container architecture. This article will give you a good introduction to container architecture and working with Docker, but also why Docker came about in the first place. In fact, let’s talk about the latter first, and it all has to do with Virtual Machines!

Let’s pretend for a second that you are a backend developer, and you just created a Flask application in Python for your awesome new web platform. To run this app, you need a machine to run it on, and the necessary software needed; In this case, Python and Flask. If you are running this app on your laptop, you would just install Python and Flask, and everything will work. But what if you want to push this app onto production on a dedicated machine, for example on DigitalOcean or AWS? Well, this is where Virtual Machines come into play. VM’s were, and still are, a popular way to emulate a computer system on a machine in order to be able to run code in a secluded and customizable environment. So to push your Flask app to production, you could create a VM that has the necessary software installed on a dedicated server, and your app will be live! As with most practices in computer science, there are a few downsides to VM’s. In short, a virtual machine is very heavy-weight, requiring a unique OS for each VM. This requirement generally comes with a decent amount of DevOps work, and results in each VM taking up gigabytes of space and in most cases, long spin-up time. These are some of the cons of VM’s that Docker and Container Architecture fix!

Over the past decade, the world of Software Development is moving increasingly towards utilizing light-weight container architecture to run software. The key idea of this approach is that containers are created ON TOP of the host operating system, for example Linux or Windows. This allows for multiple containers(processes) to run on a single operating system, each in their own secluded environment. Furthermore, because each container utilizes the host’s OS, the size of the containers is usually megabytes in size and have a spin-up time of just seconds.

Docker essentially solves the container problem. It is open-source software created in 2013 that allows us to easily define and run containers for our applications. To get a running container, it is as simple as creating a Dockerfile for your app and running one CLI command! But let’s not take that simplicity for granted and go through the elements of Docker, and then a step-by-step process of getting your first container running on your local machine!

Docker Elements

Don’t worry if some of these do not make sense at first, this is meant to be a reference as you go through the step-by-step example!

A Docker Image is a template of a Dockerized application. This is analogous to how a class is a template for an object in OOP, where here the class is the Docker Image, and the object is the running Docker Container

A running Docker Container(a process), that is based off of a Docker Image

A github-like repository for pre-made Docker Images. This is used to share Docker Images with the Docker community.

A file that defines a Docker Image. This is a set of instructions for how we want to build our Image and usually consists of, among other things, creating directories, installing dependencies, opening ports and defining a command to be run when we create and run a Docker Container based off of this Docker Image.

This is a Docker Image, usually sitting in Docker Hub, from which we can start creating our own Image. This lets us avoid having to start from scratch!

Creating and Running a Docker Container

For this example, I am going to be using a Flask app that I have build previously and “dockerizing” it, a term used for the process of creating a Docker Image for an application.

The Dockerfile

# STEP 1: Install base image. Optimized for Python.
FROM python:3.7-slim-buster

# STEP 2: Install required dependencies.
RUN pip install Flask pillow matplotlib numpy

# STEP 3: Set working directory to /app so we can execute commands in it
WORKDIR /app

# STEP 4: Copy the source code in the current directory to the container location /app
COPY . .

# STEP 5: Set environment variables
ENV FLASK_APP=app.py
ENV FLASK_ENV=development

# STEP 6: Expose the port that Flask is running on
EXPOSE 5000

# STEP 7: Run Flask!
CMD ["flask", "run", "--host=0.0.0.0"]

Let’s go through this Dockerfile line by line.

The first line of every Dockerfile has to begin with the FROM keyword. This defines a base image that we want to use. Since Flask is a Python application, I am using the python base image with version/tag of 3.7-slim-buster, which is a more lightweight version of the Python:3.7 base image.

The RUN keyword will run whatever comes after it as if you were running this command in the terminal. In this case, we are installing the necessary dependencies that this project requires.

The WORKDIR command is essentially like doing a ‘cd’ in the terminal. We are specifying that we want our current directory to be /app, and if this directory does not exist in the docker filesystem, it will create it for us.

The copy command does exactly what you think it does. It copies everything from the specified directory/file on the host filesystem into the specified directory/file on the docker filesystem. In this case, because my Dockerfile is in the root of the project, I copy everything from the current directory(my whole project), into the current directory of the Docker filesystem, which is /app(look at WORKDIR /app)

These two ENV commands set environment variables, just like we would do in our own terminal.

This exposes port 5000! As simple as that

Lastly, we specify the command that we want to run to launch our Flask application.

Build & Run commands

Once we have a Dockerfile defined for our application, we have to build a Docker Image, and can then run a Docker Container based off of this Image.

If our Dockerfile is at the root of the project, we can run the following to build and run our docker container. The dot in the build command defines the context of this build, in this case, it is the current directory, the root of the project

Build: $ docker build -t {image_name} .

Run: $ docker run — name {container_name} -t {image_name}

In the case of this Flask app, my build and run commands where the following

Build: $ docker build -t mtrx:latest

Run: $ docker run -p 5000:5000 — name mtrx_container -t mtrx:latet

And just like that, you have a running Flask Docker Container! — Author

To check if your container is running, you can first of all go to localhost:5000/, or you can run $ docker ps to see current running containers.

Comments