August 29, 2026

Docker Swarm Best Practices: The Checklist for a Cluster That Stays Up (2026)

A one-page Docker Swarm best-practices checklist: managers and quorum, labels and placement, limits and reservations, updates and rollbacks, secrets, networks, logging, backups and upgrades, each line linking to the guide that explains it.

Docker Swarm Best Practices: The Checklist for a Cluster That Stays Up (2026)

Every item here is something that has taken a swarm down, or made one slower to fix than it needed to be. The explanations live in the posts each line links to; this page is the list you check before a cluster goes to production and again after every change to it. Print it, or keep it beside the command reference.

Managers and the cluster

  • Three managers, or five. Never an even number, never one. The cluster survives the loss of a minority. (Guide: high availability)
  • Managers drained on any cluster that matters, so application workloads run on workers and a memory leak cannot reach the control plane.
  • Managers on a private network, reached by SSH from a bastion with keys. Nothing on 2375; 2377, 7946 and 4789 open between nodes only. (Security hardening)
  • Autolock on, and the unlock key stored with the root password. (Secrets)
  • A backup of /var/lib/docker/swarm from a manager, taken with the swarm locked or the daemon stopped, stored off the cluster and treated as secret.
  • Certificate expiry known. Node certificates rotate on their own every 90 days by default; the root CA does not. Check docker info for the CA and rotate it on your own schedule with docker swarm ca --rotate.

Nodes

  • Labels, not hostnames. Placement constraints reference node.labels.*, so a replacement machine inherits a role by being labelled, not by being renamed. (Guide: placement)
  • Drain before maintenance. docker node update --availability drain moves the tasks off; reboot; active brings them back.
  • Log rotation in daemon.json on every node: max-size and max-file. A full disk takes every task on the node with it.
  • The same Engine version on every node, upgraded managers first, one at a time, with the release notes read for Swarm entries. (What changed, release by release)
  • Time in sync. Raft and TLS both care; run chrony or systemd-timesyncd everywhere.

Services and stacks

  • Everything is a stack. No docker service create by hand in production; the stack file in git is the record of what runs. (Compose to Swarm)
  • Images pinned by digest, or at least by an immutable tag. :latest is a deploy you did not decide.
  • A healthcheck on every service that has an HTTP or TCP endpoint. Without one, Swarm considers a task healthy the moment the process starts.
  • update_config set on purpose: parallelism: 1, a delay, failure_action: rollback, and order: start-first for single-replica services. rollback_config the same.
  • Limits and reservations on every service. The reservation is what the scheduler needs free; the limit is where the kernel stops it. Set both, limit above reservation. (Pending states)
  • restart_policy written down. The Compose restart: key is ignored by stack deploy.
  • Stateful services pinned to a labelled node with a local volume. A named volume does not follow a task. (HA databases)
  • --with-registry-auth on every deploy that pulls from a private registry.
  • A tested rollback. docker service rollback on a staging swarm, once, before you need it on production.

Secrets and configuration

  • No credentials in environment:. Docker secrets through the _FILE convention, always.
  • Secrets versioned in their names (db_password_v3), rotated by a rolling update with a stable target.
  • Configs for non-secret files, so the stack file says what is sensitive and what is not.
  • Registry credentials as secrets or a pull-through cache, never baked into an image.

Networks

  • One overlay per concern: a public network the reverse proxy attaches to, an application network, a database network. Services reach each other by name; nothing else can.
  • Only the reverse proxy publishes ports. Databases, caches and internal APIs stay unpublished; the routing mesh publishes on every node, whether or not the task runs there.
  • Encrypted overlays where the node-to-node network is not yours.
  • mode: host ports paired with a placement constraint, because a host-bound port is only where the task is.

Observability

  • Prometheus and Grafana scraping every node, with alerts on node down, disk over 80 percent, task restarts and replication lag. (Monitoring)
  • Logs readable from a manager. json-file or journald on every node, or a shipper, so docker service logs works during an incident.
  • One place to see the whole cluster. SwarmCLI for the live view: tasks with their real error, nodes with their capacity, logs across replicas.

Security

  • The hardening guide worked through: socket, mTLS, identity in front of the daemon, secrets, ports, images scanned and signed, containers non-root and read-only with capabilities dropped.
  • Docker Bench run on every node after the first pass and after every upgrade, its warnings worked off.
  • Every human has their own identity on the cluster, through the RBAC proxy, and there is an audit log with names in it.

Backups and recovery

  • Application data backed up on a schedule, off the cluster, and restored once on purpose. Replication is not a backup; it replicates the bad DELETE too.
  • Swarm state backed up (above), and the procedure for docker swarm init --force-new-cluster written down before a quorum loss, not during one.
  • A staging swarm that receives every Engine upgrade and every stack change first, even if it is three small VMs.

Common concerns, answered

How many managers should a Docker Swarm have? Three for most clusters, five for large ones, never an even number and never one in production. The swarm keeps working while a majority of managers is up, so three tolerates one failure and five tolerates two. More than seven slows consensus for no gain.

Should Docker Swarm managers run workloads? Only on small clusters. On anything that matters, drain the managers with docker node update --availability drain so a runaway workload cannot take the control plane with it, and keep them on private networks.

How do I update a Docker Swarm service without downtime? Set update_config with parallelism 1, a delay, order start-first for single-replica services, and failure_action rollback, and give the service a healthcheck so Swarm knows when the new task is actually ready. Then docker service update --image replaces tasks one at a time and reverts on failure.

The five-minute version

Odd managers, drained and private. Labels, limits, healthchecks and an update policy on every service. Secrets through files, one overlay per concern, only the proxy publishes. Monitoring that alerts, logs you can read, backups you have restored. If those hold, the ten most common issues mostly do not happen, and the ones that do are found in the command reference's diagnostic sequence.