Read Docker Swarm Nodes Without Changing the Cluster
docker node ls is entirely read-only: it lists, filters and formats, but it cannot promote, demote, drain or remove a single node. This guide covers listing every node from a manager, narrowing the view with filters, and choosing output that suits a person or a script. Allow about ten minutes if you already have access to a Swarm manager.
The route
Jump straight to the step you need, or tick off Done means at the end.
- You need: the Docker CLI installed, and the selected Docker context connected to a Swarm manager.
- Version used here: Docker CLI 29.8.1, installed from the
docker-ce-clipackage on this machine. - Note: output columns and formatting features can differ between CLI releases, so check the local help when reproducing an example elsewhere.
1. Check the client and selected context
Start by checking the CLI version and the endpoint that the command will use:
$ docker --version
Docker version 29.8.1, build 4a63305
$ docker context show
default
The context name is only a routing choice: it does not prove that the endpoint is a Swarm manager. Do not change contexts or initialise a swarm just to make this listing work. docker swarm init changes cluster state and can create a new single-node swarm, which is outside this inspection task.
Checkpoint
If you are meant to inspect a remote swarm, select its already configured context before continuing. If you do not know which context is correct, stop and ask the swarm administrator rather than guessing.
2. List every node from a manager
Run the command without options:
$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
yg550ettvsjn6g6t840iaiwgb * swarm-manager1 Ready Active Leader 23.0.3
2lm9w9kbepgvkzkkeyku40e65 swarm-worker1 Ready Active 23.0.3
The exact IDs, names and versions will be different. The asterisk marks the node associated with the current Docker daemon. STATUS describes the node's condition, AVAILABILITY is its scheduling state, and MANAGER STATUS is populated for managers only: a blank manager-status field normally means the node is a worker, not that the command failed.
This is a manager-only cluster command. On a machine that is not a Swarm manager, the same command returns: This node is not a swarm manager. That error is an access or endpoint problem, not evidence that the swarm has no nodes.
Use docker node ls --help to confirm the options exposed by the installed client:
$ docker node ls --help
Usage: docker node ls [OPTIONS]
List nodes in the swarm
3. Filter the list for a question
Filters use key=value. The supported keys documented for this command include id, label, node.label, membership, name and role. Pass --filter more than once when you need more than one filter:
$ docker node ls --filter 'role=manager'
$ docker node ls --filter 'membership=accepted'
$ docker node ls --filter 'name=swarm-manager1'
$ docker node ls --filter 'id=1'
The id value can match all or part of a node ID, and name matches all or part of a node hostname. The role values are manager and worker. Membership values are accepted and pending. If a filter produces no rows, check spelling and the selected context before treating that as a cluster condition.
Engine labels and Swarm node labels are different filters: use label for an engine label and node.label for a label assigned to the Swarm node.
$ docker node ls --filter 'node.label=region'
$ docker node ls --filter 'node.label=region=region-a'
$ docker node ls --filter 'label=example'
These commands only query labels. Do not substitute docker node update --label-add unless changing scheduling metadata is explicitly approved; that update changes cluster behaviour.
4. Produce compact or machine-readable output
For a list of IDs only, use quiet mode:
$ docker node ls --quiet
yg550ettvsjn6g6t840iaiwgb
2lm9w9kbepgvkzkkeyku40e65
This is useful as input to a reviewed script, but an ID alone does not tell you whether a node is ready or drainable. Keep the normal table output when a person needs operational context.
For a stable, selected set of fields, use a Go template. The available fields include .ID, .Self, .Hostname, .Status, .Availability, .ManagerStatus, .TLSStatus and .EngineVersion:
$ docker node ls --format '{{.Hostname}}: {{.Status}}/{{.Availability}}'
swarm-manager1: Ready/Active
swarm-worker1: Ready/Active
The template above omits headers, so label it yourself if another program or person needs to know what each field means. For one JSON object per node, use the documented JSON directive:
$ docker node ls --format json
{"Availability":"Active","EngineVersion":"23.0.3","Hostname":"swarm-manager1","ID":"yg550ettvsjn6g6t840iaiwgb","ManagerStatus":"Leader","Self":true,"Status":"Ready","TLSStatus":"Ready"}
Do not parse the aligned table with awk or fixed character positions: columns can be blank, added or adjusted by the CLI. Prefer a template or JSON when another command will consume the result.
5. Diagnose the common failures
- Not a Swarm manager. Verify the context and endpoint, then repeat the command against an existing manager. A worker can run many Docker commands but cannot use this manager-only listing. Do not run
docker swarm initon a production host as a repair step. - Permission or connection errors. Check the current context, Docker socket access and the administrator's access method. The listing itself does not normally require
sudo. Elevation changes which local Docker socket or credentials are used, so use it only when your host policy specifically requires it, and confirm the resulting context rather than assuming it is the same daemon. - Unexpectedly empty or stale-looking data. Repeat the unfiltered command, record the context with
docker context show, and compare the manager endpoint with the one that owns the swarm. A filter can hide nodes, and a different context can show a different cluster. CheckSTATUS,AVAILABILITYandMANAGER STATUStogether before taking action elsewhere. - A script breaks after an upgrade. Run
docker node ls --helpon the target machine and confirm the fields it expects. Pin the output contract in the script, handle blank manager fields, and treat command failure as a failure rather than as an empty node list.
Done means
- Version and context checked. You confirmed the Docker CLI version and selected context.
- Ran against a manager. You ran
docker node lsagainst an existing Swarm manager. - Filters used safely. You used filters only to narrow inspection, without changing labels or node state.
- Output matched the consumer. You chose quiet, templated or JSON output to match the consumer.
- State-changing commands stayed out. You kept
docker swarm init, node updates and other state-changing commands out of a read-only check.