Keeping secrets out of images

Anything written into an image, by ENV, ARG, COPY or a RUN, can be read by whoever can pull it, even if a later layer deletes it. Secrets are given to the container when it starts.

How it works

docker history and docker inspect reveal ENV and ARG values, and every layer can be extracted from the image. Pass secrets with -e, --env-file or Compose secrets at run time, and use RUN --mount=type=secret for the ones the build itself needs.

What breaks

COPY . . with a .env file in the context, ENV DB_PASSWORD=… or an npm token passed as a build argument all end up in the registry. Once pushed, change the secret: removing it from the next image does not erase it from the old one.

In a terminal

docker history --no-trunc orders-api
docker run -d --name api --env-file ./prod.env orders-api

See it break, then fix it

Write the Dockerfile or the compose file, type the docker commands, and watch a simulated server run them through reboots, upgrades and traffic. Free to start.