Skip to main content

A quick guide to writing a Dockerfile and building a Docker image

6 minutes


Introduction

A Dockerfile is a text document that contains simple instructions for building Docker images from scratch. During build time, the command docker build tells Docker to build the image by following the commands (instructions) specified in the Dockerfile.

The instructions in the Dockerfile may include installing dependencies, copying files, setting environment variables, exposing ports, and few more. Each Dockerfile instruction  contributes to the creation of Docker image that can be used to create containers. 

In this article, we will go through the steps of building a Dockerfile and creating a Docker image from CLI.

Why do we need Dockerfile?

We need a Dockerfile to build docker image from the given instructions from it.  By providing instructions in a Dockerfile, it acts as a recipe for building a Docker image. These instructions lets you define environment and configuration of the container within which the application will run.

Essentially, a Dockerfile specifies a set of guidelines about structure of image, dependencies and how the application should behave within the container. 

Moreover, A Dockerfile imparts developers to have a complete control over the application runtime environment and ensures all requirements are meet for running container applications.

Prerequisites

The only prerequisite for Dockerfile is Docker is installed in your system. Follow this guide if Docker is not installed in your system.

 

 

Creating a Dockerfile

Let’s find out how to create a Dockerfile and write instructions in it. We will create a dockerfile for a Python application and will have the following points.

  • The Dockerfile will define environments for a Python-based flask web application.
  • The instructions in the Dockerfile will maintain a logical step-by-step order.
  • The instructions in the Dockerfile will use the existing standard instructions like FROM, ENV, EXPOSE, and many more.

Let's name our web application flask-app. The Dockerfile and the codes/structure for the Flask web application are available on GitHub. For reference, the structure of the web application is given below.

Web application structure
 

As shown above, the folder for the flask application(flask-app) encapsulates the Dockerfile, dependencies, and other resources for Docker to build image by reading instructions from the Dockerfile.

The Dockerfile reference for the flask application is listed next.

# Starting point, a base image
FROM python:3.8
# Working directory for the web app
WORKDIR /usr/src/app
# Copy all the files to the container
COPY . .
# Install web application dependencies
RUN pip install --no-cache-dir -r requirements.txt
# Web app port number that the container should expose
EXPOSE 5000
# Run the web application
CMD ["python", "./app.py"]

Dockerfile instructions

The instructions that you write in the Dockerfile start with a specific word(in capital letters) that dictates how to build a Docker image. The Dockerfile instructions we used in the Dockerfile are:

FROM
The Dockerfile FROM instruction specifies the base image for the new image. All the subsequent instructions from the Dockerfile will be executed on this base image.

WORKDIR
Define the working directory and it is used in conjunction with subsequent RUN, CMD, ENTRYPOINT, COPY, and ADD instructions.

COPY
Copy files, directories, and any other resources to the Docker image.

RUN
This instruction is used to execute commands.

EXPOSE
The EXPOSE instruction is used to inform users about the ports the application is listening on.

CMD
It provides a default command to run along with parameters if any for the container.

The second part of the instructions in a Dockerfile are similar to the Linux commands. For example, the Dockerfile syntax to create a folder in a WORKDIR say /usr/src/app is:

...
...
WORKDIR /usr/src/app 
RUN mkdir -p image
...
...

There are 18 Dockerfile instructions and are:

FROM, MAINTAINER, RUN, CMD, ENTRYPOINT, ADD, COPY,  EXPOSE, ENV,  VOLUME, WORKDIR, USER, ARG, ONBUILD, STOPSIGNAL, LABEL, HEALTHCHECK, SHELL.

Any of these commands or instructions in a Dockerfile are invoked by the user on the CLI to assemble an docker image.

Create Docker image

Once you complete writing instructions in the Dockerfile and compiled codes, and other resources needed by the application - build Docker image with the docker build command. The image build process will start from the first line by pulling the python:3.8 image which is known as Dockerfile base/parent image and will proceed sequentially one by one. 

Run the following command to builld docker image. You can view the output of the image build process on the screen. If everything goes fine, your docker image from Dockerfile should be ready!

$ cd ~/flask-app
$ ~/flask-app$ docker build .
[+] Building 521.2s (10/10) FINISHED                                                                                                                      docker:default
 => [internal] load build definition from Dockerfile                                                                                                                0.0s
 => => transferring dockerfile: 340B                                                                                                                                0.0s
 => [internal] load metadata for docker.io/library/python:3.8                                                                                                       7.0s
 => [auth] library/python:pull token for registry-1.docker.io                                                                                                       0.0s
 => [internal] load .dockerignore                                                                                                                                   0.0s
 => => transferring context: 2B                                                                                                                                     0.0s
 => [1/4] FROM docker.io/library/python:3.8@sha256:6ea16099cac9f66419d1fc3a63aaa9d783214e8e38d2a1c0db2bfb0852ef9b7d                                               504.5s
 => => resolve 
....
....
....

Run the following docker images command and check if it shows your image.

$ docker images
REPOSITORY                                      TAG       IMAGE ID       CREATED        SIZE
<none>                                          <none>    07ff569194e1   2 weeks ago    83.2MB

 Each instruction in the Dockerfile corresponds to an image layer and is stacked on top of each other to form the final Docker image. An image layer is the fundamental building block of a Docker image and there can be many image layers in a Docker image.

Web application structure  

 

Docker starts to build from Dockerfile by taking python:3.8 as the base image and then creating an intermediary image for every instruction it executes. Docker adds the build files from the intermediary step as another layer on top of the base image.

Create container

The docker image is now ready to be used as a container. To create a container from the above Docker image,  use the following docker run command with image ID as an argument.

$ docker run 07ff569194e1
* Serving Flask app 'app'
* Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on all addresses (0.0.0.0)
* Running on http://127.0.0.1:5000
* Running on http://172.17.0.2:5000
Press CTRL+C to quit

Point your web browser to the URL displayed on the screen to access the web application.

Web application structure  

Tag a Docker image

It gets difficult to identify an image when you are working with a large number of them. Docker provides a option to tag an Docker image with names of your choosing. Let's tag the Docker image that we have created with the following command. 

$ docker build . -t yourusername/flask-app

Run the docker images command and verify the tagged name associated with the image.

 $ docker images
REPOSITORY                  TAG     IMAGE ID          CREATED         SIZE
yourusername/flask-app       latest   e85b2852ee8c   8 minutes ago   83.2MB

Push Docker image to Docker Registry

The Docker image that you have created previously is stored in your local system. This implies that you cannot access or use it from other work stations. You must push the Docker image to a Docker registry in order for it to be used elsewhere.

Docker images are stored in a Docker registry. Docker Hub is one of the well-known Docker registries. To push Docker images to Docker Hub, you'll need an account. Create an Docker hub account if you don't have the one.

Once you have created your account, Login to the docker hub by providing your user name and password/token.

$ docker login

Re-tag the previous docker image with your docker hub user name and a tag.

$ docker tag yourusername/flask-app yourdockerhubusername/flask-app:v1

Finally push the image to the Docker hub.

$ docker push yourdockerhubusername/flask-app:v1

You can now run the Docker container by using the pushed docker image from anywhere.

$ docker run  yourdockerhubusername/flask-app:v1

 

 

Conclusion

The article briefly describes a Dockerfile structure and how to start writing a Dockerfile.  Moreover,the article also shows how to build docker image, tag a docker image and push the image to the Docker hub. More references in the Dockerfile can be found on Docker's online documentation.

fivestar_rating
Average: 4.5 (2 votes)
Related Post
How to install docker in Ubuntu 24.04 How to install docker in Ubuntu 24.04
7 minutes / Aug ' 22 2024
Comments