How to Build Docker Images with Dockerfile
6 min read
A Docker image is the blueprint of Docker containers that contains the application and everything you need to run the application. A container is a runtime instance of an image.
In this tutorial, we will explain what Dockerfile is, how to create one, and how to build a Docker image with Dockerfile.
What is Dockerfile
A Dockerfile is a text file that contains all the commands a user could run on the command line to create an image. It includes all the instructions needed by Docker to build the image.
Docker images are made up of a series of filesystem layers representing instructions in the image’s Dockerfile that makes up an executable software application.
The Docker file takes the following form:
# Comment INSTRUCTION arguments
INSTRUCTION is not case-sensitive, but the convention is to use UPPERCASE for its names.
Below is the list with a short description of some of the most used Dockerfile instructions:
- ARG - This instruction allows you to define variables that can be passed at build-time. You can also set a default value.
- FROM - The base image for building a new image. This instruction must be the first non-comment instruction in the Dockerfile. The only exception from this rule is when you want to use a variable in the
FROMargument. In this case,
FROMcan be preceded by one or more
- LABEL - Used to add metadata to an image, such as description, version, author ..etc. You can specify more than one
LABEL, and each
LABELinstruction is a key-value pair.
- RUN - The commands specified in this instruction will be executed during the build process. Each
RUNinstruction creates a new layer on top of the current image.
- ADD - Used to copy files and directories from the specified source to the specified destination on the docker image. The source can be local files or directories or an URL. If the source is a local tar archive, then it is automatically unpacked into the Docker image.
- COPY - Similar to
ADDbut the source can be only a local file or directory.
- ENV - This instruction allows you to define an environment variable.
- CMD - Used to specify a command that will be executed when you run a container. You can use only one
CMDinstruction in your Dockerfile.
- ENTRYPOINT - Similar to
CMD, this instruction defines what command will be executed when running a container.
- WORKDIR - This directive sets the current working directory for the
- USER - Set the username or
UIDto use when running any following
- VOLUME - Enables you to mount a host machine directory to the container.
- EXPOSE - Used to specify the port on which the container listens at runtime.
To, exclude files and directories from being added to the image, create a
.dockerignore file in the context directory. The syntax of the
.dockerignore is similar to the one of the Git's
For a complete reference and detailed explanation of Dockerfile instructions see the official Dockerfile reference page.
Create a Dockerfile
The most common scenario when creating Docker images is to pull an existing image from a registry (usually from Docker Hub) and specify the changes you want to make on the base image. The most commonly used base image when creating Docker images is Alpine because it is small and optimized to be run in RAM.
In this example, we will create a Docker image for the Redis server. We'll use the latest ubuntu 18.04 as a base image.
First, create a directory that will contain the Dockerfile and all the necessary files:
Navigate to the directory and create the following Dockerfile:
FROM ubuntu:18.04 RUN apt-get update && \ apt-get install -y redis-server && \ apt-get clean EXPOSE 6379 CMD ["redis-server", "--protected-mode no"]
Let's explain the meaning of each of the lines in the Dockerfile:
- In line
1we are defining the base image.
RUNinstruction that starts in line
3will update the apt index, install the “redis-server” package and clean the apt cache. The commands used in instructions are the same as the commands you would use to install redis on Ubuntu server.
EXPOSEinstruction defines the port on which the redis server listens.
- In the last line, we are using the
CMDinstruction to set the default command that will be executed when the container runs.
Save the file and close the editor.
Building the Image
The next step is to build the image. To do so run the following command from the directory where the Dockerfile is located:
docker build -t linuxize/redis .
-t specifies the image name and optionally a username and tag in the ‘username/imagename:tag’ format.
The output of the build process will look something like this:
Sending build context to Docker daemon 3.584kB Step 1/4 : FROM ubuntu:18.04 ---> 7698f282e524 Step 2/4 : RUN apt-get update && apt-get install -y gosu redis-server && apt-get clean ---> Running in e80d4dd69263 ... Removing intermediate container e80d4dd69263 ---> e19fb7653fca Step 3/4 : EXPOSE 6379 ---> Running in 8b2a45f457cc Removing intermediate container 8b2a45f457cc ---> 13b92565c201 Step 4/4 : CMD ["redis-server", "--protected-mode no"] ---> Running in a67ec50c7048 Removing intermediate container a67ec50c7048 ---> d8acc14d9b6b Successfully built d8acc14d9b6b Successfully tagged linuxize/redis:latest
WHen the build process is completed the new image will be listed in the image list:
docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE linuxize/redis latest d8acc14d9b6b 4 minutes ago 100MB ubuntu 18.04 7698f282e524 5 days ago 69.9MB
If you want to push the image to Docker Hub see Pushing a Docker container image to Docker Hub.
Running a Container
Now that the image is created you run a container from it by running:
docker run -d -p 6379:6379 --name redis linuxize/redis
-d options tell Docker to run the container in detached mode, the
-p 6379:6379 option will publish the port 6379 to the host machine and the
--name redis option specifies the container name. The last argument
linuxize/redis is the name of the image, which is used to run the container.
When the container starts, use the following command to list all running containers:
docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 6b7d424cd915 linuxize/redis:v0.0.1 "redis-server '--pro…" 5 minutes ago Up 5 minutes 0.0.0.0:6379->6379/tcp redis
To verify that everything works as it should use the
redis-cli to connect to the docker container:
The redis server should respond with
This tutorial covered only the basics of using Dockerfiles to build images. To learn more about how to write Dockerfiles and the recommended best practices see Best practices for writing Dockerfiles.
If you have any questions, please leave a comment below.