My App

Docker Swarm Operations

Production topology, network requirements, and safe cluster operations.

Upstand operates one Docker Swarm control plane. It must run on a reachable manager node; workers can run application tasks but cannot safely inspect or change cluster state.

Production topology

  • Run an odd number of managers for high availability. Three managers is the normal minimum; manager nodes need reliable, low-latency connectivity.
  • Keep Postgres, Redis, and the Upstand API on the manager labelled upstand.control-plane=true. Their local volumes do not automatically move when a node fails.
  • Allow TCP 2377, TCP/UDP 7946, and UDP 4789 between every node. Open only the externally published application ports to the internet.
  • Initialize the manager with a routable SWARM_ADVERTISE_ADDR. Do not use localhost, 127.0.0.1, or 0.0.0.0.
  • The dashboard defaults overlay allocation to 10.20.0.0/16 and 10.21.0.0/16 with /24 subnets. If either overlaps an existing network, set a non-overlapping pool through the Swarm API before initialization.
  • The shared upstand-network must remain an attachable overlay network. Upstand refuses to silently replace a network with a bridge network.

Installation

The production installer deploys immutable image digests and validates the Swarm network before it creates the stack.

export SWARM_ADVERTISE_ADDR=10.0.0.10
export BETTER_AUTH_URL=https://api.example.com
export CORS_ORIGIN=https://console.example.com
export NEXT_PUBLIC_SERVER_URL=https://api.example.com
export UPSTAND_SERVER_IMAGE=ghcr.io/upstand/upstand-server@sha256:<digest>
export UPSTAND_WEB_IMAGE=ghcr.io/upstand/upstand-web@sha256:<digest>
export UPSTAND_DOCS_IMAGE=ghcr.io/upstand/upstand-fumadocs@sha256:<digest>

sudo bash ./install.sh

The installer writes origins and resolved image references to /etc/upstand/.env with mode 0600, and writes each generated credential to /etc/upstand/secrets/ as a Docker secret source file. Treat both paths as sensitive. It also uses docker stack deploy --resolve-image always --with-registry-auth --prune so a rollout has a resolved image digest and stale services are removed.

Cluster dashboard

The Docker Swarm dashboard is restricted to organization owners and requires a verified second factor when 2FA is enabled. It exposes cluster state separately from join credentials:

  • Join commands are hidden until explicitly revealed.
  • Rotating a worker or manager token immediately invalidates unused commands for that role.
  • Node updates include Docker's object version. If the cluster changed while the dashboard was open, the action is rejected rather than overwriting current state.
  • Removing a node requires its exact hostname, drains it first, and refuses to remove the leader, the local control-plane manager, or the last manager.

The task view intentionally shows Swarm task state rather than fabricated CPU, memory, or disk figures. A manager cannot reliably report per-container metrics from every remote host without a dedicated node-level metrics collector.

Routine operations

  1. Add workers with the worker join command. Use manager joins only for stable hosts that should hold Raft state.
  2. Before maintenance, set a node to drain and wait for eligible tasks to reschedule.
  3. Verify manager quorum before demoting or removing a manager.
  4. Rotate join tokens after staff changes, a lost server, or any suspected command exposure.
  5. Back up Postgres and all resource volumes independently; Swarm does not replicate local volumes.

Use docker node ls, docker service ls, and docker stack services upstand from a manager for an out-of-band operational check during incidents.

On this page