-
Notifications
You must be signed in to change notification settings - Fork 0
Deployment
Three supported ways to run coopd beyond a foreground coopd serve &.
β οΈ Before exposing Coop beyond127.0.0.1setCOOP_API_TOKEN(bearer auth) andCOOP_PUBLIC=1(accept non-loopbackHost/Origin). Without the token you expose an unauthenticated farm; withoutCOOP_PUBLIC=1every non-loopback request is rejected. See Configuration.
docker build -t coop .
docker run -d --name coopd \
-p 9700:9700 \
-v coop-data:/data \
-e COOP_PUBLIC=1 \
-e COOP_API_TOKEN="$(openssl rand -hex 32)" \
coopThe image bundles bubblewrap (per-hen bash sandbox) and tmux (PTY
sessions); data persists in the coop-data volume.
export COOP_API_TOKEN=$(openssl rand -hex 32)
docker compose up -d
docker compose logs -fTo auto-unlock a vault, mount it under /data and set COOP_VAULT /
COOP_PASSPHRASE. To use Azure Key Vault instead, pass the AZURE_* env vars
(see BYOK Secrets).
# 1. install binaries
curl -fsSL https://raw.githubusercontent.com/dcluomax/coop/main/scripts/install.sh | sudo COOP_INSTALL_DIR=/usr/local/bin sh
# 2. service user + unit + env
sudo useradd --system --create-home --home-dir /var/lib/coop coop
sudo install -Dm644 contrib/systemd/coopd.service /etc/systemd/system/coopd.service
sudo install -Dm640 contrib/coop.env.example /etc/coop/coop.env
sudo chown root:coop /etc/coop/coop.env
sudoedit /etc/coop/coop.env # set COOP_ADDR / token as needed
# 3. enable
sudo systemctl daemon-reload
sudo systemctl enable --now coopd
journalctl -u coopd -fThe unit runs as an unprivileged coop user with ProtectSystem=strict, keeps
state in /var/lib/coop, and restarts on failure.
Fronting coopd with nginx, Caddy, or a Cloudflare/cloudflared tunnel
(public hostname β container) has two requirements that are easy to miss:
-
The proxy must be able to reach the daemon. With Docker, put the proxy and
coopdon the same network β otherwise the proxy resolves the service name to nothing and returns502 Bad Gateway:docker network connect <proxy-net> coopd # or, in compose, list the shared network under the coopd service: # networks: [default, <proxy-net>]
-
Set
COOP_PUBLIC=1. The proxy forwards a publicHost/Origin(e.g.farm.example.com), which the loopback allowlist rejects with403until you opt in. KeepCOOP_API_TOKENset βCOOP_PUBLIC=1only relaxes theHost/Origincheck, it does not disable auth.
The public hostname also needs a DNS record pointing at the proxy/tunnel; a
missing record surfaces as NXDOMAIN / connection failures, not a coopd
error. Verify the chain end to end:
curl -s -o /dev/null -w '%{http_code}\n' https://farm.example.com/api/v1/healthz # 200 (exempt)
curl -s -o /dev/null -w '%{http_code}\n' https://farm.example.com/ # 401 (auth works)
curl -s -o /dev/null -w '%{http_code}\n' "https://farm.example.com/?token=$TOKEN" # 200 (UI loads)Once bound to 0.0.0.0 with COOP_PUBLIC=1 + a token, open the Farm UI, click
βοΈ, and the π Farm location panel lists every reachable URL. The same data
is at GET /api/v1/farm/location.
Coop is Apache-2.0 Β· pre-alpha (v0.1). Authoritative docs live in the repo.
Get started
Operate
Reference