diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..18423b4 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,40 @@ +# Version control +.git +.gitignore + +# Python caches and virtualenvs +__pycache__/ +*.py[cod] +*.egg-info/ +.eggs/ +.pytest_cache/ +.ruff_cache/ +.mypy_cache/ +.coverage +htmlcov/ +pythonie-venv/ +.venv/ +venv/ + +# Local databases and media +*.sqlite3 +pythonie/db.sqlite3 +media/ + +# Secrets and local env +.env +.envrc +*.env + +# Editor / OS noise +.vscode/ +.idea/ +.DS_Store + +# Worktrees and tooling output +.claude/ +graphify-out/ + +# Docs and CI not needed in the build context +*.md +.github/ diff --git a/Dockerfile b/Dockerfile index 510278e..f05a4fa 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,20 +1,52 @@ # syntax=docker/dockerfile:1.21.0 -FROM python:3.13 AS compile-stage -RUN --mount=type=cache,target=/var/cache/apt \ - apt update && \ - apt install -y --no-install-recommends \ - build-essential gcc neovim fish less iputils-ping postgresql-client \ - ack -ADD requirements/main.txt \ - requirements/dev.txt \ - requirements/production.txt \ - ./requirements/ + +# ---- builder: compile and install Python deps into an isolated venv ---- +FROM python:3.13-slim AS builder + +ENV UV_LINK_MODE=copy \ + PIP_DISABLE_PIP_VERSION_CHECK=1 + +# build-essential/gcc are only needed to build wheels that lack a prebuilt one. +# They live in this stage only and never reach the final image. +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,target=/var/lib/apt/lists,sharing=locked \ + apt-get update && \ + apt-get install -y --no-install-recommends \ + build-essential gcc + +RUN --mount=type=cache,target=/root/.cache \ + pip install -U pip uv + +COPY requirements/main.txt \ + requirements/dev.txt \ + requirements/production.txt \ + ./requirements/ + +# Install everything into a self-contained venv at /opt/venv so the final +# stage can copy it without dragging in the build toolchain. RUN --mount=type=cache,target=/root/.cache \ - pip install -U pip uv ruff && \ - python -m uv pip install \ + uv venv /opt/venv && \ + uv pip install --python /opt/venv \ -r requirements/main.txt \ -r requirements/dev.txt \ - -r requirements/production.txt aws + -r requirements/production.txt + +# ---- dev: lean runtime image with interactive tooling (used by web + test) ---- +FROM python:3.13-slim AS dev + +ENV PATH="/opt/venv/bin:$PATH" \ + PYTHONUNBUFFERED=1 \ + PYTHONDONTWRITEBYTECODE=1 + +# Runtime-only system packages: the postgres client for psql/pg_dump plus the +# interactive tooling the dev shell relies on (compose runs `fish`). +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,target=/var/lib/apt/lists,sharing=locked \ + apt-get update && \ + apt-get install -y --no-install-recommends \ + postgresql-client \ + fish neovim less ack iputils-ping -FROM compile-stage AS tests-stage +COPY --from=builder /opt/venv /opt/venv +WORKDIR /app