From 0dbd0eb0603f2374b8381b15c4567df3a3169765 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Sun, 23 Jan 2022 17:47:53 +0100 Subject: [PATCH 1/3] feat: Add Dockerfile --- .dockerignore | 34 ++++++++++++ Dockerfile | 121 +++++++++++++++++++++++++++++++++++++++++++ docker-entrypoint.sh | 25 +++++++++ 3 files changed, 180 insertions(+) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100755 docker-entrypoint.sh diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..2d1f4746 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,34 @@ +# Keep the build context small and avoid baking secrets/dev artifacts into +# image layers. The Dockerfile does `COPY . /src`, so anything not ignored +# here ends up in the build stage. + +# Version control +.git +.jj + +# Local environment and secrets +.env +*.env +!dev-template.env + +# Python virtualenv and caches +.venv +.*_cache +__pycache__/ +*.egg-info/ + +# Tooling and test artifacts +.tox +.coverage* +coverage.xml + +# Generated/local runtime data +run/ + +# Docs build output +docs/_build/ + +# Docker files themselves don't belong in the image +Dockerfile +.dockerignore +docker-compose*.yml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..cdd777bc --- /dev/null +++ b/Dockerfile @@ -0,0 +1,121 @@ +FROM python:3.14.6-slim-trixie AS base + +# -------------------------------------------- + +FROM base AS build +SHELL ["sh", "-exc"] + +# Install uv (pinned for reproducible builds) +COPY --from=ghcr.io/astral-sh/uv:0.11.21 /uv /usr/local/bin/uv + +# - Compile Python bytecode for faster app startup. +# - Silence uv complaining about not being able to use hard links. +# - Set the project virtualenv to /app. +# - Pick a Python. +# - Prevent uv from accidentally downloading isolated Python builds. +ENV UV_COMPILE_BYTECODE=1 \ + UV_LINK_MODE=copy \ + UV_PROJECT_ENVIRONMENT=/app \ + UV_PYTHON=/usr/local/bin/python \ + UV_PYTHON_DOWNLOADS=never + +# Install app dependencies +COPY pyproject.toml /_lock/ +COPY uv.lock /_lock/ +RUN --mount=type=cache,target=/root/.cache < Date: Sun, 23 Jan 2022 18:03:34 +0100 Subject: [PATCH 2/3] feat: Add docker-compose with PostgreSQL This can be useful for quickly getting the app running locally in an environment close to production. --- docker-compose.yml | 49 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 docker-compose.yml diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..ecdebe42 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,49 @@ +name: comics + +volumes: + postgres: + media: + +services: + postgres: + image: postgres:18 + environment: + - POSTGRES_USER=comics + - POSTGRES_PASSWORD=comics + - POSTGRES_DB=comics + volumes: + - postgres:/var/lib/postgresql + command: + - postgres + - -cfsync=off + - -cfull_page_writes=off + - -csynchronous_commit=off + ports: + - "5432:5432" + healthcheck: + test: ["CMD-SHELL", "pg_isready -U comics -d comics"] + interval: 5s + timeout: 5s + retries: 5 + restart: unless-stopped + + web: + build: + context: . + dockerfile: Dockerfile + image: comics:latest + depends_on: + postgres: + condition: service_healthy + env_file: + - path: .env + required: false + environment: + - DATABASE_URL=postgres://comics:comics@postgres:5432/comics + - PORT=8000 + volumes: + - media:/media + command: web + ports: + - "8000:8000" + restart: unless-stopped From c5b24b1dd74a34c9a8d001e50e4f6891e130f9a5 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Fri, 19 Jun 2026 00:10:03 +0200 Subject: [PATCH 3/3] ci: Build and publish the Docker image After the test matrix passes on a push to main, build and publish the Docker image to ghcr.io. --- .github/workflows/ci.yml | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7add55c5..6751e155 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,13 +40,11 @@ jobs: - name: "zizmor" python: "3.14" tox: zizmor - name: ${{ matrix.name }} runs-on: ubuntu-24.04 permissions: contents: read id-token: write - steps: - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: @@ -64,3 +62,39 @@ jobs: if: ${{ matrix.coverage }} with: use_oidc: true + + publish: + name: "Publish image" + needs: main + if: ${{ github.event_name == 'push' }} + runs-on: ubuntu-24.04 + permissions: + contents: read + packages: write + steps: + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false + - uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6.1.0 + id: meta + with: + images: ghcr.io/${{ github.repository }} + tags: | + type=raw,value=latest + type=sha,format=long + - uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0 + - uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + build-args: | + GIT_SHA=${{ github.sha }} + cache-from: type=gha + cache-to: type=gha,mode=max