RUN A FLEET WITH DOCKER COMPOSE
This guide shows you how to deploy a pool of Swamp workers with Docker Compose, using a single fleet token to enroll multiple containers.
Prerequisites
You need a running orchestrator with TLS and token authentication. See
Run a Worker in Docker for the
orchestrator setup steps (TLS certificate, swamp serve, server token).
Create a fleet token
Create an enrollment token that allows multiple machines to enroll:
swamp worker token create compose-fleet --duration 7d --max-enrollments 20Save the token value. Each container that connects with this token receives an
auto-generated name (compose-fleet-<suffix>) and a fleet=compose-fleet
label.
Write the Compose file
services:
worker:
image: swamp-worker
environment:
SWAMP_ORCHESTRATOR_URL: wss://host.docker.internal:9090
SWAMP_SERVER_TOKEN: admin.<secret>
SWAMP_WORKER_TOKEN: compose-fleet.<secret>
SWAMP_WORKER_CONCURRENCY: "4"
DENO_CERT: /certs/cert.pem
volumes:
- ./cert.pem:/certs/cert.pem:ro
command: ["worker", "connect"]
stop_grace_period: 5m
restart: on-failurestop_grace_period: 5m gives in-flight steps five minutes to complete when
Docker sends SIGTERM during docker compose down or scaling events. If a step
takes longer than the grace period, Docker force-kills the container and the
step is lost.
restart: on-failure restarts a worker that crashes but does not restart one
that exits cleanly (exit code 0). A clean exit happens when --max-dispatches
or --idle-timeout triggers a drain.
SWAMP_WORKER_CONCURRENCY sets the number of concurrent dispatch slots per
container. Adjust based on the workload — CPU-bound steps benefit from fewer
slots; I/O-bound steps can handle more.
Scale the fleet
Start with one worker, then scale up:
docker compose up -d
docker compose up -d --scale worker=5Verify enrollment:
swamp worker listEach worker appears with its auto-generated name and the fleet=compose-fleet
label.
To scale down, Docker sends SIGTERM to the excess containers. Each drains its in-flight work before exiting:
docker compose up -d --scale worker=2Run a parallel workload
Create a workflow with a forEach that fans work across the fleet:
jobs:
- name: parallel-work
forEach:
items: ["a", "b", "c", "d", "e"]
steps:
- name: process
task:
type: model_method
modelIdOrName: "processor-${{ self.item }}"
methodName: run
labels:
fleet: compose-fleetswamp workflow run fan-outSteps dispatch to available workers across the fleet. The orchestrator selects the worker with the most available capacity for each step.
Per-model lock: steps that write to the same model definition serialize on the definition's datastore lock. If the
forEachitems all target the samemodelIdOrName, they run sequentially regardless of fleet size. Use distinct model names (as above, with${{ self.item }}) for true parallelism. See Workflow Placement for scheduling details.
Add lifecycle policies
To run workers that process a fixed number of steps and exit:
environment:
SWAMP_WORKER_MAX_DISPATCHES: "10"To run workers that exit after 10 minutes of inactivity:
environment:
SWAMP_WORKER_IDLE_TIMEOUT: 10mBoth produce exit code 0, so restart: on-failure does not restart the
container.
Related
- Run a Worker in Docker — single-worker setup and TLS configuration
- Run a Fleet on Kubernetes — deploy to Kubernetes instead
- Scale from Zero Workers — submit work before workers connect
- Worker Commands — full CLI and environment variable reference