Trying to build worker images
Build and Push Spoon Images / quality (push) Successful in 1m52s
Build and Push Spoon Images / build-images (push) Successful in 8m19s

This commit is contained in:
Gabriel Brown
2026-06-22 20:29:10 -04:00
parent 7e7bec56d5
commit f33f76d874
6 changed files with 80 additions and 6 deletions
+16 -4
View File
@@ -1,4 +1,4 @@
name: Build and Push Next App name: Build and Push Spoon Images
on: on:
push: push:
@@ -33,7 +33,7 @@ jobs:
printf '%s\n' "$DOTENV_PROD" > "$env_file" printf '%s\n' "$DOTENV_PROD" > "$env_file"
bunx dotenv -e "$env_file" -- env NODE_ENV=test SKIP_E2E=1 bun run ci:check bunx dotenv -e "$env_file" -- env NODE_ENV=test SKIP_E2E=1 bun run ci:check
build-next: build-images:
needs: [quality] needs: [quality]
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
@@ -44,7 +44,7 @@ jobs:
with: with:
bun-version: 1.3.10 bun-version: 1.3.10
- run: bun install --frozen-lockfile - run: bun install --frozen-lockfile
- name: Build image - name: Build Next image
env: env:
DOTENV_PROD: ${{ secrets.DOTENV_PROD }} DOTENV_PROD: ${{ secrets.DOTENV_PROD }}
run: | run: |
@@ -52,9 +52,21 @@ jobs:
trap 'rm -f "$env_file"' EXIT trap 'rm -f "$env_file"' EXIT
printf '%s\n' "$DOTENV_PROD" > "$env_file" printf '%s\n' "$DOTENV_PROD" > "$env_file"
CI_ENV_FILE="$env_file" ./scripts/build-next-app production CI_ENV_FILE="$env_file" ./scripts/build-next-app production
- name: Tag and push image - name: Build agent images
run: ./scripts/build-agent-images
- name: Tag and push images
run: | run: |
docker tag spoon-next:latest git.gbrown.org/gib/spoon-next:${{ gitea.sha }} docker tag spoon-next:latest git.gbrown.org/gib/spoon-next:${{ gitea.sha }}
docker tag spoon-next:latest git.gbrown.org/gib/spoon-next:latest docker tag spoon-next:latest git.gbrown.org/gib/spoon-next:latest
docker push git.gbrown.org/gib/spoon-next:${{ gitea.sha }} docker push git.gbrown.org/gib/spoon-next:${{ gitea.sha }}
docker push git.gbrown.org/gib/spoon-next:latest docker push git.gbrown.org/gib/spoon-next:latest
docker tag spoon-agent-worker:latest git.gbrown.org/gib/spoon-agent-worker:${{ gitea.sha }}
docker tag spoon-agent-worker:latest git.gbrown.org/gib/spoon-agent-worker:latest
docker push git.gbrown.org/gib/spoon-agent-worker:${{ gitea.sha }}
docker push git.gbrown.org/gib/spoon-agent-worker:latest
docker tag spoon-agent-job:latest git.gbrown.org/gib/spoon-agent-job:${{ gitea.sha }}
docker tag spoon-agent-job:latest git.gbrown.org/gib/spoon-agent-job:latest
docker push git.gbrown.org/gib/spoon-agent-job:${{ gitea.sha }}
docker push git.gbrown.org/gib/spoon-agent-job:latest
+5
View File
@@ -16,6 +16,11 @@
Postgres on port 5432 for Convex storage, and the Convex dashboard on port 6791. Postgres on port 5432 for Convex storage, and the Convex dashboard on port 6791.
Agent jobs are opt-in; build `docker/agent-job.Dockerfile` as Agent jobs are opt-in; build `docker/agent-job.Dockerfile` as
`spoon-agent-job:latest` before running Docker-backed jobs. `spoon-agent-job:latest` before running Docker-backed jobs.
- Gitea CI builds and pushes `spoon-next`, `spoon-agent-worker`, and
`spoon-agent-job` images to `git.gbrown.org/gib`. In production,
`SPOON_AGENT_JOB_IMAGE` should point to
`git.gbrown.org/gib/spoon-agent-job:latest`, and the worker service requires
access to the host Docker socket.
## Protected and generated files ## Protected and generated files
+50
View File
@@ -156,6 +156,56 @@ or job container.
</details> </details>
<details>
<summary><strong>Production agent runtime images</strong></summary>
Gitea CI builds and pushes three production images:
```txt
git.gbrown.org/gib/spoon-next:latest
git.gbrown.org/gib/spoon-agent-worker:latest
git.gbrown.org/gib/spoon-agent-job:latest
```
The worker image is the long-running service that polls Convex. The job image is
the isolated workbench that the worker launches for each agent job. For the MVP,
production should use the repo-provided JS/TS workbench image:
```env
SPOON_AGENT_JOB_IMAGE="git.gbrown.org/gib/spoon-agent-job:latest"
```
The job image includes Node 22, Bun, package managers through Corepack, git,
ripgrep, Python, build tools, and the OpenCode CLI. It is not the forked
project's production runtime; it is the agent execution environment.
Production worker runtime requirements:
- `spoon-agent-worker` must run as a separate service.
- The worker needs `/var/run/docker.sock` mounted so it can launch job
containers.
- The production Docker host must be logged into `git.gbrown.org` so worker jobs
can pull the private `spoon-agent-job` image.
- `SPOON_WORKER_TOKEN` must match the value stored in Convex production env.
- `spoon-next` needs `SPOON_AGENT_WORKER_URL=http://spoon-agent-worker:3921` and
`SPOON_AGENT_WORKER_INTERNAL_TOKEN` so Next API routes can proxy workspace
file, diff, message, command, and draft PR actions.
- `spoon-agent-worker` also needs `GITHUB_APP_ID` and `GITHUB_APP_PRIVATE_KEY`.
Useful production checks:
```sh
docker logs --tail=200 spoon-agent-worker
curl -H "Authorization: Bearer $SPOON_AGENT_WORKER_INTERNAL_TOKEN" \
http://spoon-agent-worker:3921/health
```
For the first production run, use an API-key based AI provider profile. Stored
OpenCode/Codex `auth.json` profiles are supported in settings, but worker-side
auth-file injection is still a follow-up before they can execute jobs.
</details>
## Architecture ## Architecture
<details open> <details open>
+1 -1
View File
@@ -1,4 +1,4 @@
FROM node:22-bookworm FROM docker.io/library/node:22-bookworm
ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0 ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0
+1 -1
View File
@@ -1,4 +1,4 @@
FROM oven/bun:1.3.10 FROM docker.io/oven/bun:1.3.10
RUN apt-get update \ RUN apt-get update \
&& apt-get install -y --no-install-recommends \ && apt-get install -y --no-install-recommends \
+7
View File
@@ -0,0 +1,7 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
docker build -f "$ROOT_DIR/docker/agent-worker.Dockerfile" -t spoon-agent-worker:latest "$ROOT_DIR"
docker build -f "$ROOT_DIR/docker/agent-job.Dockerfile" -t spoon-agent-job:latest "$ROOT_DIR"