Security best practices

You can take a few steps to improve the security of your container. This includes:

  1. Choosing the right base image from a trusted source and keeping it small
  2. Using multi-stage builds
  3. Rebuilding images
  4. Checking your image for vulnerabilities

Choose the right base image

The first step towards achieving a secure image is to choose the right base image. When choosing an image, ensure it's built from a trusted source and keep it small.

Docker Hub has more than 8.3 million repositories. Some of these images are Official Images, which are published by Docker as a curated set of Docker open source and drop-in solution repositories. Docker also offers images that are published by Verified Publishers. These high-quality images are published and maintained by the organizations partnering with Docker, with Docker verifying the authenticity of the content in their repositories. When you pick your base image, look out for the Official Image and Verified Publisher badges.

Docker Hub Official and Verified Publisher images

When building your own image from a Dockerfile, ensure you choose a minimal base image that matches your requirements. A smaller base image not only offers portability and fast downloads, but also shrinks the size of your image and minimizes the number of vulnerabilities introduced through the dependencies.

You should also consider using two types of base image: the first image for development and unit testing and the second image for testing during the later stages of development and production. In the later stages of development, your image may not require build tools such as compilers, build systems, and debugging tools. A small image with minimal dependencies can considerably lower the attack surface.

Use multi-stage builds

Multi-stage builds are designed to create an optimized Dockerfile that is easy to read and maintain. With a multi-stage build, you can use multiple images and selectively copy only the artifacts needed from a particular image.

You can use multiple FROM statements in your Dockerfile, and you can use a different base image for each FROM. You can also selectively copy artifacts from one stage to another, leaving behind things you don’t need in the final image. This can result in a concise final image.

This method of creating a tiny image doesn't only significantly reduce complexity, but also reduces the chance of implementing vulnerable artifacts in your image. Therefore, instead of images that are built on images, that again are built on other images, multi-stage builds let you 'cherry pick' your artifacts without inheriting the vulnerabilities from the base images on which they rely.

For detailed information on how to configure multi-stage builds, see multi-stage builds.

Rebuild images

A Docker image is built from a Dockerfile. A Dockerfile contains a set of instructions which lets you automate the steps you would normally (manually) take to create an image. Additionally, it can include some imported libraries and install custom software. These appear as instructions in the Dockerfile.

Building your image is a snapshot of that image at that moment. When you depend on a base image without a tag, you’ll get a different base image every time you rebuild. Also, when you install packages using a package installer, rebuilding can change the image drastically. For example, a Dockerfile containing the following entries can potentially have a different binary with every rebuild.

# syntax=docker/dockerfile:1
FROM ubuntu:latest
RUN apt-get -y update && apt-get install -y python

Docker recommends that you rebuild your Docker image regularly to prevent known vulnerabilities that have been addressed. When rebuilding, use the option --no-cache to avoid cache hits and to ensure a fresh download.

For example:

$ docker build --no-cache -t myImage:myTag myPath/

Consider the following best practices when rebuilding an image:

  • Each container should have only one responsibility.
  • Containers should be immutable, lightweight, and fast.
  • Don’t store data in your containers. Use a shared data store instead.
  • Containers should be easy to destroy and rebuild.
  • Use a small base image (such as Linux Alpine). Smaller images are easier to distribute.
  • Avoid installing unnecessary packages. This keeps the image clean and safe.
  • Avoid cache hits when building.
  • Auto-scan your image before deploying to avoid pushing vulnerable containers to production.
  • Analyze your images daily both during development and production for vulnerabilities. Based on that, automate the rebuilding of images if necessary.

For detailed best practices and methods for building efficient images, see Dockerfile best practices.

Check your image for vulnerabilities

In addition to following the best practices outlined on this page when developing images, it's also important to continuously analyze and evaluate the security posture of your images using vulnerability detection tools.

Docker tools come with features that help you to stay up to date about vulnerabilities that affect images that you build or use.

  • Docker Hub supports an automatic vulnerability scanning feature, which when enabled automatically scans images when you push them to a Docker Hub repository. Requires a Docker subscription.
  • Docker Hub also supports an early-access advanced image analysis feature, which extends the "core" vulnerability scanning solution with enhanced capabilities and more detailed and actionable insights.
  • For the CLI, there's the docker scout CLI plugin which lets you explore vulnerabilities for images using the terminal.
  • Docker Desktop has a detailed image view for images in your local image store, that visualizes all of the known vulnerabilities affecting an image.

All of these security features are powered by the same technology: Docker Scout. These features help you to achieve a holistic view of your supply chain security, and to provide actionable suggestions for what you can do to remediate those vulnerabilities.

Conclusion

Building secure images is a continuous process. Consider the recommendations and best practices highlighted in this guide to plan and build efficient, scalable, and secure images.

To summarize the topics covered in this guide:

  • Start with a base image that you trust. Pay attention to the Official image and Verified Publisher badges when you choose your base images.
  • Secure your code and its dependencies.
  • Select a minimal base image which contains only the required packages.
  • Use multi-stage builds to optimize your image.
  • Ensure you carefully monitor and manage the tools and dependencies you add to your image.
  • Ensure you scan images at multiple stages during your development lifecycle.
  • Check your images frequently for vulnerabilities.