Hey there! Welcome to Hostman! 🎉

How to Improve Docker Containers Security: Best Practices

24.11.2023
Reading time: 5 min
Hostman Team
Technical writer

Programmers widely use Docker containers. They are isolated environments that have everything needed to launch an application quickly. Working with containers speeds up application development and increases the developer's efficiency.

One of the actual problems for developers using containers is security in Docker. Containers are a standardized environment for attacks; their misuse opens the door to valuable information for attackers. Let's take a look at how we can secure containers with time-tested best practices.

Security basics when working with Docker containers

Container security depends on the operating system, the embedded software components with which the developer interacts, and configuration settings. Proper build and deployment will ensure that Docker is secure, and you can enjoy all the benefits of containers.

Another important tip is to update the software regularly. Each update introduces improved protection algorithms, so use only up-to-date solutions.

Recommendations for building the image

Always use a verified image from official sources. Alpine Linux is the best option as a base distribution. These simple guidelines reduce the likelihood of surface and supply chain attacks.

Many developers wonder whether choosing a fixed or the latest tag is better. Specifying a particular version in the tags provides a strong defense against making changes that could break containers. However, it prevents security settings from being updated when updates are released, which can reduce security. If you tag a specific version, choose the most stable one.

Do not assign root privileges to users

Processes in containers are initially started in root mode. To ensure security, grant fewer privileges to the user. To do this, specify the -u symbol in front of an arbitrarily assigned user ID that does not exist in a particular container. It looks like this:

Docker run -u 3000 <image>

The second way to create a user without root privileges:

FROM <base image>
RUN addgroup -S appgroup
&& adduser -S appuser -G appgroup
USER appuser
...<continued Dockerfile>...

These settings prevent attackers from logging in through the container.

Privilege capabilities and configuration

You shouldn't run privileged containers, and it is also advisable to prevent new privileges from being added while the container is in use. To do this, set the following settings:

--security-opt=no-new-privileges

For security reasons, you should not use default capabilities. It is better to remove the irrelevant ones.

Create control groups to track resource access parameters. This allows you to control memory access as well as all operations. Each container is automatically allocated its own group. To avoid increasing the risk of hacker attacks, never specify the --cgroup-parent attribute.

To ensure the security of Docker containers, restrict user access to memory. To do this, set parameters such as:

--memory="400m"
--memory-swap="1g"
--cpus=0.5
--restart=on-failure:5
--ulimit nofile=5
--ulimit nproc=5

Data storage and file system

The root file system of all containers should not be modified. Select read-only settings:

docker run --read-only <image>

Properly implement long-term storage of information. You can either use volumes or mount host directories. Whichever you choose, you should select "read-only" in the settings to prevent unauthorized modification of data.

If you are using temporary storage for files, set the options:

docker run --read-only --tmpfs /tmp:rw,noexec, nosuid <image>

Network parameters

Initially, docker0 is installed on the system. We do not recommend using this bridge interface. To disable this option, set the --bridge=none parameter. This will prevent containers from communicating through a network connection. 

It is better to create separate networks for connections:

docker network create <network_name>
docker run --network=<network_name>

For security purposes, isolate the host interface by assigning the --net=host parameter.

When working with containers, you should systematically monitor network activity. This way, you can detect anomalous activity in time and prevent malicious attacks.

Use only trusted registries

Using the official online registry from Docker is a safe solution. You can also configure the registry yourself on your own host. Installing the registry behind the firewall serves as an additional lever to strengthen security.

Regular scanning

Don't neglect scanning for vulnerabilities. You can use either free solutions or more functional paid software. Regular monitoring will allow you to detect problems quickly and avoid serious consequences.

Do not open a UNIX socket

This socket is the entry point to the API. By opening the socket at /var/run/docker.sock, you grant unrestricted root access to the host. Ensure the other containers don't get access; this is a critical security setting.

Do not include secrets and credentials

Initially, any user accessing the image can get information about the secrets recorded in Dockerfiles. To prevent this, you should use Docker BuildKit to store secret information and specify the --secret option on the command line.

Now you know how to protect Docker from intruders. Following these simple rules will allow you to avoid serious problems and keep your information safe.