Securing Docker Containers – Best Practices for Beginners

Welcome to this beginner-friendly tutorial on securing Docker containers. Docker is a popular tool used for deploying applications in a consistent environment using containers. However, as with any technology, security is a crucial aspect to consider. In this tutorial, we’ll go over some of the best practices for securing your Docker containers.

Before we start, it’s important to understand what Docker is and what containers are. Docker is an open-source platform that uses OS-level virtualization to deliver software in packages called containers. Containers are standalone units of software that package up code and all its dependencies so the application runs quickly and reliably from one computing environment to another.

To learn more about Docker, please check Docker Tutorials page.

Now, let’s dive into securing these containers!

Using the Latest Docker Version

Docker is regularly updated with new features, bug fixes, and most importantly, security patches. As a best practice, you should always use the latest version of Docker. It’s easy to check your Docker version and update it.

docker version

If an update is available, use the package manager that is specific to your operating system to update Docker. For example, on Ubuntu, you would use:

sudo apt-get update
sudo apt-get upgrade docker-ce

Use Minimal Base Images

When creating Docker containers, you start from a base image. This base image can be a full OS, but it can also be a minimal image like Alpine Linux. By using a minimal base image, you reduce the attack surface because fewer components are installed and thus fewer vulnerabilities are present.

FROM alpine:3.7

Handle Docker Content Trust and Image Signing

Docker Content Trust (DCT) provides the ability to use digital signatures for data sent to and received from remote Docker registries. These signatures allow client-side or runtime verification of the integrity and publisher of specific image tags.

To enable Docker Content Trust, set the DOCKER_CONTENT_TRUST variable on your Docker CLI to 1.

export DOCKER_CONTENT_TRUST=1

Use Docker Security Scanning

Docker Security Scanning is a service that provides a detailed security profile of your Docker images for proactive vulnerability management. This tool scans each layer of your Docker image, identifies potential vulnerabilities, and provides a detailed report.

Docker Security Scanning can be enabled in Docker Trusted Registry or as an add-on service for Docker Hub.

Using Namespaces and CGroups

Namespaces and CGroups (Control Groups) are powerful tools in Docker that help in isolating and managing resources for Docker containers.

Namespaces provide containers with their own view of the underlying Linux system, limiting what they can see and access. When you run a container, Docker creates namespaces that the container will use.

CGroups limit the amount of resources such as CPU, memory, and disk I/O, that a container can use. By default, a container can use as much of a resource as the host’s kernel scheduler allows. Docker provides ways to control how much memory, or CPU a container can use, setting runtime configuration flags of the docker run command.

For example, the following command runs a container and sets the memory limit to 100m and the CPU equivalent of 0.5 of a core:

docker run -it --memory="100m" --cpus=".5" ubuntu

Running Containers as a Non-root User

By default, Docker containers are run as root. This means that if an attacker manages to break out of the application running inside the container, they could have root access to the Docker host. To prevent this, it’s a good practice to run services inside the container as a non-root user.

FROM node:14
RUN useradd app 
USER app
WORKDIR /home/app
COPY package*.json ./
RUN npm install
COPY . .
CMD [ "node", "app.js" ]

In this Dockerfile, we’re adding a new user called “app”, switching to this user with the USER command, and running the application as this non-root user.

Limit Container Resources

To prevent denial of service attacks by one container on others running on the same host, it’s a good practice to limit container resources. You can use Docker’s support for kernel control groups (cgroups) to set limits on resources like CPU, memory, I/O, and network for each container.

The following command sets a memory limit of 100m and CPU shares to 50:

docker run -it -m 100m --cpu-shares 50 ubuntu

Keep Container Processes to a Minimum

A best practice for Docker containers is to keep them simple and small. Each container should have only one concern. This reduces the complexity, improves the reliability, and speeds up the start time of your containers.

If you have multiple services that need to communicate, it’s better to create separate containers and link them together. This way, if one service has a security issue, it does not directly affect the other services.

Conclusion

Security is an important aspect of managing Docker containers. In this tutorial, we covered some best practices including always using the latest Docker version, using minimal base images, enabling Docker Content Trust, using Docker Security Scanning, isolating and managing resources with namespaces and cgroups, running containers as non-root users, limiting container resources, and keeping container processes to a minimum.

Remember that security is not a one-time setup but an ongoing process. Regularly check your Docker containers for potential vulnerabilities, apply the latest patches, and follow best practices to keep your containers secure. Happy Dockering!