Create a Docker Swarm and Add Its First Worker
You will finish with one Docker Engine acting as a Swarm manager and a second Engine joined as a worker. You will also have a repeatable check for membership and a safe way to handle the join token. The examples were checked with Docker CLI 29.8.1 from package docker-ce-cli version 5:29.8.1-1~ubuntu.24.04~noble.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow 15 to 30 minutes, plus time for network access between the hosts. You need two Linux machines with Docker Engine installed and running, administrative access to the Docker daemon on both, and a manager address that the worker can reach. The commands that initialise or join a swarm change Docker state and may affect later deployments. Do not run them on a host that already belongs to a swarm until you have checked its current role.
1. Check the CLI and the daemon
Run these read-only checks on each host:
$ docker --version
Docker version 29.8.1, build 4a63305
$ docker info --format '{{.ServerVersion}}'
29.8.1
The first command checks the client. The second asks the daemon for its server version. A permission error usually means your account cannot access Docker's Unix socket; fix that host access before attempting Swarm administration. Do not add sudo everywhere by habit. Use it only if your installation requires elevated access, and keep the privilege boundary visible.
Checkpoint: confirm that the two hosts are running compatible Docker Engine releases and that the worker can reach the manager's planned address. Swarm control traffic normally uses TCP port 2377; the overlay data path also needs the network ports required by your deployment.
2. Inspect the command before changing state
The local docker-swarm(1) manpage describes the command as Manage Swarm
and points to the individual subcommands. Ask the installed CLI for the options you will use:
$ docker swarm --help
Usage: docker swarm COMMAND
Manage Swarm
Commands:
init Initialize a swarm
join Join a swarm as a node and/or manager
$ docker swarm init --help
Usage: docker swarm init [OPTIONS]
Initialize a swarm
This is a useful distraction trap: docker swarm is a command group, not the operation that creates a cluster. The state-changing operation is docker swarm init. The CLI also provides management commands such as docker swarm join-token and docker swarm leave, even though the short group listing on this installed build is abbreviated.
3. Initialise the manager with a reachable address
On the host that will be the first manager, replace MANAGER_IP with the address the worker will actually use:
$ sudo docker swarm init --advertise-addr MANAGER_IP
--advertise-addr tells other nodes where to contact this manager. If the host has one suitable address, Docker can often select one automatically, but an explicit address avoids choosing the wrong interface on a multi-homed machine or a cloud host with separate internal and external addresses.
Warning
Initialisation enables Swarm mode on this Engine, creates the manager's cluster state and prints join credentials. Read the output before closing the terminal. The worker join token is secret material: do not paste it into a ticket, commit it to a repository or include it in ordinary logs.
Successful output begins in this form, with different IDs and token values:
Swarm initialized: current node (...) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-... MANAGER_IP:2377
Checkpoint: verify the manager without changing it:
$ docker info --format '{{.Swarm.LocalNodeState}} manager={{.Swarm.ControlAvailable}}'
active manager=true
4. Retrieve a fresh worker join command
If you did not save the initial output, run this on the manager:
$ sudo docker swarm join-token worker
Docker prints a command containing the worker token and the manager endpoint. Copy it directly to the worker, keeping the token private. For automation, --quiet prints only the token, but that is still a credential:
$ sudo docker swarm join-token --quiet worker
SWMTKN-...
A worker token grants entry as a worker, not as a manager. Manager tokens are more sensitive because a manager participates in the Raft-controlled cluster state. If a token leaks, rotate the affected token on the manager with sudo docker swarm join-token --rotate worker or the corresponding manager form, then use the newly printed value for future joins. Rotation does not remove nodes that already joined.
5. Join the worker
On the second host, run the exact command produced by the manager. This example shows placeholders rather than a real credential:
$ sudo docker swarm join \
--token SWMTKN-REPLACE_WITH_CURRENT_WORKER_TOKEN \
MANAGER_IP:2377
This node joined a swarm as a worker.
Joining changes the worker's Docker state, requests a TLS certificate from the manager and adds the node to the swarm. If the command reports a connection failure, check the advertised address, DNS or routing, and the firewall before retrying. Do not generate a new swarm on the worker: that creates a separate cluster rather than fixing connectivity.
Checkpoint: the manager is the authoritative place to see membership:
$ sudo docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
... worker-1 Ready Active
The manager itself should also appear with a manager status such as Leader. docker node ls is a manager operation, so a worker should not be expected to run it successfully.
6. Undo a mistaken join safely
If the worker joined the wrong swarm and no service workload depends on it, leave from that worker:
$ sudo docker swarm leave
Node left the swarm.
Leaving removes that node's membership; it does not delete the swarm or remove other nodes. If a worker refuses because of a local condition, inspect the message first. The --force option exists, but use it only when you understand the effect and normal leaving cannot complete. On a manager, leaving can reduce quorum and disrupt administration, so remove or replace managers deliberately rather than treating the command as routine cleanup.
Done means
- The manager reports an active Swarm state and has the intended advertised address.
- The worker joined with a worker token kept out of repositories and general logs.
docker node lson the manager shows the worker asReadyandActive.- You know how to rotate a leaked token and how to make a mistaken worker leave.
- No manager was added casually: high availability needs an odd number of managers and a maintained quorum.