Skip to main content

RUN A WORKER IN DOCKER

This guide shows you how to run a single Swamp worker inside a Docker container, connected to an orchestrator on your host machine.

For deploying a scalable pool of workers, see Run a Fleet with Docker Compose.

Build the worker image

Create a Dockerfile that installs Swamp from the install script:

FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y --no-install-recommends curl ca-certificates tini \
  && rm -rf /var/lib/apt/lists/*
RUN curl -fsSL https://swamp-club.com/install.sh | sh
ENTRYPOINT ["/usr/bin/tini", "-s", "--", "swamp"]

The entrypoint runs Swamp under tini so that processes a step leaves behind are reaped instead of lingering as zombies until the container exits.

Build the image:

docker build -t swamp-worker .

Generate a self-signed TLS certificate

The orchestrator requires TLS for off-loopback connections. For local testing, generate a self-signed certificate:

openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 \
  -pkeyopt ec_param_enc:named_curve \
  -keyout key.pem -out cert.pem -days 30 -nodes \
  -subj "/CN=localhost" \
  -addext "subjectAltName=DNS:localhost,DNS:host.docker.internal" \
  -addext "basicConstraints=CA:FALSE"

basicConstraints=CA:FALSE is required — without it, the Deno runtime rejects the certificate as a CA certificate used as a server certificate.

ec_param_enc:named_curve is required with the LibreSSL openssl that ships with macOS. Without it, LibreSSL writes the key with explicit curve parameters and swamp serve exits at startup with Error: keys may not be consistent: KeyMismatch. OpenSSL 3 accepts the flag and produces the same pair either way.

Include host.docker.internal in the SAN so the worker can verify the certificate when connecting from inside the container.

Start the orchestrator

Authenticate with swamp auth login or set SWAMP_API_KEY with serve:* scope — every Swamp process needs a swamp-club.com account, see Swamp Account Requirement — then start swamp serve with TLS, token authentication, at least one admin principal, and the host bound to 0.0.0.0 so the container can reach it:

swamp serve \
  --host 0.0.0.0 \
  --cert-file cert.pem \
  --key-file key.pem \
  --auth-mode token \
  --admins 'user:<you>' \
  --trusted-hosts host.docker.internal

--admins is required with --auth-mode token; see Set Up Token Authentication. --trusted-hosts allows the Host: host.docker.internal header that Docker sends. Without it, the orchestrator rejects the connection. See Serve Flags for the full flag reference.

Create tokens

In a separate terminal, in the same repository, mint a server token for the worker and create a worker enrollment token:

swamp access token mint worker-token --principal user:worker --duration 24h
swamp worker token create docker-worker --duration 24h

The server token's plaintext is stored in a vault. Print it with:

swamp access token reveal worker-token --yes

The value has the form worker-token.<secret>. Save the enrollment token value too — it is shown once.

Run the worker container

Every Swamp process needs a swamp-club.com credential to start, and a container has no swamp auth login. Give the worker a collective token as SWAMP_API_KEY and its signin token as SWAMP_SIGNIN_TOKEN, which lets the worker start while swamp-club.com is unreachable. Both are shown once when the collective token is created — see Run Swamp in CI.

docker run -d --name swamp-worker \
  -e SWAMP_API_KEY=swamp_org_<hex> \
  -e SWAMP_SIGNIN_TOKEN=<signin-token> \
  -e SWAMP_ORCHESTRATOR_URL=wss://host.docker.internal:9090 \
  -e SWAMP_SERVER_TOKEN=worker-token.<secret> \
  -e SWAMP_WORKER_TOKEN=docker-worker.<secret> \
  -e SWAMP_WORKER_LABELS=env=docker \
  -e SWAMP_CA_CERT=/certs/cert.pem \
  -v "$(pwd)/cert.pem:/certs/cert.pem:ro" \
  swamp-worker worker connect

On Linux with Docker Engine rather than Docker Desktop, host.docker.internal does not resolve inside a container by default. Add --add-host host.docker.internal:host-gateway to the docker run command.

SWAMP_CA_CERT makes the worker trust the self-signed CA certificate, which is bind-mounted into the container. Images with a Swamp release older than v20260922.185723.0-sha.33229b53 also need -e DENO_CERT=/certs/cert.pem; see TLS and Proxies.

Refer to Worker Commands for the full list of environment variables and flags.

Verify enrollment

Confirm the worker appears in the pool:

swamp worker list

The worker should show as connected with the env=docker label.

Run a placed workflow

Create a workflow that targets the Docker worker by label and run it:

jobs:
  - name: test
    steps:
      - name: hello
        task:
          type: model_method
          modelIdOrName: my-model
          methodName: run
        labels:
          env: docker
swamp workflow run my-workflow

The step dispatches to the Docker worker. Confirm completion with swamp workflow status my-workflow.