Running with Docker
Squadron publishes Docker images to GitHub Container Registry on every release. Two variants are available:
| Image | Tag | Use case |
|---|---|---|
| Alpine | ghcr.io/mlund01/squadron:latest | Default — small, static binary |
| Debian | ghcr.io/mlund01/squadron:latest-debian | Plugins that need glibc/CGO |
Both images support linux/amd64 and linux/arm64.
Quick Start
docker run --rm ghcr.io/mlund01/squadron versionMounts
Squadron in Docker uses a single mount point:
| Mount | Purpose |
|---|---|
/config | Your HCL configuration files and .squadron/ state directory |
All runtime state (vault, plugins, database) lives in /config/.squadron/, right alongside your HCL config files. The container’s working directory is /config, so the -c flag is not needed.
Run with the Command Center UI
docker run -it \
-v ./my-project:/config \
-p 8080:8080 \
ghcr.io/mlund01/squadron engage --cc-itis optional — with it, the quickstart wizard runs on an empty project. Without it, Squadron auto-initializes and you set everything up from the UI.-p 8080:8080publishes the command center to the host. Openhttp://localhost:8080.
The official image sets SQUADRON_CONTAINER=1, which makes Squadron run in the foreground and skip browser auto-open. You never need to pass --foreground here.
If some variables are missing, Squadron still starts — the UI lets you set them after the container is up.
Connect to a Remote Command Center
If your HCL config declares a command_center block, Squadron connects outbound — no --cc and no port mapping needed:
docker run \
-v ./my-project:/config \
ghcr.io/mlund01/squadron engagePassing --cc alongside a command_center block is an error.
Run a Single Mission
docker run \
-v ./my-project:/config \
ghcr.io/mlund01/squadron mission --init my_missionDocker Compose
services:
squadron:
image: ghcr.io/mlund01/squadron:latest
volumes:
- ./my-project:/config
command: ["engage", "--cc"]
ports:
- "8080:8080"docker compose upSetting Variables
Variables are stored in an encrypted vault at /config/.squadron/vars.vault. There are two ways to set them:
Via the command center UI (easiest): Open the UI at http://localhost:8080, navigate to Variables, and add them there.
Via vars set in a running container:
docker exec <container> squadron vars set anthropic_api_key sk-ant-...Securing the Vault Passphrase
By default, when Squadron auto-initializes the vault, it writes the passphrase to /config/.squadron/vault.key with 0600 permissions. This works fine when the volume is local and trusted.
For stronger production setups, mount a passphrase file as a Docker secret:
services:
squadron:
image: ghcr.io/mlund01/squadron:latest
volumes:
- ./my-project:/config
command: ["engage", "--cc"]
secrets:
- vault_passphrase
ports:
- "8080:8080"
secrets:
vault_passphrase:
file: ./vault_passphrase.txtSquadron checks /run/secrets/vault_passphrase automatically. If the file exists, it uses that passphrase instead of the on-disk key. Docker mounts secrets as tmpfs, so the passphrase never touches the container’s disk.
Pinning a Version
Use a version tag instead of latest:
docker pull ghcr.io/mlund01/squadron:v0.0.45
docker pull ghcr.io/mlund01/squadron:v0.0.45-debianAlpine vs Debian
- Alpine (
latest) — smaller image, static binary withCGO_ENABLED=0. Use this unless you have a reason not to. - Debian (
latest-debian) — larger image, built withCGO_ENABLED=1. Use this if you have plugins that depend on C libraries or glibc.