Repository navigation
feat: publish openab-sb container image to GHCR on v* tags - #22
Conversation
Add a Dockerfile that packages the release's static openab-sb binary on debian:bookworm-slim with curl and ca-certificates, running as a non-root user, and an `image` job in release.yml that builds linux/amd64+arm64 and pushes ghcr.io/openabdev/openab-sb on v* tags. The job reuses the binaries from the `build` job and has packages:write only. Verification (see .agents/tasks/k8s-openab-sb/verification.md, outside repo): - ruby -ryaml load of .github/workflows/release.yml: exit 0, jobs build/publish/image - staging tar extraction on a fake tarball: exit 0, binary is 0755 - hadolint: not installed, not run - docker build: docker daemon down, not built - no cargo/rustc run locally
Address review CHANGES_REQUESTED (findings 1 and 2). - README: the healthz probe now reads `curl -fsS --max-time 2 ...`, matching the settled probe string. - Dockerfile: use a numeric user, UID/GID 10001, so kubelet runAsNonRoot can verify it. Suppress DL3008 inline (pinning bookworm apt versions breaks on security updates). - README: state the UID/GID in the container image section. Verification (macmini, the only host with docker; this machine has none): - Input: published v0.2.2 linux-amd64/arm64 tarballs, `shasum -a 256 -c` against SHA256SUMS: OK, exit 0. - hadolint before fix: DL3008 warning, DL3066 info, exit 1. After fix: no findings, exit 0. - `docker buildx build --platform linux/amd64,linux/arm64 -f Dockerfile .`: exit 0. One harmless useradd warning (UID > SYS_UID_MAX). - Smoke test of arm64 image: uid=10001, `openab-sb --version` = 0.2.2, `check -c` on the example config with generated verifiers: exit 0. - ruby -ryaml load of .github/workflows/release.yml: exit 0, jobs build/publish/image unchanged. - Not run: GHCR push (tag-only job), amd64 image run, p1. Record: .agents/tasks/k8s-openab-sb/verification.md (outside repo).
|
Important CHANGES REQUESTED What This PR Doesopenab-sb has no container image today, so OpenAB Connect cannot deploy it to Kubernetes. This PR adds a runtime-only Dockerfile and a release job that packages the existing static musl binaries into a multi-arch (amd64, arm64) image on GHCR for every How It Works
Findings
Finding Details🟡 F1: Port 8796 vs. 8790
Requested change: pick one port. Prefer 8790 everywhere, or, if 8796 is required by the Connect deployment design, say so explicitly in the README and explain why it differs from the default. 🟡 F2: Image is not gated on the release
Requested change: use 🟡 F3: arm64 binary is never executedThe staging step runs Requested change: after 🟡 F4: GHCR package visibilityGitHub docs: a package linked to a repository inherits the repository's access permissions "but not the visibility", and new packages start private. Requested change: document the one-time manual step (Package settings -> Change visibility -> Public) in the README or release notes, and optionally add an unauthenticated pull check after the first release. 🟡 F5: Build context hygieneThe repository has no Requested change: add a 🟡 F6:
|
- F1: use port 8790 everywhere (Dockerfile comment, README), matching DEFAULT_LISTEN in src/config.rs. The probe stays curl -fsS --max-time 2 http://127.0.0.1:8790/healthz. - F2: image job now needs [build, publish], so an image is pushed only after the GitHub Release succeeds. - F3: run the arm64 binary under QEMU (docker run --platform linux/arm64) before the push. The amd64 --version check is kept. - F4: release notes and README say a new GHCR package is private by default and must be set to Public once before anonymous pull works. - F5: add .dockerignore (exclude *, re-include image-bin/** and Dockerfile). - F6: README documents that stable tags also move :latest. The metadata-action flavor is unchanged (default latest=auto). Checks run: - ruby -ryaml: YAML.load_file(".github/workflows/release.yml") exits 0. - grep 8796 in README.md, Dockerfile, openab-sb.toml.example, release.yml: no matches. - hadolint not installed locally; not run. - macmini (OrbStack docker, arm64 host): docker build of the Dockerfile with a staged fake image-bin/amd64 binary and this .dockerignore succeeded; the COPY resolved. The arm64 step command (docker run --rm --platform linux/arm64 -v ...:/tmp/openab-sb:ro debian:bookworm-slim /tmp/openab-sb --version) ran and printed output with exit 0. This used a fake binary, not the release artifact.
Review round 2 at 2743c61Two independent reviewers, run in parallel on the same head: Opus (claude-opus-5.5) and Sol (gpt-5.6-sol). Both: LGTM, 0 High, 0 Medium. Opus listed 4 Low, Sol listed 2 Low.
Extra evidence outside CI: the image was built from this Dockerfile with the real v0.2.2 binaries, started with the config shape OpenAB Connect renders (uid 10001, read-only root, Remaining Low items (not blocking, can follow): README pull example names a tag that will not exist until the first Merging on the two LGTMs. The image job runs on the next |
Adds a container image for openab-sb so OpenAB Connect can deploy it to Kubernetes (design: oablab/oab-pty-mac#117).
Changes
Verification
Not done