Inspect a Docker Swarm Service Without Touching It
docker service inspect pulls the full state of a Swarm service so you can check facts instead of guessing. You will read that state as JSON, as pretty text, or as a single templated value, and learn to tell a missing service from a manager you cannot even reach. The examples match Docker CLI 29.8.1, installed here as 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 about ten minutes. Bring the Docker CLI and access to a Swarm manager: nothing here updates a service, deploys a task or changes cluster state. Docker may still gate its socket, so use whatever account and privilege arrangement your host already has approved. Do not join the docker group just to make a command run: that membership hands you broad control over the daemon.
1. Confirm the installed command
Check the client version and the local option set before you copy anyone else's example:
$ docker --version
Docker version 29.8.1, build 4a63305
$ docker service inspect --help
Usage: docker service inspect [OPTIONS] SERVICE [SERVICE...]
Options:
-f, --format string Format output using a custom template
--pretty Print the information in a human friendly format
The service name or ID is mandatory. This build has two command-specific switches:
--format(or-f). Format the output with a Go template.--pretty. Print a human-friendly summary instead of JSON.
Options from docker inspect do not carry over automatically.
Checkpoint
If your help output differs, read it before copying an example: you may be running a different CLI version or a vendor build.
2. Make sure the host can see the Swarm
List services first. This gives you an exact name or ID, and proves your current Docker context reaches a manager:
$ docker service ls
ID NAME MODE REPLICAS IMAGE
abc123... frontend replicated 3/3 nginx:alpine
Use the values your own host prints, not these. If Docker says the node is not a Swarm manager, switch context or query an approved manager instead: a worker cannot run this cluster-management command. Do not run docker swarm init as a shortcut around that error either, because it changes cluster state and sits well outside this guide.
Socket permission error instead? Check context and group membership before reaching for elevated privileges:
$ docker context show
default
$ id -nG
developers docker
That output is host-specific. Use sudo docker ... only where your operating policy requires it: changing group membership or context configuration is its own administrative change and deserves its own review.
3. Inspect one service as JSON
Pass the exact service name or ID:
$ docker service inspect frontend
Docker always wraps the result in a JSON array, even for a single service. The first object usually carries ID, Version, timestamps, Spec, Mode and Endpoint, though the exact shape depends on the service and your Docker version.
That specification can expose image references, labels, environment values, mounts and endpoint details. Save it only somewhere protected, with sensible retention. Treat it as operational data, not harmless debug text.
Checkpoint
Validate the response before you trust a field:
$ docker service inspect frontend | jq '.[0] | {id: .ID, name: .Spec.Name, mode: .Mode}'
{
"id": "abc123...",
"name": "frontend",
"mode": {
"Replicated": {
"Replicas": 3
}
}
}
jq is optional here. Without it, use the raw JSON or a Docker template instead.
4. Get a human-readable view
For an interactive look, ask Docker for its human-oriented view:
$ docker service inspect --pretty frontend
ID: abc123...
Name: frontend
Service Mode: REPLICATED
ContainerSpec:
Image: nginx:alpine
Endpoint Mode: vip
Current Docker documentation also accepts --format pretty for the same style. It reads well for a person, but it is not a stable interchange format: use JSON or an explicit template for anything scripted.
5. Pull specific values with a Go template
Use --format for a repeatable one-line answer. For a replicated service, this prints the desired replica count:
$ docker service inspect --format '{{.Spec.Mode.Replicated.Replicas}}' frontend
3
That path is conditional: a global service has no .Spec.Mode.Replicated.Replicas field at all. Inspect the JSON first if you are not sure whether a service is replicated, global or a job. To print several fields at once:
$ docker service inspect --format 'name={{.Spec.Name}} image={{.Spec.TaskTemplate.ContainerSpec.Image}}' frontend
name=frontend image=nginx:alpine
For a nested structure, reach for Docker's json function:
$ docker service inspect --format '{{json .Spec.TaskTemplate.ContainerSpec}}' frontend
{"Image":"nginx:alpine",...}
A blank result is not proof that a field is empty. The path may simply not exist for that service mode or version. Compare it against the full JSON before you build an alert on it.
6. Inspect several services in one go
The synopsis accepts multiple service arguments, and Docker runs the format once per service:
$ docker service inspect --format 'name={{.Spec.Name}} id={{.ID}}' frontend backend
name=frontend id=abc123...
name=backend id=def456...
Names and IDs can be mixed, but each one must resolve in the manager's context. Misspell one and the whole command can fail rather than hand you a partial report, so check the exit status in automation and log exactly what you asked for.
7. Tell a manager error from a lookup error
A message saying the node is not a Swarm manager is a placement or context problem, not proof the service is missing. A message that a service cannot be found means the manager answered but could not resolve your name or ID. Check these in order:
$ docker context show
default
$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
manager-id... manager-1 Ready Active Leader
$ docker service ls
ID NAME MODE REPLICAS IMAGE
abc123... frontend replicated 3/3 nginx:alpine
docker node ls is also manager-only, so if that fails, fix context or access first. If the service shows up in docker service ls but inspecting it by name fails, use its exact ID instead and check the shell has not added stray whitespace or expanded an unquoted placeholder.
Recovery
Inspection needs no rollback. Return to the previous context or command; do not create, update, remove or restart a service just to repair a read-only query, because those actions can disrupt real workloads and need their own change plan.
Done means
- Confirmed the CLI. You checked the installed version and the local
service inspectsyntax. - Queried the right manager. You ran the command against the intended Swarm manager and Docker context.
- Used an exact name or ID. Copied straight from
docker service ls, not from memory. - Picked the right output. JSON,
--prettyor a Go template, whichever the task needed. - Accounted for service mode. Your template handles a missing field instead of assuming zero.
- Changed nothing. No Swarm was initialised and no service touched while you were only looking.