Headless Deployment
Quick deployment patterns for running tandem-engine as a background service.
Docker (Simple)
FROM debian:bookworm-slim
RUN useradd -r -s /usr/sbin/nologin tandemCOPY tandem-engine /usr/local/bin/tandem-engine
USER tandemWORKDIR /home/tandemVOLUME ["/data"]
ENV TANDEM_STATE_DIR=/dataEXPOSE 39731
ENTRYPOINT ["tandem-engine", "serve", "--hostname", "0.0.0.0", "--port", "39731", "--web-ui", "--web-ui-prefix", "/admin"]Run:
docker run -d --name tandem \ -p 127.0.0.1:39731:39731 \ -v tandem-data:/data \ -e TANDEM_API_TOKEN=tk_your_token \ -e TANDEM_WEB_UI=true \ tandem-engine:0.3.8Use a reverse proxy/TLS in front of this port for non-local use.
systemd (Linux)
/etc/systemd/system/tandem.service:
[Unit]Description=Tandem Engine (Headless)After=network-online.targetWants=network-online.target
[Service]Type=simpleUser=tandemGroup=tandemEnvironmentFile=/etc/tandem/envExecStart=/usr/local/bin/tandem-engine serve --hostname 127.0.0.1 --port 39731 --web-ui --web-ui-prefix /adminRestart=on-failureRestartSec=5NoNewPrivileges=truePrivateTmp=trueProtectSystem=strictReadWritePaths=/srv/tandem
[Install]WantedBy=multi-user.target/etc/tandem/env:
TANDEM_API_TOKEN=tk_your_tokenTANDEM_STATE_DIR=/srv/tandemTANDEM_WEB_UI=trueTANDEM_WEB_UI_PREFIX=/adminEnable/start:
sudo systemctl daemon-reloadsudo systemctl enable tandemsudo systemctl start tandemsudo systemctl status tandemVerify
curl -s http://127.0.0.1:39731/global/health \ -H "X-Tandem-Token: tk_your_token"Web admin:
http://127.0.0.1:39731/admin
Reverse Proxy (TLS)
Caddy (recommended quick setup)
/etc/caddy/Caddyfile:
tandem.example.com { reverse_proxy 127.0.0.1:39731}Then reload Caddy:
sudo systemctl reload caddyCaddy will provision TLS certificates automatically when DNS is configured.
Nginx (minimal example)
server { listen 443 ssl http2; server_name tandem.example.com;
ssl_certificate /etc/letsencrypt/live/tandem.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/tandem.example.com/privkey.pem;
location / { proxy_pass http://127.0.0.1:39731; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; }}Cloudflare Tunnel (no public port)
Run a tunnel to the local Tandem service:
cloudflared tunnel --url http://127.0.0.1:39731For a named tunnel (recommended for persistent setup), create a tunnel and map your hostname in Cloudflare DNS, then run it as a service:
cloudflared tunnel create tandemcloudflared tunnel route dns tandem tandem.example.comcloudflared tunnel run tandemNotes
- Keep token auth enabled (
TANDEM_API_TOKEN). - Terminate TLS at a reverse proxy if exposed beyond localhost.
- For channel features, set channel env vars or config values in state config.