Skip to content

fix(server): align CPU image port + /data ownership with CUDA image (v0.5.1)#31

Merged
dvcdsys merged 1 commit intomainfrom
fix/v0.5.1-cpu-image-defaults
May 4, 2026
Merged

fix(server): align CPU image port + /data ownership with CUDA image (v0.5.1)#31
dvcdsys merged 1 commit intomainfrom
fix/v0.5.1-cpu-image-defaults

Conversation

@dvcdsys
Copy link
Copy Markdown
Owner

@dvcdsys dvcdsys commented May 4, 2026

Summary

Two latent bugs in the v0.5.0 CPU image (`dvcdsys/code-index:v0.5.0` / `:latest`) surfaced during post-release smoke testing on macOS arm64. CUDA image is unaffected — both fixes bring the CPU image to parity.

🐛 #1 — Port mismatch

CPU image baked `ENV CIX_PORT=8001` (Python-FastAPI parallel-rollout carry-over), but `docker-compose.yml` maps `21847:21847`. A fresh `docker compose up -d` from the published files left the host port pointing at a non-listening container port → `curl: Recv failure: Connection reset by peer`.

The Python backend was archived 2026-04, so the rationale for 8001 is dead. CUDA image already uses 21847.

🐛 #2 — /data ownership for named volumes

CPU image runs as `nonroot:nonroot` (uid 65532) but the Dockerfile declared `VOLUME ["/data"]` without pre-creating the directory with proper ownership. A fresh Docker named volume inherited root ownership from the daemon → runtime user hit `mkdir /data/sqlite: permission denied` on first boot.

CUDA image pre-creates `/data` via `COPY --chown=1001:1001` from a builder stage. CPU now does the same with `--chown=65532:65532`.

Changes

File What
`server/Dockerfile` `ENV CIX_PORT=21847`, `EXPOSE 21847`; `mkdir /out/data` in builder; `COPY --chown=65532:65532 /out/data /data` before `VOLUME`
`server/internal/config/config.go` `getenvInt` default `8001 → 21847`; doc comment rewritten
`server/internal/config/config_test.go` `TestLoadDefaults` expects `21847`
`server/README.md` Removed stale "Phase 1 / Python parallel" preamble; port table updated; quick-start `docker run` example modernized
`docker-compose.yml` + `.cuda.yml` Explicit `CIX_PORT=${CIX_PORT:-21847}` (defense in depth)
`docker-compose.yml` Bind-mount uid comment updated `1001 → 65532` (CPU image's nonroot uid)

Test plan

  • `go build ./...` green
  • `go test ./...` green (one fixture updated for the new port default)
  • Local `docker buildx build` produces an arm64 image
  • `docker run` with a named volume (no `--user` override) and default port (no `CIX_PORT` env) boots cleanly:
    • `/health` → 200
    • `/api/v1/auth/bootstrap-status` → 200
    • `/dashboard/` → 200
    • `/api/v1/admin/users` → 200 (admin session)
  • Reviewer: tag `server/v0.5.1` after merge → CI builds + publishes `:0.5.1`, `:latest`, `:0.5.1-cu128`, `:cu128`

Release notes (for v0.5.1 GitHub Release body)

```markdown

Server v0.5.1 — CPU image fixes

  • Fix: CPU image now defaults to port `21847` (matches docker-compose
    port mapping). Previously the image listened on 8001 — a Python-FastAPI
    parallel-rollout default that's no longer relevant.
  • Fix: CPU image pre-creates `/data` with nonroot (uid 65532) ownership
    so a fresh Docker named volume is writable on first boot. Previously
    hit `mkdir /data/sqlite: permission denied` on first `docker compose
    up -d`.

No breaking changes. CUDA image was already correct on both points.
```

🤖 Generated with Claude Code

Two latent bugs in the v0.5.0 CPU image surfaced during post-release
smoke testing of dvcdsys/code-index:v0.5.0 on macOS arm64:

1) Port mismatch — image baked ENV CIX_PORT=8001 (Python parallel-PoC
   carry-over) but docker-compose.yml mapped 21847:21847. A fresh
   `docker compose up -d` from the published files left the host port
   pointing at a non-listening container port; `curl` saw connection
   reset. The Python backend was archived 2026-04, so the rationale
   for 8001 is dead. CUDA image already uses 21847; CPU now matches.

2) /data ownership — distroless USER nonroot:nonroot (uid 65532) but
   the Dockerfile declared `VOLUME ["/data"]` without pre-creating the
   directory with nonroot ownership. A fresh Docker named volume
   inherited root ownership from the daemon and the runtime user got
   `mkdir /data/sqlite: permission denied` on first boot. CUDA image
   pre-creates /data via COPY --chown=1001:1001; CPU now does the
   same with --chown=65532:65532.

Changes:
- server/Dockerfile: ENV CIX_PORT=21847, EXPOSE 21847; mkdir /out/data
  in builder stage; COPY --chown=65532:65532 /out/data /data before
  VOLUME declaration.
- server/internal/config/config.go: getenvInt default 8001 → 21847.
  Doc comment rewritten — "Python parallel rollout" rationale is dead.
- server/internal/config/config_test.go: TestLoadDefaults expects 21847.
- server/README.md: stale "phase 1 / Python parallel" preamble replaced;
  port table cell updated; quick-start docker run example uses 21847
  and shows the now-required bootstrap admin envs.
- docker-compose.yml + docker-compose.cuda.yml: explicit
  CIX_PORT=${CIX_PORT:-21847} as defense in depth against future
  Dockerfile regressions or third-party forks.
- docker-compose.yml: bind-mount uid comment updated 1001 → 65532
  (the CPU image's nonroot uid; CUDA's 1001 only applies to the
  CUDA compose file).

Local verification:
- `make` build green; full Go test suite green (one fixture updated).
- `docker buildx build` of the patched CPU Dockerfile produces an arm64
  image. `docker run` with a NAMED VOLUME (no --user override) and the
  DEFAULT port (no CIX_PORT env) now boots cleanly:
    /health → 200
    /api/v1/auth/bootstrap-status → 200
    /dashboard/ → 200
    /api/v1/admin/users → 200 (admin session)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@dvcdsys dvcdsys merged commit 74a98d0 into main May 4, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant