# OpenCode on CT 116 (Submatter) Headless coding harness for Submatter. Prefer this over OpenHands. Runs `opencode serve` on `:4096` (HTTP API for the worker). Attach a TUI with `opencode attach http://…:4096`, or use the browser via Traefik once Authentik is happy. The image has no desktop browser — do not use `opencode web` in compose without an `xdg-open` stub (entrypoint provides one if you switch back). ## Tooling image `docker/opencode/Dockerfile` extends `ghcr.io/anomalyco/opencode:latest` with: - `git`, `openssh-client`, `gh` - Node.js + `npm` + `pnpm` + `tsx` - `bash`, `curl`, `ripgrep`, `python3`, `make`, `g++` (native module builds) Forgejo HTTPS auth is seeded from `FORGEJO_TOKEN` into `~/.git-credentials` at container start. Projects live under `/workspace/` on the shared volume. ```bash export COMPOSE_PROFILES=opencode docker compose --project-directory /opt/submatter \ -f docker/docker-compose.prod.yml --env-file .env \ build opencode bash scripts/deploy-prod.sh up ``` ## Enable On CT 116 `/opt/submatter/.env`: ```bash COMPOSE_PROFILES=opencode WORKER_SESSION_TYPE=opencode OPENCODE_SERVER_PASSWORD= OPENCODE_SERVER_URL=http://opencode:4096 OMNIROUTE_BASE_URL=https://omniroute.stillwell.cloud/v1 OMNIROUTE_API_KEY= FORGEJO_TOKEN= ``` Then: ```bash export COMPOSE_PROFILES=opencode bash scripts/deploy-prod.sh up # First time / after worker harness code lands: # bash scripts/deploy-prod.sh build ``` ## URLs | Surface | URL | |---------|-----| | Traefik | `https://opencode.stillwell.cloud` (Authentik + basic auth) | | Worker API | `http://opencode:4096` on the `echodo` Docker network | | LAN health | `curl -u opencode:$OPENCODE_SERVER_PASSWORD http://192.168.68.116:4096/global/health` | ## Auth - Browser: Authentik via Traefik (`authentik-auth`) **and** OpenCode basic auth. - Worker: same basic auth via `OPENCODE_SERVER_PASSWORD`. - Models: `@omniroute/opencode-plugin` + `OMNIROUTE_API_KEY` (seeded into `auth.json` by `entrypoint.sh`). - Git: `FORGEJO_TOKEN` → HTTPS credential helper for `forgejo.stillwell.cloud`. ## RAM Container capped at 3 GB (Next.js builds). Keep one concurrent agent until host RAM → 64 GB.