Home / Alt manpages / docker-secret(1)

  • docker-secret(1)
  • User command
  • linux

Create and rotate Docker Swarm secrets safely

You will create a Docker Swarm secret from standard input, confirm that it exists without printing its value, and remove it safely when no service needs it. Allow about ten minutes for a test on an existing Swarm manager. This guide uses Docker CLI 29.8.1 from docker-ce-cli on the reference machine. Secret commands are Swarm management commands, so you need access to a running Swarm and must run them on a manager node. The examples normally run as your unprivileged account; use sudo only if your Docker socket policy requires it.

1. Check the CLI and Swarm role

Start by checking the installed client and the local node state. This changes nothing:

$ docker version --format '{{.Client.Version}}'
29.8.1
$ docker info --format '{{.Swarm.LocalNodeState}} {{.Swarm.ControlAvailable}}'
active true

You need active true. If the state is inactive, do not run docker swarm init on a host that belongs to another deployment. Ask the Swarm administrator for a manager endpoint or follow your site's cluster recovery process. A worker can run ordinary container commands, but it cannot create, list or remove Swarm secrets.

Checkpoint

Continue only when the Docker client can reach an active manager. The local reference machine reports an inactive Swarm, so its secret examples cannot be executed there without changing cluster state.

2. Create a secret without putting the value in shell history

Use a pipe and a final - to send content on standard input. The secret name must be unique within the Swarm. This example creates a disposable test value:

$ printf '%s\n' 'REPLACE_WITH_A_TEST_VALUE' | docker secret create demo_api_key -
q1w2e3r4t5y6u7i8o9p0a1s2d

The output is an ID, not the secret value. The ID shown above is illustrative and will differ. Avoid writing real credentials directly into a command line: command history, process inspection or copied terminal logs can retain them. For a file-backed value, use docker secret create SECRET_NAME /path/to/file; check the file permissions first and remember that the path is read by the Docker client.

Creation is a state-changing operation. If the value is real, record where it is used and how it will be rotated before creating it. Docker does not provide an in-place update for a secret.

3. Verify the name and metadata

List names and IDs with docker secret ls. The default table includes creation and update timestamps:

$ docker secret ls
ID                          NAME          CREATED             UPDATED
q1w2e3r4t5y6u7i8o9p0a1s2d   demo_api_key  10 seconds ago      10 seconds ago

Use a filter when the Swarm contains many secrets. The exact timestamp and ID are variable:

$ docker secret ls --filter name=demo_api_key
$ docker secret ls --quiet

Do not treat ls as a value check. Docker deliberately does not print secret contents. To inspect metadata, use:

$ docker secret inspect demo_api_key
[
    {
        "ID": "q1w2e3r4t5y6u7i8o9p0a1s2d",
        "Spec": {
            "Name": "demo_api_key"
        }
    }
]

The full JSON also contains timestamps and other metadata. It should not contain the secret payload. Treat inspect output as operational data nonetheless, because names and labels can reveal system details.

4. Attach a secret to a service deliberately

A secret is useful when a Swarm service grants a task access to it. The service command is outside this guide's primary command, but the boundary matters: a secret is not a general Docker environment variable and is not available to every container automatically. When a service is created or updated, select the secret explicitly with the service's --secret or --secret-add option. Docker makes it available inside the task at a secret path, normally under /run/secrets/.

Inspect the service specification before changing it:

$ docker service inspect SERVICE_NAME --format '{{json .Spec.TaskTemplate.ContainerSpec.Secrets}}'

Replace SERVICE_NAME with the real service name. Do not paste secret contents into service labels, environment variables, image build arguments or logs. Those locations have different exposure and lifetime properties.

Checkpoint

Before proceeding to rotation, identify every service using demo_api_key. Removing a secret that a running service uses is rejected by the daemon, but plan the change rather than relying on that protection.

5. Rotate by adding a new name

Because a Docker secret cannot be updated, rotation uses a new versioned name. Create the replacement from standard input:

$ printf '%s\n' 'REPLACE_WITH_THE_NEW_VALUE' | docker secret create demo_api_key_v2 -
z9x8c7v6b5n4m3a2s1d0f9g8h

Update the service to consume demo_api_key_v2, then wait for the service rollout and test the application using the new credential. Keep the old secret until the service has converged and no remaining task needs it. The exact update command depends on the service image and its existing secret target, so copy the current service specification before editing it.

After the replacement is confirmed, list both names and remove only the old one. A failed update is recoverable: leave the old secret attached, fix the service configuration, and retry the rollout. Do not remove the old secret first.

6. Remove a secret only after detaching it

Warning

docker secret rm is destructive and does not ask for confirmation. It cannot be undone. First confirm that no service still references the secret, then remove it by exact name or ID:

$ docker secret rm demo_api_key
demo_api_key

If the secret is still attached to a service, the daemon rejects the request and identifies the service. Remove access through the service update workflow, verify that replacement tasks are healthy, and retry the removal. Do not remove a service or stop production tasks merely to make this command succeed.

For an accidental removal, the secret value cannot be recovered from Docker. Recreate it from the authoritative credential source under a new versioned name, update the affected service, and revoke the old credential at its upstream system if necessary.

Done means

  • You confirmed an active Swarm manager and the installed Docker CLI version.
  • You created the secret from standard input without printing its value.
  • You verified its name and ID with docker secret ls and metadata with docker secret inspect.
  • You recorded which services use the secret before changing access.
  • You rotate by creating a new version, updating and testing the service, then removing the old secret.
  • You understand that docker secret rm is immediate, irreversible and intentionally non-interactive.