Best Practices for Docker Security For 2020

Docker provides a more secure and robust environment for managing development and deployment cycles as opposed to the traditional server and virtual machine models. However, like any other infrastructure, Docker is prone to a number of security issues, including kernel exploits, container breakouts, poisoned images, and denial-of-service attacks.


Developers can address these pitfalls and safeguard their containerized environments by following a distinct set of best practices for Docker security.


In this post, we will dive into the most important things every Docker user should keep in mind to secure their deployments.

1. Use Authentic Docker Images

Let’s start with image authenticity — an issue that is inherent in every developer’s experience with Docker.


Too often, developers prefer using the base Docker images as opposed to building them from scratch. However, downloading Docker images from untrusted third-party sources and vendors can introduce security vulnerabilities to your containers.


It is therefore imperative to check the authenticity of an image before downloading them by:


  • Using base images from Docker Hub, a trusted source whose images are scanned and reviewed using Docker’s Security Scanning Services.
  • Using base images that are digitally signed by the Docker Content Trust.


Note that the Docker Content Trust feature is disabled by default. You can enable it using this  command:




When you attempt to pull down images that aren’t signed by a genuine publisher, Docker declines as shown in the snapshot below:



2. Run Containers as a Non-Root User


Most people are tempted to run Docker containers with root permissions simply because they don’t have to worry about restrictions. However, this introduces a security gap that hackers or ill-intended DevOps team members can use to perform malicious activities. 


Unless you’re working in a Docker test environment, there’s no reason for running Docker containers as root. 


The good thing is that Docker does not run containers as root as a default setting. So, there’s nothing big apart from resisting the urge to run containers as root for convenience reasons.


Below is an example showing the recommended root settings for running docker.


If you use Kubernetes for container orchestration, you can enhance Docker security by ensuring all containers run as non-root by using the MustRunAsNonRoot directive.


3. Embrace the Principle of Least Privilege


Executing Docker containers with root permissions broadens the attack surface because users can easily escalate privilege access, making the application vulnerable to greater exploitation.


So, apart from running as non-root, Docker users should have a well-established access control solution that lets users run containers with minimal privileges. Ideally, you can create a minimize exposure by configuring the USER directive such that dedicated users run the application with the right amount of privileges.  


Limiting the container’s privileges to the underlying host can reduce the risk of vulnerabilities substantially.


4. Manage Sensitive Information With Docker Secrets


Secrets contain sensitive pieces of information such as passwords, addresses, TLS certificates, SSH keys, tokens, and more. These should not be communicated or stored in a Dockerfile or the application source code without being encrypted.


To avoid leaking this sensitive information, you should deploy secrets to your Docker containers through Kubernetes, Docker Swarm, or any other orchestration platform. 


Docker encrypts secrets during transit and when at rest in a Docker Swarm. A specific secret on Docker is only accessible to a service that has been granted access.


The key here is ensuring that secrets are only accessible to the relevant containers and that they are never stored or exposed at the host level.


A good practice is using the Docker alpha feature to manage secrets and mount sensitive data without caching it, as shown below:


5. Use Multi-Stage Builds


One of the most prevalent challenges when optimizing Docker files is keeping the image size small. Traditionally, most people embraced a Docker builder pattern that involved maintaining separate Docker files. This was not only prone to errors but also hard to maintain.


Fortunately, Docker version 17.05 introduced the Docker multi-stage build feature, which allows users to keep image sizes down with ease. Multi-stage builds will allow you to leverage the power of the builder pattern without maintaining separate Docker files for development or production.


More specifically, it allows you to use multiple FROM statements in your Dockerfile.


Below is an example showing a multi-stage Docker build:




6. Set Resource Limits for your Containers


Docker gives you a lot of flexibility because you can run as many containers as you wish in production. While this enables you to use the host resources at an optimal level, it also presents major performance issues and security risks such as denial of service attacks.


To ensure your server is not compromised through DoS attacks, you should limit the amount of system resources that each container can consume. 


You can limit a container’s access to memory or CPU cycles. You can also set ulimits in containers to specify the maximum number of processes (–ulimit nproc=< specify number here>), number of file descriptors (–ulimit nofile=<specify number here>), and number of restarts (–restart=on-failure:<specify_number_of_restarts_here>) .


Limiting the resources allotted for individual containers minimizes the attack surface in the event of a system compromise.


7. Harden the Host


Your Docker environment is only as secure as the host. If the host is compromised, your containers are also at risk. For this reason, you should only run Docker on a secured, hardened host.


Some effective practices of hardening your host include using updated operating systems, kernel versions, and system software. Other best practices for hardening your host include continuous patching and auditing of all system processes.


If your server is meant for running container services only, then it is good to consider using distributions like CoreOS that are explicitly designed for this purpose. Additionally, consider using security features such as SELinux.


Another security practice is continously monitoring your host environment as well as Docker containers for security vulnerabilities. 


8. Audit With Docker Bench


Docker Bench is a very handy auditing tool that you can run against your Docker. It analyzes your host configuration, daemon configuration, daemon configuration files, container images, build files, container runtime, and more.      


Checking your configuration settings with the Docker bench script provides a lot of information that can be used to secure your containers. 


To install Docker Bench, clone the repo by running:



After cloning the repository, use the command below to run Benchmark against your Docker.


Running the command above produces output as shown below.


As you can see, the output shows every check that was run alongside its results in a very straightforward manner. The user should pay attention to the [WARN] status messages and make necessary improvements.




There you go! With these tips, you can maintain a robust and highly secure environment for containerized applications. Docker Security should be far-reaching in that it should cover the entire stack — from the containers to the daemons, and the host environment.


The Center for Internet Security put together a comprehensive Docker Benchmark with security guidelines for Docker server software. The 200-page document is widely viewed as the ultimate guide for securing Docker Containers.


By following and enforcing all practices outlined in the CIS Benchmark, you will enjoy all the amazing benefits of Docker containers without exposing yourself to security problems.


Seah Higgins / About Author

Entrepreneur & Full Time Dad. Full Stack Web Developer And AppSec Freak | Twitter