Docker secrets management is not optional

Docker secrets management starts by assuming that anything passed through a Dockerfile’s ARG, ENV, or COPY gets written into the image’s layers and metadata forever, visible to anyone who pulls the image via docker history or docker inspect. In this lab we first manufacture the leak, then fix it with four techniques that genuinely keep the secret out of the image: a BuildKit build secret, a read-only file mount, a properly scoped env-file, and Docker Compose’s native secrets without needing Swarm.

Which technique to use, and when

If the secret is only needed while the image is being built (a private key to clone a repository, a token to fetch a dependency), docker build --secret mounts it at /run/secrets/ only for that one RUN instruction and it never reaches a layer. If the running process needs the secret instead, a read-only (:ro) file mount or Compose’s secrets: block keep it out of the container’s Env, which is exactly what --env-file does not do. Teams managing credentials at scale should consider a dedicated manager like HashiCorp Vault, and real clusters running Docker Swarm also get docker secret create, encrypted in the cluster’s Raft log.

Keep going

See our guide to environment variables and secrets in Docker Compose, and if you haven’t installed Docker yet, our guide to installing Docker on Debian. More reproducible labs live in the Tools category and among our other hands-on labs. The official reference for RUN --mount=type=secret is Docker’s Dockerfile reference, Compose secrets are detailed in the Compose Specification, and OWASP’s Docker Security Cheat Sheet covers broader best practices.

FAQ

Why shouldn't I put a secret in a Dockerfile's ARG or ENV?

Because both get baked into the image's layers and metadata forever: anyone who runs docker history or docker inspect on that image can read it, even if you "delete" it in a later instruction — the earlier layer is still there.

What is a BuildKit build secret and how is it different from ARG?

docker build –secret mounts a file at /run/secrets/ only for the RUN instruction that requests it and never writes it to a layer or the history. ARG, by contrast, gets recorded as part of the image's build metadata.

Is it safe to use –env-file with docker run?

It's better than ARG/ENV in the Dockerfile because the secret never touches the image, but it's still visible via docker inspect on the running container. For runtime processes, a read-only file mount or Compose secrets are safer.

Do I need Docker Swarm to use Compose secrets?

No. The top-level secrets: block with a file: driver works with a plain docker compose up on a single host. docker secret create and encrypted storage in the Raft log do require a cluster started with docker swarm init.