How to create custom docker images

Last updated: October 24th 2022

Introduction

In order to run your application in a docker container, a customized docker image is created. This customized docker image includes instructions that install specific packages and copy the code into the docker container. This guide describes the basic steps to create a custom docker image.

Prerequisites

  • Webdock cloud Ubuntu instance (18.04 or later)
  • Clone of a demo node.js project

Writing Dockerfile for custom docker image

Docker builds the docker image by reading the instructions from a text file. By default Docker looks for a file named Dockerfile to build the docker image. The Dockerfile consists of instructions that are used to customize the docker image.

For this guide, we will write a Dockerfile for a node.js application. First go to the root directory of a node.js project.

$ cd node-app

Create a Dockerfile using the following command in the terminal.

$ touch Dockerfile

Open the Dockerfile in your favorite editor.

$ nano Dockerfile

Following is the format of Dockerfile instruction.

INSTRUCTION arguments

The instructions in Dockerfile are not case sensitive but it is convention to use UPPERCASE letters for instructions. Dockerfile builds the docker image by running the instructions in the order they are specified in Dockerfile.

A Dockerfile always starts from a FROM instruction which specifies which base image will be used to create the custom docker image. For example, if you want to create a custom docker image for node.js application, then the node base image will be used as follows.

FROM node:14

If you do not specify a version tag, by default it will use the node image with the latest tag. The base docker image will be pulled from DockerHub if it is not available locally.

Dockerfile provides WORKDIR instruction to set the working directory.

WORKDIR /app

The above instruction will set the working directory to /app inside the container. All the remaining instructions will be executed in this directory.

The COPY and ADD instructions are used to copy data into the docker container. The COPY instruction is only used to copy data from docker host to docker container while the ADD instruction can copy data from docker host and web as well.

Copy the source code into the docker container using the COPY instruction as follows.

COPY . .

This instruction will copy all the data from the working directory of the docker host to the working directory of the docker container.

In order to install new packages or run some shell commands in the base docker image, the RUN instruction is used. For example, in order to install npm packages, the RUN instruction will be used as follows.

RUN npm install

The RUN instruction will run the command in the shell of the docker container.

The EXPOSE instruction is used to expose a port of a container. The port on which the application runs can be exposed using the EXPOSE instruction as follows.

EXPOSE 3000

Now the application running on port 3000 of the docker container will be accessible from docker host when a container is launched using this docker image.

The CMD and ENTRYPOINT instructions are used to execute the shell commands inside the docker container when the docker container starts.

The ENTRYPOINT instruction is used to provide the shell command that runs when the container starts. The default ENTRYPOINT for docker is /bin/sh -c.

While the CMD instruction is used to define the arguments passed to the shell command.

In order to run the /bin/sh -c node index.js command inside the docker container at runtime, use the following CMD instruction.

CMD [“node”, “index.js”]

Following is the final Dockerfile.

FROM node:14

WORKDIR /app

COPY . .

RUN npm install

EXPOSE 3000

CMD [“node”, “index.js”]

Create docker image from Dockerfile

After writing Dockerfile, now run the following command in the terminal to build the docker image from Dockerfile.

$ docker build .

This command will get the Dockerfile from the current working directory and build the docker image.

In order to build the docker image from another directory, specify the path of the directory containing Dockerfile.

$ docker build /home/$USER/

This command will get the Dockerfile from /home/$USER directory and build the docker image.

To build a docker image from a file named other than Dockerfile, specify the Dockerfile name using the -f option.

$ docker build -f Dockerfile.dev /home/$USER/

The above command will build the docker image by reading instructions from Dockerfile.dev file in /home/$USER directory.

Each docker image created using the build command gets a unique ID and all the docker images with their IDs can be listed using the following command.

$ docker images

Tag docker image

The docker image built using the commands described in the previous section does not have a name and tag. Docker tags are helpful to push the docker image to a remote docker repository and specify the docker image version.

Use the following command to tag the docker image.

$ docker tag 21233 node-app:v1

The above command will take a docker image with ID 21233 and add a tag node-app:v1 to it.

Use the following command to list all the docker images with tags.

$ docker images

Push docker image to DockerHub

In order to push the docker image to DockerHub or some other docker image repository, the docker image must be tagged properly. If you want to push a docker image to a docker hub repository, the docker image must be tagged as follows.

example/node-app:v1

Where example is the docker hub account id, node-app is the docker hub repository and v1 is the docker image tag. Use the following command to tag the docker image.

$ docker tag 212233 example/node-app:v1

Before pushing the docker image to docker hub, you must log into the docker hub using command line. Use the following command to log into docker hub.

$ docker login

It will ask for docker hub username and password. After authentication, use the following command to push the docker image to docker hub.

$ docker push example/node-app:v1

Conclusion

A customized docker image can be created by writing instructions in a file named Dockerfile. This guide explains how different instructions can be used in Dockerfile to create a custom docker image.