# syntax=docker/dockerfile:1
#
# Single-container image for Velodrome (docs/DECISIONS.md D15/D16): Caddy serves the SvelteKit
# static SPA and reverse-proxies /api/* to the FastAPI app, both running in the same container
# behind whatever TLS-terminating reverse proxy already exists on the host. Build context is the
# repo root, since this needs both apps/api and apps/web:
#
#   docker build -t velodrome .
#
# Replaces apps/api/Dockerfile and apps/web/Dockerfile from the old 4-container compose plan
# (PR #4, closed as superseded) — those built two images meant to run as separate services;
# this builds one.

# ---- web: produces /app/build, nothing from this stage ends up running ----
FROM node:22-slim AS web-builder
WORKDIR /app
COPY apps/web/package.json apps/web/pnpm-lock.yaml ./
RUN corepack enable && corepack prepare pnpm@9 --activate \
	&& pnpm install --frozen-lockfile
COPY apps/web .
RUN pnpm run build

# ---- api: produces the venv at /app/.venv ----
FROM python:3.12-slim AS api-builder
RUN pip install --no-cache-dir uv
WORKDIR /app
COPY apps/api/pyproject.toml apps/api/uv.lock ./
# Dependencies first, isolated from source changes, so touching velodrome/ doesn't invalidate
# this layer.
RUN uv sync --frozen --no-install-project --no-dev
COPY apps/api/velodrome ./velodrome
COPY apps/api/alembic ./alembic
COPY apps/api/alembic.ini ./
RUN uv sync --frozen --no-dev

# ---- runtime ----
FROM python:3.12-slim AS runtime

# Caddy's official images ship a single statically-linked Go binary (no CGO) — copying it out of
# the upstream image is the standard way to get Caddy into a non-Caddy base image without a
# second package manager or a source build.
COPY --from=caddy:2 /usr/bin/caddy /usr/bin/caddy

# tini is PID 1: reaps zombies and forwards signals correctly to entrypoint.sh's two background
# processes, which a bare `CMD` running a shell script as PID 1 would not do on its own.
RUN apt-get update && apt-get install -y --no-install-recommends tini \
	&& rm -rf /var/lib/apt/lists/*

RUN groupadd --system velodrome && useradd --system --gid velodrome --create-home velodrome

WORKDIR /app
COPY --from=api-builder --chown=velodrome:velodrome /app /app
COPY --from=web-builder --chown=velodrome:velodrome /app/build /srv/web
COPY --chown=velodrome:velodrome deploy/Caddyfile /etc/caddy/Caddyfile
COPY --chown=velodrome:velodrome deploy/entrypoint.sh /app/entrypoint.sh
RUN chmod +x /app/entrypoint.sh

ENV PATH="/app/.venv/bin:$PATH"
# Absolute path into the mounted volume below. See deploy/README.md for the full env var table —
# this is the one variable NOT meant to be overridden per-deployment, since /data is the contract
# with the volume mount, not a per-instance setting.
ENV VELODROME_DATABASE_URL="sqlite+aiosqlite:////data/velodrome.db"

RUN mkdir -p /data && chown velodrome:velodrome /data

USER velodrome
VOLUME ["/data"]
# Non-privileged port: Caddy needs no root/setcap here, and TLS termination is the host reverse
# proxy's job (docs/PLAN.md "Service topology"), not this container's.
EXPOSE 8080

ENTRYPOINT ["tini", "--"]
CMD ["/app/entrypoint.sh"]
