List a Stack's Services with docker stack services
Your stack is deployed, and now you want to know which of its services are actually up without wading through every service in the Swarm. This guide uses docker stack services to list, filter and format a stack's services in about ten minutes. The command is read-only: it does not scale, redeploy or remove anything. The examples use Docker CLI 29.8.1 from docker-ce-cli 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.
What you need:
- The Docker CLI and a running Swarm.
- A manager node. A machine that merely has Docker installed will not do.
- The exact stack name.
- No
sudo, unless your Docker setup needs elevated access to the daemon socket.
1. Check the installed command
Read the local command help before using it:
$ docker stack services --help
Usage: docker stack services [OPTIONS] STACK
List the services in the stack
The shape to remember is docker stack services [OPTIONS] STACK. STACK is a stack name, not a service name or a Compose file. The options on this installation are --filter, --format and --quiet, with the short forms -f and -q where provided.
Checkpoint
Record the version and confirm which binary will run.
$ docker version --format '{{.Client.Version}}'
29.8.1
$ command -v docker
/usr/bin/docker
2. Confirm manager access before querying
Use a real stack name from your deployment. The query below only reads Swarm state, but it still needs a manager:
$ docker stack services STACK_NAME
Replace STACK_NAME with a name such as myapp. Do not type the placeholder literally.
On a manager with that stack, the default table has columns such as ID, NAME, REPLICAS, IMAGE and COMMAND. Service IDs, images and replica counts are deployment-specific, so do not compare them with an example from another cluster.
A successful command normally exits silently apart from the table. Check the status immediately if a script depends on it:
$ docker stack services STACK_NAME > /tmp/stack-services.txt
$ status=$?
$ printf 'docker status: %s\n' "$status"
docker status: 0
Tip
The temporary file is only an example of capturing output. Use a private, controlled path if service names or image details are sensitive, and remove it after inspection with rm -- /tmp/stack-services.txt when you no longer need it.
Warning
If Docker reports that the node is not a Swarm manager, stop there. Moving to a manager or joining a Swarm changes cluster state and is an administrative decision outside this guide. If the stack name does not exist, check the spelling with whoever owns the Swarm; do not create a stack just to make a read-only query succeed.
3. Read the default service table
Run the query without formatting first:
$ docker stack services myapp
ID NAME MODE REPLICAS IMAGE PORTS
7be5ei6sqeye myapp_web replicated 1/1 nginx:latest
Your Docker release may include slightly different columns or alignment. The fields that matter are the service identity, mode, desired and running replicas, image, and any published ports.
A replica value such as 0/1 is a warning to investigate, not a command to restart the service. Inspect task details with the separate Swarm commands your operations process uses.
Do not mistake this for docker service ls, which lists services across the whole Swarm. docker stack services myapp limits the result to services associated with the named stack.
4. Filter the result
Use a filter when a stack has more services than you need. The filter value is a key=value pair. For example, filter by service name:
$ docker stack services --filter name=myapp_web myapp
ID NAME MODE REPLICAS IMAGE PORTS
7be5ei6sqeye myapp_web replicated 1/1 nginx:latest
The Docker documentation also describes id and label filters. Pass the option more than once when you need more than one value:
$ docker stack services \
--filter name=myapp_web \
--filter name=myapp_db \
myapp
Multiple filter flags are combined as an OR in current Docker documentation. Two name filters select either named service, rather than requiring one service to have both names. Keep that in mind in scripts.
Tip
If a filter returns no rows, check the stack name and the exact service name before concluding the service is absent.
5. Use quiet output for service IDs
--quiet prints only service IDs, which is useful when another command will consume them:
$ docker stack services --quiet myapp
7be5ei6sqeye
dn7m7nhhfb9y
Do not parse the human-readable table when IDs are all you need. The output can hold more than one line, so treat it as a list rather than a single value.
Warning
A missing stack or a manager error still produces a non-zero exit status. Always check the status before passing captured IDs to another command.
6. Format fields for scripts
Use a Go template with --format when a script needs stable fields rather than padded table columns:
$ docker stack services \
--format '{{.Name}} {{.Replicas}} {{.Image}}' \
myapp
myapp_web 1/1 nginx:latest
myapp_db 1/1 postgres:16
The documented service placeholders include .ID, .Name, .Mode, .Replicas and .Image. The template controls the fields and separators, so choose a separator that cannot occur in the values you expect, or use a more structured format.
For one JSON object per service, use the installed CLI's JSON directive:
$ docker stack services --format json myapp
{"ID":"7be5ei6sqeye","Name":"myapp_web","Mode":"replicated","Replicas":"1/1","Image":"nginx:latest"}
Warning
JSON output is a report, not a backup of the stack definition. It does not contain every deployment setting, and it should not be edited and fed back to Docker. If a later tool processes the output, check the command exited successfully before parsing it.
7. Keep the inspection reversible
Every command in this workflow reads Swarm metadata. It does not change replicas, service definitions, images or routing, so there is no rollback step.
The main trap is following an unhealthy replica count with an unplanned repair. Treat that as a separate change: record the observed output, identify the service owner, and use an approved deployment procedure before running commands such as service update, scale or remove.
For a repeatable check, save a timestamp beside a report rather than overwriting a useful one:
$ report="stack-services-$(date +%Y%m%d-%H%M%S).txt"
$ docker stack services --format '{{.Name}} {{.Mode}} {{.Replicas}} {{.Image}}' myapp > "$report"
$ test -s "$report" && sed -n '1,20p' "$report"
myapp_web replicated 1/1 nginx:latest
Recovery
Check the report before archiving it. If the query failed, the redirection may still have created an empty file. Remove only that known temporary report with rm -- "$report", not a broad wildcard.
Done means
- Basics confirmed. You checked Docker CLI 29.8.1 and the exact stack name.
- Right place. The query ran on a Swarm manager and returned status 0.
- Reading the output. You can read the default table or select services with a verified filter.
- Script output chosen. You use
--quietfor IDs and--formatfor script-friendly fields. - Nothing changed. You treated replica warnings as observations and made no unapproved service changes.