Gateway: Dockerfile #9

Closed
opened 2026-08-09 20:31:47 +00:00 by hermes · 1 comment
Owner

Context

Gateway service (see #18). The deliverable of this project is a container
image the owner deploys on their infra.

Task

A Dockerfile at the repo root following coop/hermes-image/Dockerfile
conventions (pinned base, comment style explaining each step):

  • base python:3.13-slim with an exact tag (e.g. -bookworm pin; never
    latest — a Renovate bot bumps base-image pins in this org)
  • uv-managed install (uv sync --no-dev or uv pip install --system),
    no build toolchain in the runtime layer
  • run as a non-root user; EXPOSE 8000; HEALTHCHECK hitting /healthz
    (use python -c "import urllib.request..." if curl is not installed)
  • CMD ["uv", "run", "uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]

Acceptance criteria

  • docker build succeeds; docker run with the required env vars starts
    and /healthz returns 200; image runs as non-root.
## Context Gateway service (see #18). The deliverable of this project is a container image the owner deploys on their infra. ## Task A `Dockerfile` at the repo root following `coop/hermes-image/Dockerfile` conventions (pinned base, comment style explaining each step): - base `python:3.13-slim` with an exact tag (e.g. `-bookworm` pin; never `latest` — a Renovate bot bumps base-image pins in this org) - uv-managed install (`uv sync --no-dev` or `uv pip install --system`), no build toolchain in the runtime layer - run as a non-root user; `EXPOSE 8000`; `HEALTHCHECK` hitting `/healthz` (use `python -c "import urllib.request..."` if curl is not installed) - `CMD ["uv", "run", "uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]` ## Acceptance criteria - `docker build` succeeds; `docker run` with the required env vars starts and `/healthz` returns 200; image runs as non-root.
Author
Owner

Implemented in 078a5cb of coop/apple-music-gateway (Dockerfile + .dockerignore).

  • Base python:3.13-slim-bookworm (exact release pin, Renovate-bumpable; never latest)
  • uv copied as a static binary from the pinned ghcr.io/astral-sh/uv:0.11.6 image; uv sync --no-dev --frozen installs deps — all wheels, no compiler toolchain
  • Runs as unprivileged appuser (uid 10001); /app stays writable so the default ./gateway.db works (override GATEWAY_DB_PATH for a mounted volume)
  • EXPOSE 8000; HEALTHCHECK probes /healthz with urllib (slim has no curl)
  • CMD: uv run uvicorn --factory app:create_app ... — the issue text said app:app, but this codebase exposes an app factory (create_app in app/init.py); app:app would fail at import, and AGENTS.md already documents --factory app:create_app

Verification on this host (no Docker daemon/user namespaces available, so no local docker build): hadolint clean, uv lock --check clean, and the exact runtime shape was smoke-tested with production deps only (uv run --no-dev uvicorn --factory app:create_app) — /healthz returns 200 and the urllib probe used by HEALTHCHECK succeeds. A real docker build will be exercised by the #10 pipeline build once installed.

Implemented in 078a5cb of coop/apple-music-gateway (Dockerfile + .dockerignore). - Base `python:3.13-slim-bookworm` (exact release pin, Renovate-bumpable; never `latest`) - uv copied as a static binary from the pinned `ghcr.io/astral-sh/uv:0.11.6` image; `uv sync --no-dev --frozen` installs deps — all wheels, no compiler toolchain - Runs as unprivileged `appuser` (uid 10001); `/app` stays writable so the default `./gateway.db` works (override `GATEWAY_DB_PATH` for a mounted volume) - `EXPOSE 8000`; HEALTHCHECK probes `/healthz` with urllib (slim has no curl) - CMD: `uv run uvicorn --factory app:create_app ...` — the issue text said `app:app`, but this codebase exposes an app factory (`create_app` in app/__init__.py); `app:app` would fail at import, and AGENTS.md already documents `--factory app:create_app` Verification on this host (no Docker daemon/user namespaces available, so no local `docker build`): hadolint clean, `uv lock --check` clean, and the exact runtime shape was smoke-tested with production deps only (`uv run --no-dev uvicorn --factory app:create_app`) — `/healthz` returns 200 and the urllib probe used by HEALTHCHECK succeeds. A real `docker build` will be exercised by the #10 pipeline build once installed.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
coop/beets-appleplaylists#9
No description provided.