Swarm secrets

docker secret create stores a value encrypted in the managers' Raft log; a service that lists it gets it as a file in /run/secrets, in memory, and nowhere else. docker service inspect never shows its value.

How it works

Create it from standard input (printf '%s' "$VALUE" | docker secret create name -) or a file, declare it in the stack (external: true, or file:), and list it under the service's secrets:. Official images read NAME_FILE variables (POSTGRES_PASSWORD_FILE); apps can follow the same convention. A secret cannot change: create a new name to rotate it.

What breaks

Environment variables are part of the service definition: docker service inspect prints them, every container inherits them, crash reports dump them. Writing ${PASSWORD} in the stack file only moves the value from git to the deploy. A secret created with the wrong value fails at login, not at deploy.

In compose.yaml

services:
  db:
    image: postgres:16
    environment:
      POSTGRES_PASSWORD_FILE: /run/secrets/db_password
    secrets:
      - db_password

secrets:
  db_password:
    external: true
    name: shop_db_password

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.