FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim

WORKDIR /app

# The uv base image bundles uv, so no `pip install uv` needed. Copy the
# manifest + lockfile first as their own layer so editing source files
# doesn't bust the dep cache. ``uv sync --frozen`` refuses to mutate
# uv.lock at build time — if pyproject.toml drifts from uv.lock, the
# build fails loudly instead of silently floating versions, which is
# the whole #158 fix. ``uv.lock*`` keeps the COPY glob permissive so
# the build error fires from `uv sync` (clearer message) rather than
# from COPY.
COPY pyproject.toml uv.lock* ./
RUN uv sync --frozen --no-cache

COPY . .

ENV PORT=8000
EXPOSE 8000

# Kernel runtime — parbaked finds your routes/ files and wires the
# auth/admin/health routers itself. No main.py needed. ``uv sync``
# installs into ``.venv`` (no --system flag exists on sync), so invoke
# uvicorn from that venv rather than expecting a system install.
#
# ``--no-proxy-headers`` (#722): parbaked owns the X-Forwarded-For
# trust decision via ``ParbakedConfig.trust_proxy_headers`` — letting
# uvicorn pre-mutate ``request.client.host`` opens a rate-limit-bucket
# bypass on any deploy whose immediate peer is loopback (``nginx →
# 127.0.0.1:8000``). ``parbaked deploy`` sets PARBAKED_TRUST_PROXY_HEADERS
# in fly.toml; parbaked reads XFF itself when that's true.
CMD [".venv/bin/uvicorn", "parbaked.runtime:create_app", "--factory", "--no-proxy-headers", "--host", "0.0.0.0", "--port", "8000"]
