TermCanvas Headless Cloud Deployment
April 17, 2026 ยท View on GitHub
This guide covers the docker-compose deployment path for the TermCanvas headless runtime introduced across the cloud rollout rounds.
What This Stack Provides
- A remotely reachable TermCanvas headless API on
TERMCANVAS_PORT - Authenticated project, terminal, workflow, worktree, telemetry, and diff control
- Persistent TermCanvas state under the container user home
- A bind-mounted workspace root at
/workspacefor repos and Hydra worktrees - Optional lifecycle webhooks and optional heartbeat callbacks
Prerequisites
- Docker Engine with Compose support
- A host directory that will hold your repos/worktrees
- The
termcanvasCLI available wherever you plan to issue remote commands - API keys for whichever agent CLIs you want to run inside the container
Run the compose stack from server/ so .env and relative bind mounts resolve predictably.
1. Configure Environment
cd server
cp .env.example .env
openssl rand -hex 32
Put the generated token into TERMCANVAS_API_TOKEN.
Important variables:
TERMCANVAS_API_TOKENRequired. All control routes except/health,/health/live, and/health/readyrequireAuthorization: Bearer <token>.HOST_WORKSPACE_DIRHost path that docker-compose bind-mounts into the container.WORKSPACE_DIR=/workspaceIn-container workspace root. Remote CLI commands must use paths under this root, for example/workspace/my-repo.TERMCANVAS_WEBHOOK_URLOptional lifecycle webhook target forserver_*,terminal_*, andworkflow_*events.TERMCANVAS_WEBHOOK_SECRETOptional shared secret for webhook signing viaX-Webhook-Signature.RESULT_CALLBACK_URLOptional heartbeat target. The headless runtime POSTs a JSON heartbeat roughly every 10 seconds while the server is running.TERMCANVAS_AGENT_CLI_PACKAGEBuild-time package name installed into the image. The compose default is@openai/codex.
Provider credentials such as OPENAI_API_KEY are passed through to spawned agent terminals.
2. Start The Stack
docker compose up --build -d
The compose file mounts:
termcanvas-data:/home/termcanvas/.termcanvasPersistent TermCanvas state, including the runtime port file and saved canvas/project state.${HOST_WORKSPACE_DIR}:${WORKSPACE_DIR}Your repo/worktree root. Hydra-created worktrees appear under this mount.
The image runs as the unprivileged termcanvas user, uses tini as PID 1 for signal forwarding, and expects Docker to stop it with a grace window so pending state can flush before exit.
3. Verify Health
Public health endpoints:
curl http://localhost:7080/health
curl http://localhost:7080/health/live
curl http://localhost:7080/health/ready
Authenticated status example:
curl \
-H "Authorization: Bearer ${TERMCANVAS_API_TOKEN}" \
http://localhost:7080/api/status
4. Connect With The Remote CLI
The termcanvas CLI is only an HTTP client in this mode. Paths passed to it are evaluated by the server, not by the machine where you run the command.
Set connection variables:
export TERMCANVAS_URL=http://your-server-host:7080
export TERMCANVAS_API_TOKEN=your-shared-token
Example flow:
termcanvas project add /workspace/my-repo
# Create a Lead-driven workflow, then dispatch a node into it.
# The `termcanvas workflow` HTTP CLI keeps the legacy `--node`
# naming even though the underlying `hydra` binary now speaks
# `--dispatch`; the ids refer to the same thing.
termcanvas workflow init \
--intent "Audit and fix the failing API path" \
--repo /workspace/my-repo
termcanvas workflow dispatch <workflow-id> \
--node dev \
--role dev \
--intent "Audit and fix the failing API path" \
--repo /workspace/my-repo
termcanvas workflow list --repo /workspace/my-repo
termcanvas workflow status <workflow-id> --repo /workspace/my-repo
termcanvas workflow watch <workflow-id> --repo /workspace/my-repo
termcanvas worktree create --repo /workspace/my-repo --branch feature/cloud-fix
termcanvas worktree list --repo /workspace/my-repo
If you run the CLI from outside the container host, keep using server-visible paths like /workspace/my-repo. Do not pass your local laptop path.
5. Webhooks And Result Callbacks
TERMCANVAS_WEBHOOK_URLReceives lifecycle notifications for server, terminal, and workflow events. WhenTERMCANVAS_WEBHOOK_SECRETis set, payloads are signed inX-Webhook-Signature.RESULT_CALLBACK_URLReceives heartbeat payloads that include workflow summary, terminal/workflow counts, memory usage, and uptime.
Use both when you need push-based monitoring:
- Webhooks for discrete lifecycle events
- Result callback for periodic liveness/progress heartbeat
6. Agent CLI Packages
The base image installs Codex during the Docker build. If you want a different default package, rebuild with a different package name:
docker compose build \
--build-arg TERMCANVAS_AGENT_CLI_PACKAGE=@openai/codex
If you need additional providers, extend the base image in your own Dockerfile and install the extra CLIs there.
7. Operational Notes
/health*stays public by design so orchestrators can probe the service./api/statusand all workflow/worktree control routes stay behindTERMCANVAS_API_TOKEN.- Docker state lives in
/home/termcanvas/.termcanvas; workspace repos/worktrees live under/workspace. - Stopping the container with
docker stopshould flush pending state, tear down PTYs, emitserver_stopping, and remove the runtime port file before exit.