Dockerfile Essentials: Defining and Building Containerized Apps

watch 6m, 50s
views 2

10:37, 29.05.2026

Article Content
arrow

  • Introduction to Dockerfile 
  • Essential Instructions Used in a Dockerfile 
  • Sample Workflow: Writing and Applying a Dockerfile
  • Steps to Build Your Dockerfile 
  • Options Available During Docker Build 
  • Running and Using the Created Image 
  • Recommended Dockerfile Practices 
  • 1. Avoid Using `latest` Tag for Base Images 
  • 2. Choose Base Images from Trusted Sources Only 
  • 3. Implement HEALTHCHECK to Monitor Container Status 
  • 4. Configure ENTRYPOINT and CMD Properly 
  • 5. Never Store Secrets Directly in Images 
  • 6. Add Labels to Organize and Track Your Images 
  • 7. Run Containers Using a Non-Root User 
  • 8. Use `.dockerignore` to Speed Up the Build Process 
  • 9. Optimize Image Size Whenever Possible 
  • 10. Use Linters and Vulnerability Scanners for Security 
  • Summary of Key Takeaways

Docker is a platform needed for running and, more importantly, for building containerized apps. With the help of containers, it is possible to pack the dependencies, source code, and runtime environment. This can be done via the Docker installation on your machine or a Kubernetes cluster for the infrastructure.

When the containers are launched, there is a necessity for the container image. The images specify the initial state of container filesystems. This can be done with the Dockerfile, and in the article, we will guide you through the process of building containerized apps and some helpful practices.

Introduction to Dockerfile 

Dockerfiles include instructions in the form of text that are needed for building the container image. To process all the instructions in the file for the image assembling, you should use the following command:

docker build

After the usage of this command, all the instructions are processed sequentially. When the line starts with #, it is not a command but a comment or interpretation of the command. The arguments in the lines can be divided with a backslash.

Essential Instructions Used in a Dockerfile 

There are more than 15 instructions that can be used in a Dockerfile for setting some configurations and adding content.  Here is the list of the most popular ones:

  • FROM is usually at the beginning of the file and is the basis for building.
  • COPY is needed for adding folders/files to the filesystem. The copying process is done between the image and the Docker host.
  • ADD works in a similar way to the above-mentioned instruction, but it also supports archive extractions and file URLs. The usage of ADD can simplify some tasks. For instance, archive files are extracted in the container instead of just copying them.
  • RUN is used for the command running in the image. This means a new image layer is created with some needed changes. Usually, this instruction is necessary for the configuration and installation of the additional packages.
  • ENV – is necessary for the setting of the environment.  

Sample Workflow: Writing and Applying a Dockerfile

Now, when you understand some basic instructions, let's proceed to the actual sample of the workflow.

Start with the creation of the new directory by using the following code and saving it:

import { v4 as uuid } from "uuid";
 
console.log("Hello World");
console.log(`Your ID is ${uuid()}`);
Then add the package to the projects as follows:
$ npm install uuid

The following step will be adding the next instructions and saving them in Dockerfile:

FROM node:16
WORKDIR /app
 
COPY package.json .
COPY package-lock.json .
RUN npm install
 
COPY main.js .
 
ENTRYPOINT ["node"]
CMD ["main.js"]

Let’s try to explain some details of the code:

  • node:16 – the official image that is used as a base.
  • WORKDIR – in this part, the directory is changed to /app.
  • COPY is used for adding 2 files from the host directory to the in-container working directory.
  • npm install – is used for installation in the container’s filesystem for fetching the dependencies.
  • COPY main.js – source code is copied to the container.

Steps to Build Your Dockerfile 

At this point, you can start building an image from Dockerfile with the usage of the following command:

$ docker build -t demo-image:latest .

Once the image is built, you will see the instructions on the terminal.

Options Available During Docker Build 

When using docker build command, you are specifying the paths to which you reference in the file. Paths outside the context won’t be noticeable for most instructions.

Docker automatically checks instructions according to the working directory, but it is possible to reference a different file with -f, like the following:

docker build -f dockerfiles/app.dockerfile -t demo-image:latest -t demo-image:v1.0 .

Running and Using the Created Image 

To run the created image, use the following:

docker run demo-image:latest node main.js

Recommended Dockerfile Practices 

Writing a Dockerfile is considered to be a fairly simple task, but some recommendations should be taken into consideration to improve performance, usability, and security level.

1. Avoid Using `latest` Tag for Base Images 

In the FROM instruction, it is better to avoid the usage of ‘latest’ because it can lead to some unplanned changes. Most image authors immediately use the latest version. When rebuilding the image, it could unnoticeably provoke the usage of a different version, causing some issues.

That’s why it is better to be more specific and mention node:16.

2. Choose Base Images from Trusted Sources Only 

The usage of a trusted source for the base image is highly important, otherwise, you can experience some security risks. An untrusted base image can include malware that functions outside the containers. That’s why it is better to use images that are published by verified users or are official.

3. Implement HEALTHCHECK to Monitor Container Status 

It is highly important to monitor the container status. This could be done with orchestrators such as Kubernetes so that problematic containers can be automatically restarted.

HEALTHCHECK should be added to the Dockerfile so the command will run inside and check if everything functions properly:

HEALTHCHECK --interval=30s --timeout=5s --retries=3 CMD curl -f http://localhost || exit 1

The status of the containers can be checked with the ps command.

4. Configure ENTRYPOINT and CMD Properly 

CMD and ENTRYPOINT instructions are somehow similar. CMD gives default arguments, and ENTRYPOINT runs this process. Arguments in CMD can be customized when containers are started with docker run.

5. Never Store Secrets Directly in Images 

For the security of your secrets, it is not recommended to store API keys or passwords in the images. Because any user with access to the image can check this information and use it.

Also, it is better to use environment variables and not defaults in the Dockerfile. This will help to minimize some security risks.

6. Add Labels to Organize and Track Your Images 

In case your team has lots of images, it is better to use the LABEL instruction. That means you can add valuable information for each project. Labels are set based on reverse DNS syntax as follows:

LABEL com.sample.team=backend

7. Run Containers Using a Non-Root User 

According to the default characteristics, containers are running as the root user. This can cause some security risks, because hackers could enter the container and run some commands on the host.

This can be solved by adding a USER instruction to the Dockerfile. The best recommendation here is to use non-root users for all the files.

USER demo-app
USER 1000
USER demo-app:demo-group

8. Use `.dockerignore` to Speed Up the Build Process 

Images are usually built with a work directory, and it can contain unnecessary directories and files. To improve the performance, it is needed to exclude the paths that are not needed. This will help to speed up the process when Docker copies the build context at the initial stage of the building process.

Use dockerignore file in the directory to exclude unnecessary directories/files.

9. Optimize Image Size Whenever Possible 

The images can become extremely large, and that directly impacts the build time. To optimize the image size, it is advisable to use only the necessary packages and exclude all the rest. Also, it is better to use the compact base image in case that is possible. For instance, Alpine Linux instead of Ubuntu.

10. Use Linters and Vulnerability Scanners for Security 

Dockerfiles might include errors that can lead to serious problems or unexpected behaviors. It is possible to use linters such as Hadolint for checking the possible issues.

To run it use the following command:

$ docker run --rm -i hadolint/hadolint < Dockerfile

Also, it is recommended to use such scanners as Trivy that will help with finding the outdated packages. Try to use it before the deployment to minimize some risks.

Summary of Key Takeaways

Docker is an extremely popular technology, and it directly impacts the software delivery by the usage of the containers that work perfectly on various environments. For the proper usage of Docker, it is necessary to write a Dockerfile that includes all the necessary instructions. The instructions are defined by the OCI image specification and create images that are needed for the OCI-compatible container runtime.

Share

Was this article helpful to you?

VPS popular offers

-15.4%

CPU
CPU
4 Xeon Cores
RAM
RAM
4 GB
Space
Space
100 GB SSD
Bandwidth
Bandwidth
60 Mbps
DDoS Protected SSD-wKVM 4096 Windows

73 /mo

/mo

Billed annually

-9.2%

CPU
CPU
4 Xeon Cores
RAM
RAM
4 GB
Space
Space
100 GB SSD
Bandwidth
Bandwidth
Unlimited
10Ge-wKVM-SSD 4096 Windows

72 /mo

/mo

Billed annually

-9.7%

CPU
CPU
10 Xeon Cores
RAM
RAM
64 GB
Space
Space
300 GB SSD
Bandwidth
Bandwidth
Unlimited
wKVM-SSD 65536 Windows

138.99 /mo

/mo

Billed annually

-10%

CPU
CPU
6 Xeon Cores
RAM
RAM
16 GB
Space
Space
150 GB SSD
Bandwidth
Bandwidth
Unlimited
10Ge-KVM-SSD 16384 Linux

231 /mo

/mo

Billed annually

-18.4%

CPU
CPU
4 Xeon Cores
RAM
RAM
2 GB
Space
Space
75 GB SSD
Bandwidth
Bandwidth
2 TB
wKVM-SSD 2048 Metered Windows

24 /mo

/mo

Billed annually

-10%

CPU
CPU
6 Xeon Cores
RAM
RAM
8 GB
Space
Space
200 GB HDD
Bandwidth
Bandwidth
300 Gb
KVM-HDD HK 8192 Linux

20.62 /mo

/mo

Billed annually

-10%

CPU
CPU
8 Xeon Cores
RAM
RAM
32 GB
Space
Space
200 GB SSD
Bandwidth
Bandwidth
12 TB
KVM-SSD 32768 Metered Linux

150 /mo

/mo

Billed annually

-10%

CPU
CPU
6 Epyc Cores
RAM
RAM
8 GB
Space
Space
100 GB NVMe
Bandwidth
Bandwidth
Unlimited
Keitaro KVM 8192
OS
CentOS
Software
Software
Keitaro

28.99 /mo

/mo

Billed annually

-9.5%

CPU
CPU
4 Xeon Cores
RAM
RAM
8 GB
Space
Space
100 GB SSD
Bandwidth
Bandwidth
Unlimited
10Ge-wKVM-SSD 8192 Windows

121.5 /mo

/mo

Billed annually

-10.2%

CPU
CPU
6 Xeon Cores
RAM
RAM
16 GB
Space
Space
150 GB SSD
Bandwidth
Bandwidth
100 Mbps
DDoS Protected SSD-KVM 16384 Linux

123 /mo

/mo

Billed semiannually

Other articles on this topic

cookie

Accept cookies & privacy policy?

We use cookies to ensure that we give you the best experience on our website. If you continue without changing your settings, we'll assume that you are happy to receive all cookies on the HostZealot website.