65 lines
1.4 KiB
Docker
65 lines
1.4 KiB
Docker
# Stage 1: Build dependencies
|
|
FROM docker.io/python:3.13-alpine3.22 AS deps
|
|
|
|
COPY --from=ghcr.io/astral-sh/uv:0.10.4 /uv /uvx /bin/
|
|
|
|
WORKDIR /app
|
|
|
|
ENV UV_COMPILE_BYTECODE=1 \
|
|
UV_PROJECT_ENVIRONMENT=/opt/venv
|
|
|
|
COPY pyproject.toml uv.lock ./
|
|
|
|
RUN --mount=type=cache,target=/root/.cache/uv \
|
|
uv sync --frozen --no-install-project --no-dev --no-editable
|
|
|
|
|
|
# Stage 2: Build backend source
|
|
FROM deps AS backend-builder
|
|
|
|
COPY . .
|
|
|
|
|
|
# Stage 3: Build staticfiles
|
|
FROM deps AS static-builder
|
|
|
|
COPY . .
|
|
|
|
RUN uv run --no-dev python manage.py collectstatic --noinput
|
|
|
|
|
|
# Stage 3: Runtime application image
|
|
FROM docker.io/python:3.13-alpine3.22 AS app
|
|
|
|
WORKDIR /app
|
|
|
|
COPY --from=deps /opt/venv /opt/venv
|
|
COPY --from=backend-builder /app /app
|
|
|
|
RUN chmod +x scripts/entrypoint.sh && \
|
|
adduser -D -g '' app && \
|
|
chown -R app:app /app
|
|
|
|
ENV PATH="/opt/venv/bin:$PATH" \
|
|
PYTHONDONTWRITEBYTECODE=1 \
|
|
PYTHONUNBUFFERED=1 \
|
|
PYTHONOPTIMIZE=2 \
|
|
DJANGO_SETTINGS_MODULE=config.settings
|
|
|
|
USER app
|
|
|
|
EXPOSE 8080
|
|
|
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --start-interval=2s --retries=3 \
|
|
CMD wget -qO- http://127.0.0.1:8080/health || exit 1
|
|
|
|
ENTRYPOINT ["scripts/entrypoint.sh"]
|
|
|
|
|
|
# Stage 4: Staticfiles image
|
|
FROM docker.io/nginx:1.29-alpine-slim AS staticfiles
|
|
|
|
COPY --from=static-builder /app/static /usr/share/nginx/html
|
|
|
|
CMD ["nginx", "-g", "daemon off;"]
|