Sefism is free for learners. We are here to help you grow, one step at a time.Join for free
Sefism.

Best practices · Stacks and tools

Docker Best Practices

Opens with credits

A practical guide to Docker best practices for developers who ship containers. It covers writing Dockerfiles that build fast and stay small, keeping images secure, passing secrets into builds safely, running containers that behave well in production, using Compose for local development and building images in CI.

Written by Tauseef Fayyaz6 chapters, 28 practicesAbout 18 min24 quiz questionsReviewed 12 October 2026

What you will learn

6 chapters · about 18 min

  1. 1Writing the DockerfileHow to structure a Dockerfile so the image is small and rebuilds are fast: the base image, stages, instruction order and the build context.5 practices · 4 min
  2. 2Image size and securityWhat makes an image safe to run: who the process runs as, which exact base you build on, and how you find and fix known vulnerabilities.5 practices · 3 min
  3. Secrets in buildsHow to give a build a token or key it needs, such as a private registry token, without leaving it inside the image.4 practices · 3 minOpens with credits
  4. Running containers wellHow a container should behave once it is running: one job, clean shutdowns, honest health reports, bounded resources and logs where the platform can find them.6 practices · 4 minOpens with credits
  5. Docker Compose for local developmentHow to use Compose so a new teammate can run the whole stack with one command and code changes show up without rebuilding by hand.4 practices · 2 minOpens with credits
  6. Building images in CIHow to build, tag, check and publish images in a pipeline so builds are fast, traceable and stop when something is wrong.4 practices · 2 minOpens with credits

About this guide

Docker best practices are mostly about three things: images that are small, builds that are fast, and containers that are safe to run. A Dockerfile that works on your laptop can still ship a 1 GB image full of compilers, run as root, leak an API token through a build argument and ignore the stop signal so every deploy waits ten seconds. None of these show up until production, which is why it pays to get the Dockerfile right early.

This guide follows the order you meet these problems. The first two chapters cover writing the Dockerfile itself (base images, multi-stage builds, layer caching, .dockerignore) and keeping the image secure (non-root users, pinned digests, scanning). Later chapters cover secrets in builds with BuildKit secret mounts, runtime behaviour like signals and health checks, Docker Compose for local development, and building and checking images in CI.

Every practice was checked against the current Docker documentation, including the official Dockerfile reference and the Docker build best practices page. Each one tells you what to do, what to avoid and how to check that you got it right, with a short example you can copy.

Common questions

What is a multi-stage Docker build?

A multi-stage build uses several FROM instructions in one Dockerfile. Early stages compile and test your app with all the tools they need, and the final stage copies only the built output. The image you ship is smaller and contains no compilers or dev dependencies.

How do I reduce my Docker image size?

Start from a slim or distroless base, use a multi-stage build, add a .dockerignore, and clean package manager caches in the same RUN step that installs packages. Check each change with docker image ls to see what actually helped.

Is it safe to pass secrets as Docker build args?

No. Docker documents that build arguments and environment variables persist in the final image, so anyone with the image can read them. Use BuildKit secret mounts (RUN --mount=type=secret) for build-time secrets and inject runtime secrets when the container starts.

Should a Docker container run as root?

No. Run your app as an unprivileged user with the USER instruction. If someone exploits the app, a non-root user limits what they can do inside the container and on mounted files.

What is the difference between CMD and ENTRYPOINT?

Docker recommends ENTRYPOINT for the image's main command and CMD for default arguments that users can override. Write both in exec form (a JSON array) so your process receives signals like SIGTERM directly.

Do I still need the version field in docker-compose.yml?

No. Current Docker Compose follows the Compose Specification, where the top-level version field is obsolete. Name the file compose.yaml and run it with docker compose.

Sources (6)

Checked against these, last on 12 October 2026.

  1. Building best practices, Docker Docsdocs.docker.com/build/building/best-practices/
  2. Build secrets, Docker Docsdocs.docker.com/build/building/secrets/
  3. Dockerfile reference, Docker Docsdocs.docker.com/reference/dockerfile/
  4. Checking your build configuration, Docker Docsdocs.docker.com/build/checks/
  5. Use Compose Watch, Docker Docsdocs.docker.com/compose/how-tos/file-watch/
  6. Docker Security Cheat Sheet, OWASPcheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html

Picked from the other libraries by shared topics.

Work with me

Stuck on something specific?

Writing only gets you so far. If you want an answer to your situation rather than the general case, book a session and we will work through it together. Sessions are free for approved Sefism members, and a few slots open each week.

  • 1:1 Mentorship
  • Fresh Graduate Mentorship
  • Career Guidance

Brand deals, promos and partnerships: tauseeffayyaz@gmail.com