|
1 | 1 | # syntax=docker/dockerfile:1 |
2 | | -# Prepare the base environment. |
3 | | -FROM python:3.13 AS builder_base |
4 | | - |
5 | | -# This approximately follows this guide: https://hynek.me/articles/docker-uv/ |
6 | | -# Which creates a standalone environment with the dependencies. |
7 | | -# - Silence uv complaining about not being able to use hard links, |
8 | | -# - tell uv to byte-compile packages for faster application startups, |
9 | | -# - prevent uv from accidentally downloading isolated Python builds, |
10 | | -# - pick a Python, |
11 | | -# - and finally declare `/app` as the target for `uv sync`. |
12 | | -ENV UV_LINK_MODE=copy \ |
13 | | - UV_COMPILE_BYTECODE=1 \ |
14 | | - UV_PYTHON_DOWNLOADS=never \ |
15 | | - UV_PROJECT_ENVIRONMENT=/app/.venv |
16 | | - |
17 | | -COPY --from=ghcr.io/astral-sh/uv:0.9 /uv /uvx /bin/ |
18 | | - |
19 | | -# Since there's no point in shipping lock files, we move them |
20 | | -# into a directory that is NOT copied into the runtime image. |
21 | | -# The trailing slash makes COPY create `/_lock/` automagically. |
22 | | -WORKDIR /_lock |
23 | | -COPY pyproject.toml uv.lock /_lock/ |
24 | | - |
25 | | -# Synchronize dependencies. |
26 | | -# This layer is cached until uv.lock or pyproject.toml change. |
27 | | -RUN --mount=type=cache,target=/root/.cache uv sync --frozen --no-group dev |
28 | | - |
29 | | -################################################################################## |
30 | | - |
31 | | -FROM python:3.13 |
| 2 | +FROM dhi.io/python:3.13-debian13-dev AS build-stage |
32 | 3 | LABEL org.opencontainers.image.authors=asi@dbca.wa.gov.au |
33 | 4 | LABEL org.opencontainers.image.source=https://github.com/dbca-wa/ssslite |
34 | 5 |
|
35 | | -# Create a non-root user. |
36 | | -RUN groupadd -r -g 1000 app \ |
37 | | - && useradd -r -u 1000 -d /app -g app -N app |
| 6 | +# Install system packages required to install the project |
| 7 | +RUN apt-get update -y \ |
| 8 | + # Python package dependencies: gunicorn_h1c requires gcc |
| 9 | + && apt-get install -y --no-install-recommends gcc g++ \ |
| 10 | + # Run shared library linker after installing packages |
| 11 | + && ldconfig \ |
| 12 | + && rm -rf /var/lib/apt/lists/* |
38 | 13 |
|
| 14 | +# Copy and configure uv, to install dependencies |
| 15 | +COPY --from=ghcr.io/astral-sh/uv:0.11 /uv /bin/ |
39 | 16 | WORKDIR /app |
40 | | -COPY --from=builder_base --chown=app:app /app /app |
41 | | -# Make sure we use the virtualenv by default |
42 | | -ENV PATH="/app/.venv/bin:$PATH" \ |
43 | | - # Run Python unbuffered: |
44 | | - PYTHONUNBUFFERED=1 |
45 | | - |
46 | | -# Install the project. |
| 17 | +# Install project dependencies |
| 18 | +COPY pyproject.toml uv.lock ./ |
| 19 | +RUN uv sync --no-group dev --link-mode=copy --compile-bytecode --no-python-downloads --frozen \ |
| 20 | + # Remove uv and lockfile after use |
| 21 | + && rm -rf /bin/uv \ |
| 22 | + && rm uv.lock |
| 23 | + |
| 24 | +# Environment variables |
| 25 | +ENV PYTHONUNBUFFERED=1 |
| 26 | +ENV PATH="/app/.venv/bin:$PATH" |
| 27 | + |
| 28 | +# Copy the remaining project files to finish building the project |
47 | 29 | COPY gunicorn.py ibp.html todaysburns.html pyproject.toml ssslite.py ./ |
48 | 30 | COPY static ./static |
49 | | -USER app |
| 31 | + |
| 32 | +# Image runs as the nonroot user |
50 | 33 | EXPOSE 8080 |
51 | 34 | CMD ["gunicorn", "ssslite", "--config", "gunicorn.py"] |
0 commit comments