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
13 changes: 9 additions & 4 deletions .github/workflows/image-push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,18 @@ jobs:
permissions:
contents: read
packages: write
id-token: write
attestations: write

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver-opts: |
network=host

- name: Log in to Container Registry
uses: docker/login-action@v3
Expand All @@ -36,16 +41,15 @@ jobs:
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=raw,value=latest,enable={{is_default_branch}}
type=sha,prefix={{branch}}-
type=sha

- name: Build and push Docker image
id: build
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
platforms: linux/amd64 # Single platform for faster builds
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
Expand All @@ -54,6 +58,7 @@ jobs:

- name: Generate artifact attestation
uses: actions/attest-build-provenance@v1
if: github.event_name != 'pull_request'
with:
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}}
subject-digest: ${{ steps.build.outputs.digest }}
Expand Down
52 changes: 35 additions & 17 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,35 +1,53 @@
# Use Python 3.13 slim image
FROM python:3.13-slim
# Multi-stage build for optimization
FROM python:3.13-slim as builder

# Set environment variables
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PIP_NO_CACHE_DIR=1 \
# Set environment variables for build stage
ENV PIP_NO_CACHE_DIR=1 \
PIP_DISABLE_PIP_VERSION_CHECK=1

# Set work directory
WORKDIR /app

# Install system dependencies
# Install build dependencies
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
postgresql-client \
build-essential \
libpq-dev \
&& rm -rf /var/lib/apt/lists/*

# Install Python dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
RUN pip install --user -r requirements.txt

# Copy project
COPY . .
# Production stage
FROM python:3.13-slim

# Create non-root user
RUN adduser --disabled-password --gecos '' appuser \
&& chown -R appuser:appuser /app
# Set environment variables
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PATH=/home/appuser/.local/bin:$PATH

# Install runtime dependencies only
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
postgresql-client \
libpq5 \
&& rm -rf /var/lib/apt/lists/* \
&& apt-get purge -y --auto-remove

# Create non-root user first
RUN adduser --disabled-password --gecos '' appuser

# Copy Python packages from builder stage
COPY --from=builder /root/.local /home/appuser/.local

# Set work directory and ownership
WORKDIR /app
RUN chown appuser:appuser /app

# Switch to non-root user
USER appuser

# Copy project files
COPY --chown=appuser:appuser . .

# Collect static files
RUN python manage.py collectstatic --noinput

Expand Down