diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..c6ed63c --- /dev/null +++ b/.dockerignore @@ -0,0 +1,35 @@ +# Build context is the repository root (see deploy/J621-Backend and +# deploy/J621-Frontend). Keep the context small and, more importantly, keep +# secrets and runtime data out of the images. + +# Version control / tooling +.git +.gitignore +.dockerignore + +# Python: the dev virtualenv, caches, and anything generated at runtime +backend/venv/ +**/__pycache__/ +**/*.py[cod] +backend/db.sqlite3 +backend/logs/ +backend/staticfiles/ + +# Secrets and media: the .env holds SECRET_KEY and DB passwords, media/ is +# the actual library. The deploy composes mount these at runtime instead. +backend/.env +backend/.env.* +backend/media/ + +# Frontend build artefacts (npm ci installs fresh from the lockfile) +frontend/node_modules/ +frontend/dist/ + +# Deploy runtime state and env +deploy/.env +deploy/.env.* +deploy/data/ +deploy/tailscale-state/ + +# Misc +*.log diff --git a/deploy/J621-Backend b/deploy/J621-Backend index b336542..923d11d 100644 --- a/deploy/J621-Backend +++ b/deploy/J621-Backend @@ -30,6 +30,14 @@ COPY backend/ ./ COPY deploy/backend-entrypoint.sh /usr/local/bin/j621-entrypoint COPY deploy/scheduler-entrypoint.sh /usr/local/bin/j621-scheduler +# Guard: fail the build if the context leaked secrets or runtime data +# (.dockerignore excludes them — see the repository root). +RUN test ! -e /app/.env \ + && test ! -d /app/venv \ + && test ! -d /app/media/library \ + && test ! -e /app/db.sqlite3 \ + && echo "build context clean" + RUN chmod +x /usr/local/bin/j621-entrypoint /usr/local/bin/j621-scheduler \ && mkdir -p /app/media /app/logs \ && python manage.py collectstatic --noinput diff --git a/deploy/README.md b/deploy/README.md index 695ac64..927c925 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -114,6 +114,15 @@ ffmpeg for video thumbnails. The `GIT_HASH` build arg is baked into the backend image so the shell's version pill shows the commit (images have no `.git` directory); the push scripts pass it automatically. +Both build from the repository root, which is filtered by `.dockerignore`: +`backend/venv`, `backend/media`, `backend/logs`, `backend/staticfiles`, +`backend/.env`, `frontend/node_modules`, `frontend/dist` and the deploy +runtime state never enter the images — the database, media and logs come +from the compose volumes and `deploy/.env` at runtime. The backend build +also asserts that (`.env`, `venv`, `media/library`, `db.sqlite3` absent), so +a missing ignore file fails the build instead of shipping secrets. Rebuild +(and `docker image prune`) if you built before that guard existed. + Push multi-arch images to the Gitea registry: ```bash