feat(opencode): ship tooling image with git, node, and build deps
Extend the Alpine OpenCode base so agent sessions can clone, npm/pnpm install, and compile native modules; seed Forgejo HTTPS creds at start. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
74f1e9eb0b
commit
d90ff11f5b
4 changed files with 87 additions and 8 deletions
|
|
@ -214,7 +214,10 @@ services:
|
|||
|
||||
opencode:
|
||||
profiles: ["opencode"]
|
||||
image: ghcr.io/anomalyco/opencode:latest
|
||||
build:
|
||||
context: .
|
||||
dockerfile: docker/opencode/Dockerfile
|
||||
image: submatter-opencode:tooling
|
||||
container_name: submatter-opencode
|
||||
restart: unless-stopped
|
||||
working_dir: /workspace/repo
|
||||
|
|
@ -235,6 +238,10 @@ services:
|
|||
- OPENCODE_SERVER_PASSWORD=${OPENCODE_SERVER_PASSWORD}
|
||||
- OPENCODE_SERVER_USERNAME=${OPENCODE_SERVER_USERNAME:-opencode}
|
||||
- OMNIROUTE_API_KEY=${OMNIROUTE_API_KEY}
|
||||
- FORGEJO_TOKEN=${FORGEJO_TOKEN:-}
|
||||
- GITHUB_TOKEN=${GITHUB_TOKEN:-}
|
||||
- GIT_USER_NAME=${GIT_USER_NAME:-opencode}
|
||||
- GIT_USER_EMAIL=${GIT_USER_EMAIL:-opencode@stillwell.cloud}
|
||||
volumes:
|
||||
- echodo-workspace:/workspace
|
||||
- opencode-data:/data
|
||||
|
|
@ -255,7 +262,8 @@ services:
|
|||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 2G
|
||||
# Next.js builds need headroom beyond the bare serve binary.
|
||||
memory: 3G
|
||||
cpus: "2"
|
||||
networks:
|
||||
- echodo
|
||||
|
|
|
|||
31
docker/opencode/Dockerfile
Normal file
31
docker/opencode/Dockerfile
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
# OpenCode serve image + host tooling for interactive / worker agent sessions.
|
||||
# Official image is Alpine and ships only the `opencode` binary.
|
||||
FROM ghcr.io/anomalyco/opencode:latest
|
||||
|
||||
USER root
|
||||
|
||||
RUN apk add --no-cache \
|
||||
bash \
|
||||
ca-certificates \
|
||||
curl \
|
||||
git \
|
||||
github-cli \
|
||||
openssh-client \
|
||||
ripgrep \
|
||||
python3 \
|
||||
make \
|
||||
g++ \
|
||||
libc6-compat \
|
||||
nodejs \
|
||||
npm \
|
||||
&& curl -fsSL -o /usr/local/bin/pnpm \
|
||||
https://github.com/pnpm/pnpm/releases/download/v9.15.9/pnpm-linuxstatic-x64 \
|
||||
&& chmod +x /usr/local/bin/pnpm \
|
||||
&& npm install -g tsx \
|
||||
&& rm -rf /root/.npm/_cacache /tmp/*
|
||||
|
||||
ENV GIT_CONFIG_COUNT=1 \
|
||||
GIT_CONFIG_KEY_0=safe.directory \
|
||||
GIT_CONFIG_VALUE_0=*
|
||||
|
||||
WORKDIR /workspace
|
||||
|
|
@ -7,17 +7,37 @@ Runs `opencode serve` on `:4096` (HTTP API for the worker). Attach a TUI with
|
|||
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/<repo>` 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 # after worker image rebuild with opencode session
|
||||
WORKER_SESSION_TYPE=opencode
|
||||
OPENCODE_SERVER_PASSWORD=<openssl rand -hex 24>
|
||||
OPENCODE_SERVER_URL=http://opencode:4096
|
||||
OMNIROUTE_BASE_URL=https://omniroute.stillwell.cloud/v1
|
||||
OMNIROUTE_API_KEY=<gateway inference key>
|
||||
FORGEJO_TOKEN=<forgejo pat with repo scope>
|
||||
```
|
||||
|
||||
Then:
|
||||
|
|
@ -29,9 +49,6 @@ bash scripts/deploy-prod.sh up
|
|||
# bash scripts/deploy-prod.sh build
|
||||
```
|
||||
|
||||
Keep `WORKER_SESSION_TYPE=minimal` until the rebuilt worker image includes the
|
||||
`opencode` session type (and the `yaml` dependency fix).
|
||||
|
||||
## URLs
|
||||
|
||||
| Surface | URL |
|
||||
|
|
@ -45,7 +62,8 @@ Keep `WORKER_SESSION_TYPE=minimal` until the rebuilt worker image includes the
|
|||
- 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 2 GB. Keep one concurrent agent until host RAM → 64 GB.
|
||||
Container capped at 3 GB (Next.js builds). Keep one concurrent agent until host RAM → 64 GB.
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ set -eu
|
|||
|
||||
CONFIG_HOME="${XDG_CONFIG_HOME:-${HOME:-/data}/.config}"
|
||||
DATA_HOME="${XDG_DATA_HOME:-${HOME:-/data}/.local/share}"
|
||||
mkdir -p "$CONFIG_HOME/opencode" "$DATA_HOME/opencode" /data/bin
|
||||
mkdir -p "$CONFIG_HOME/opencode" "$DATA_HOME/opencode" /data/bin "$HOME"
|
||||
|
||||
# Container has no desktop — stub xdg-open so `opencode web` does not exit.
|
||||
if [ ! -x /data/bin/xdg-open ]; then
|
||||
|
|
@ -24,4 +24,26 @@ if [ -n "${OMNIROUTE_API_KEY:-}" ]; then
|
|||
chmod 600 "$DATA_HOME/opencode/auth.json" || true
|
||||
fi
|
||||
|
||||
# Git identity + Forgejo HTTPS auth for clone/push from agent sessions.
|
||||
if command -v git >/dev/null 2>&1; then
|
||||
git config --global --add safe.directory '*'
|
||||
if [ -n "${GIT_AUTHOR_NAME:-}" ]; then
|
||||
git config --global user.name "$GIT_AUTHOR_NAME"
|
||||
else
|
||||
git config --global user.name "${GIT_USER_NAME:-opencode}"
|
||||
fi
|
||||
if [ -n "${GIT_AUTHOR_EMAIL:-}" ]; then
|
||||
git config --global user.email "$GIT_AUTHOR_EMAIL"
|
||||
else
|
||||
git config --global user.email "${GIT_USER_EMAIL:-opencode@stillwell.cloud}"
|
||||
fi
|
||||
if [ -n "${FORGEJO_TOKEN:-}" ]; then
|
||||
git config --global credential.helper store
|
||||
# oauth2:<token> is Forgejo's HTTPS token username convention.
|
||||
printf 'https://oauth2:%s@forgejo.stillwell.cloud\n' "$FORGEJO_TOKEN" \
|
||||
> "$HOME/.git-credentials"
|
||||
chmod 600 "$HOME/.git-credentials"
|
||||
fi
|
||||
fi
|
||||
|
||||
exec "$@"
|
||||
|
|
|
|||
Loading…
Reference in a new issue