1.9 KiB
1.9 KiB
GrowQR OpenCode Runtime Image
This folder defines the custom per-user OpenCode image used by the Rivet user actor lifecycle.
Why this exists
The upstream image (ghcr.io/anomalyco/opencode:latest) is only the base runtime. GrowQR needs an owned image that bakes in:
- GrowQR sub-agent markdown modules from
agents/ - GrowQR system prompts from
prompts/ - global OpenCode config under
/root/.config/opencode - a Git-backed workspace template under
/opt/growqr/workspace-template - runtime metadata for image/prompt/migration rollout checks
Local build
From growqr-backend/:
docker build -f docker/opencode/Dockerfile -t growqr/opencode:dev .
Then run the backend with:
OPENCODE_IMAGE=growqr/opencode:dev OPENCODE_IMAGE_VERSION=dev PROMPT_VERSION=dev docker compose up -d --build backend
For the current compose setup, the backend talks to the host Docker socket, so local images built on the host are available to per-user containers.
Release build
VERSION=2026.06.01-1
docker build -f docker/opencode/Dockerfile \
--build-arg GROWQR_IMAGE_VERSION=$VERSION \
--build-arg GROWQR_PROMPT_VERSION=$VERSION \
-t ghcr.io/<org>/growqr-opencode:$VERSION \
-t ghcr.io/<org>/growqr-opencode:latest .
docker push ghcr.io/<org>/growqr-opencode:$VERSION
docker push ghcr.io/<org>/growqr-opencode:latest
Then update backend env:
OPENCODE_IMAGE=ghcr.io/<org>/growqr-opencode:$VERSION
OPENCODE_IMAGE_VERSION=$VERSION
PROMPT_VERSION=$VERSION
Runtime behavior
The backend/Rivet actor still owns lifecycle:
- provision central Gitea repo for the user
- start one OpenCode container from this image
- mount host workspace at
/workspace - wait for OpenCode readiness
- clone/pull the user's Gitea repo into
/workspace - sync important runtime outputs back to Git
The image only provides the runtime and templates; user data remains in the user's central Gitea repo.