Rotate a Swarm Root CA with docker swarm ca

The Swarm root certificate is what every node trusts, so replacing it is a change you plan, not one you try out. This guide uses docker swarm ca to inspect the root certificate, or replace it while Docker rotates every node certificate. It covers the installed Docker Community CLI 29.8.1, packaged as docker-ce-cli 5:29.8.1-1~ubuntu.24.04~noble. Allow 10 to 20 minutes for a small, healthy cluster, plus time to investigate any node that is offline.

This is a manager-only cluster operation. You need:

Displaying the existing certificate is read-only. Rotation changes the trust root and makes registered nodes renew their TLS certificates.

1. Check that you are on the right manager

Run this as the account that normally administers the Swarm. Add sudo only if that account needs elevated access to the Docker socket.

Warning: do not initialise a new Swarm just to make this command work. That would create a new cluster on the target Engine.

$ docker info --format '{{.Swarm.LocalNodeState}} {{.Swarm.ControlAvailable}}'
active true

The expected values are active true. A worker, a manager without control access, or an Engine outside Swarm will not perform the operation. On this Docker version, an inactive Engine reports an error such as This node is not a swarm manager.

2. Display and record the current root certificate

With no options, the command prints the current Swarm root CA in PEM format. This output is the certificate, not the private key. Save a copy only in a location whose access is appropriate for certificate material.

$ docker swarm ca
-----BEGIN CERTIFICATE-----
...certificate data...
-----END CERTIFICATE-----

For an audit record, redirect the output to a deliberately named file in a protected directory. The command writes the certificate to standard output, so terminal scrollback or a shell history entry is not a substitute for controlled storage.

$ install -d -m 700 /var/lib/docker-ca-audit
$ docker swarm ca > /var/lib/docker-ca-audit/root-ca-before.pem
$ openssl x509 -in /var/lib/docker-ca-audit/root-ca-before.pem -noout -subject -issuer -dates -fingerprint -sha256

Checkpoint: you have confirmed the manager identity and captured the certificate fingerprint. Stop here if the subject or issuer is not the cluster you meant to change.

3. Choose the rotation source

The simplest rotation generates a new root certificate and key inside the Swarm:

$ docker swarm ca --rotate

If your organisation supplies a PEM-formatted root certificate and its matching private key, provide both files instead. Keep the key readable only by the administrator running Docker, and check that your backup and incident procedures cover it before using it.

$ sudo install -m 600 /secure/change-042-swarm-ca-key.pem /run/docker-swarm-ca-key.pem
$ sudo docker swarm ca --rotate \
    --ca-cert /secure/change-042-swarm-ca-cert.pem \
    --ca-key /run/docker-swarm-ca-key.pem

Warning: do not guess at certificate and key pairing. Validate the certificate first, and have your PKI process confirm that the supplied key belongs to it. The option names say what the files contain, but the command does not turn an arbitrary certificate into a valid organisational PKI design.

An external signer is a separate design. The CLI accepts one or more --external-ca specifications, in the documented form protocol=X,url=Y. The current Docker documentation identifies cfssl as the supported protocol. Use the exact endpoint and operational controls supplied by that CA rather than copying a placeholder into a production command.

4. Set the node certificate lifetime

--cert-expiry controls the validity period for node certificates issued during the rotation. Its installed default is 2160h0m0s, or 90 days. The value accepts a duration made from nanoseconds, microseconds, milliseconds, seconds, minutes and hours.

$ docker swarm ca --rotate --cert-expiry 720h

5. Rotate and wait for convergence

For a normal planned change, run the rotation attached to the terminal. Docker shows a desired root digest and progress for TLS and CA certificate renewal. Let the command finish, and do not treat the first progress line as success.

$ docker swarm ca --rotate --quiet=false
desired root digest: sha256:...
rotated TLS certificates:  [==============================>] 3/3 nodes
rotated CA certificates:   [==============================>] 3/3 nodes
-----BEGIN CERTIFICATE-----
...new certificate...
-----END CERTIFICATE-----

The exact digest, progress width and PEM content vary. The completion signal is that every registered node has reached the total, followed by the new certificate. --quiet suppresses progress output, but it does not make an incomplete rotation complete.

Warning: rotation changes cluster trust. Existing managers and workers must renew. Do not use it as a routine command on a busy cluster without checking node health and having console access to recover a manager.

6. Use detached mode with a follow-up check

--detach starts the rotation and exits without waiting for convergence. That suits automation that has its own polling, but an immediate zero exit is not enough evidence that every node renewed.

$ docker swarm ca --rotate --detach
$ docker node ls --format '{{.ID}} {{.Hostname}} {{.Status}} {{.TLSStatus}}'

Inspect every node after a detached rotation. A down or unreachable node can prevent completion. If a node stays unavailable, restore its connectivity or follow your documented node replacement procedure.

Warning: do not rotate the CA repeatedly to hide an unhealthy node. That adds more trust changes without repairing the underlying problem.

7. Verify the new root and clean up

Read the certificate again and compare its fingerprint with the pre-change record. A successful rotation should produce a different root fingerprint when Docker generated a new root.

$ docker swarm ca > /var/lib/docker-ca-audit/root-ca-after.pem
$ openssl x509 -in /var/lib/docker-ca-audit/root-ca-after.pem -noout -subject -issuer -dates -fingerprint -sha256
$ docker node ls --format '{{.Hostname}} {{.Status}} {{.TLSStatus}}'

Remove temporary private-key copies after your retention policy has captured the approved backup. Do not delete the only recovery copy, and do not place a private key in a world-readable directory.

Recovery: if the rotation was started with a supplied CA and failed, stop and consult the PKI owner before trying a different certificate or key.

Done means