Swarm provider

The Swarm provider discovers entrypoints from Docker Swarm services. Sōzune connects to a Swarm manager, lists services, and reads sozune.* labels declared on the service spec (not on the underlying tasks/containers).

This is the right provider when your stack is deployed with docker stack deploy or docker service create instead of plain docker run.

Configuration

providers:
  swarm:
    enabled: true
    endpoint: "/var/run/docker.sock"
    expose_by_default: false
    network: "sozune-public"
    refresh_interval: 15
FieldDefaultDescription
enabledfalseEnables the Swarm provider
endpoint/var/run/docker.sockDocker socket. Must point to a Swarm manager node.
expose_by_defaultfalseIf true, every service is a candidate even without sozune.enable=true
network""Optional overlay network name. When set, Sōzune ignores VIPs on other networks.
refresh_interval15Periodic poll interval in seconds (safety net behind the event stream)

How it works

  1. Sōzune subscribes to Docker events filtered on type=service for near-real-time reactions to service create, service update and service rm.
  2. A periodic poll (refresh_interval) re-runs the same diff against the Swarm API. This is a safety net for missed events or disconnected streams.
  3. On every diff, Sōzune replaces the full set of source: "swarm" entrypoints in storage and triggers a reload.

Service labels are parsed by the same engine the other providers use (Docker, Podman, Kubernetes, Nomad, HTTP, config file), so sozune validate reports the exact diagnostics the runtime applies.

Example service

docker service create \
  --name my-api \
  --label sozune.enable=true \
  --label sozune.http.api.host=api.example.com \
  --label sozune.http.api.port=8080 \
  --network sozune-public \
  --replicas 3 \
  my-api:latest

Example stack file

Deploy with docker stack deploy -c stack.yml mystack:

networks:
  sozune-public:
    external: true

services:
  api:
    image: my-api:latest
    networks:
      - sozune-public
    deploy:
      replicas: 3
      labels:
        sozune.enable: "true"
        sozune.http.api.host: "api.example.com"
        sozune.http.api.port: "8080"
        sozune.network: "sozune-public"

Important: put sozune.* labels under deploy.labels, not services.api.labels. Service-level labels live on the running tasks (containers); only deploy.labels are stored on the service spec, which is what Sōzune reads.

Backend resolution

Swarm exposes two endpoint modes:

  • vip (default). Swarm assigns one virtual IP per attached overlay network and load-balances behind it. Sōzune uses that VIP as the single backend, so scaling the service does not churn Sōzune's cluster — Swarm balances internally.
  • dnsrr. Swarm relies on DNS round-robin. The Docker API does not expose individual task IPs through bollard 0.20, so Sōzune cannot enumerate per-replica backends in this mode. If a VIP is still attached, Sōzune falls back to it and logs a warning. For production multi-replica routing through Sōzune, prefer vip (the Swarm default).

The network config field, when set, restricts which overlay's VIP Sōzune considers. This is useful when the same service is attached to several overlays (e.g. a public ingress overlay plus a private backend overlay).

Coexistence with the Docker provider

On a Swarm node, the local Docker socket exposes both services (Swarm) and containers (the tasks running locally). If you enable both providers.docker and providers.swarm against the same socket, you will discover the same workload twice — once at the service level and once at the task level — with potentially conflicting labels.

Recommendation: pick one. Use swarm when your stack is service-deployed; use docker for plain single-host containers.

Each provider tags its entries with a distinct source (swarm vs docker), so a misconfiguration is visible through the API or dashboard, but Sōzune does not deduplicate across providers.

Requirements

  • The endpoint socket must point to a manager node. On a worker, the Docker daemon refuses Swarm API calls and Sōzune logs an error per poll.
  • Sōzune itself must be able to reach the chosen overlay network. The simplest setup is to run Sōzune as a Swarm service attached to the same overlay as the discovered services. Otherwise, expose ports with mode=host.

Environment variables

FieldEnv var
providers.swarm.enabledSOZUNE_PROVIDER_SWARM_ENABLED
providers.swarm.endpointSOZUNE_PROVIDER_SWARM_ENDPOINT
providers.swarm.expose_by_defaultSOZUNE_PROVIDER_SWARM_EXPOSE_BY_DEFAULT
providers.swarm.networkSOZUNE_PROVIDER_SWARM_NETWORK
providers.swarm.refresh_intervalSOZUNE_PROVIDER_SWARM_REFRESH_INTERVAL