Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ Notes

## Containers & Volumes
- Code is bind-mounted read-only into containers (`.:/app:ro`) to avoid writes into the repo from inside Docker.
- The dev `Dockerfile` installs the packages `uv.lock` pins into `/opt/venv` before it copies the code, so a code
change doesn't reinstall them. A dependency change in `pyproject.toml` needs `uv lock` before the image builds.
- Runtime artifacts (Django `STATIC_ROOT`, `MEDIA_ROOT`, Celery beat schedule) write under `/data` backed by the `appdata` named volume.
- Generate migrations on the host (e.g., `uv run python qb_site/manage.py makemigrations`) and commit them, rather than creating files from inside containers.
- `Dockerfile.production` is the production image, separate from the dev `Dockerfile`/Compose setup: packages from
Expand Down
34 changes: 22 additions & 12 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,28 +1,38 @@
# syntax=docker/dockerfile:1

FROM python:3.12-slim
# Development image, for docker-compose.yml, which mounts the repo over /app. The production image
# is Dockerfile.production; this one starts from the same base image and the same uv.lock.

FROM python:3.12.14-slim-trixie@sha256:f77ac9e44ae96ef2c90b8053ea08c31f8be030f824196b0ae4db6d462c84e51f

COPY --from=ghcr.io/astral-sh/uv:0.12.19@sha256:04d046b13e60d6bcec73cbc5e1cad25d680dea90c8573340950a0ac2d1aef424 /uv /bin/uv

ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PIP_NO_CACHE_DIR=1 \
PIP_DISABLE_PIP_VERSION_CHECK=1 \
PYTHONPATH=/app
PYTHONPATH=/app \
PATH=/opt/venv/bin:$PATH \
UV_LINK_MODE=copy \
UV_PYTHON_DOWNLOADS=never \
UV_PROJECT_ENVIRONMENT=/opt/venv

WORKDIR /app

RUN apt-get update \
&& apt-get install -y --no-install-recommends \
build-essential \
libpq-dev \
&& rm -rf /var/lib/apt/lists/*
# Dependencies first, so that a change to the code doesn't reinstall them. The environment is
# outside /app, which Compose mounts over. --locked fails the build if uv.lock is out of date with
# pyproject.toml.
RUN --mount=type=cache,target=/root/.cache/uv \
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
--mount=type=bind,source=uv.lock,target=uv.lock \
uv sync --locked --no-dev --no-install-project

COPY pyproject.toml README.md uv.lock* ./
COPY pyproject.toml README.md uv.lock ./
COPY src ./src
COPY qb_site ./qb_site
COPY scripts ./scripts

RUN pip install --upgrade pip && \
pip install --no-cache-dir -e .
# The project itself, editable, which puts src/ on the path.
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --locked --no-dev

RUN chmod +x scripts/docker-entrypoint.sh

Expand Down
4 changes: 2 additions & 2 deletions docs/sandboxed_docker_setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ which it treats as fatal. It dies before doing any credential work, and BuildKit
generic "error getting credentials".

The helper runs only because `~/.docker/config.json` sets `"credsStore": "desktop"`. Every image
this stack pulls is public — `python:3.12-slim`, `postgres:16-alpine`, `redis:7-alpine` — so
nothing here needs a credential helper.
this stack pulls is public — `python:3.12.14-slim-trixie`, `ghcr.io/astral-sh/uv`,
`postgres:16-alpine`, `redis:7-alpine` — so nothing here needs a credential helper.

**Read-only access to those paths does not help.** The failure is a write.

Expand Down
Loading