45 lines
1.8 KiB
Docker
45 lines
1.8 KiB
Docker
FROM node:26-trixie-slim AS frontend
|
|
WORKDIR /src/frontend
|
|
COPY frontend/package.json frontend/package-lock.json ./
|
|
RUN npm ci
|
|
COPY frontend/ ./
|
|
# Django serves its routes under /api/ in the image (BBS_API_PREFIX in settings_prod.py)
|
|
ENV VITE_API_URL=/api
|
|
RUN npm run build
|
|
|
|
FROM python:3.14-slim-trixie AS build
|
|
COPY --from=ghcr.io/astral-sh/uv:0.13.4 /uv /bin/uv
|
|
# mysqlclient ships no wheels; it stays until no database is copied from MySQL
|
|
RUN apt-get update \
|
|
&& apt-get install -y --no-install-recommends build-essential pkg-config default-libmysqlclient-dev \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
# The venv lives outside /app so the final stage copies it as a layer of its own, which
|
|
# only a dependency change replaces.
|
|
ENV UV_COMPILE_BYTECODE=1 UV_LINK_MODE=copy UV_PYTHON_DOWNLOADS=never UV_PROJECT_ENVIRONMENT=/venv
|
|
WORKDIR /app
|
|
COPY pyproject.toml uv.lock ./
|
|
RUN uv sync --locked --no-dev --no-install-project
|
|
COPY . .
|
|
# Vite writes into static/, beside the files already tracked there
|
|
COPY --from=frontend /src/static/ static/
|
|
RUN DJANGO_SETTINGS_MODULE=bbs.settings_prod SECRET_KEY=collectstatic /venv/bin/python manage.py collectstatic --noinput
|
|
|
|
FROM python:3.14-slim-trixie
|
|
RUN apt-get update \
|
|
&& apt-get install -y --no-install-recommends libmariadb3 \
|
|
&& rm -rf /var/lib/apt/lists/* \
|
|
&& useradd --system --uid 932 --home-dir /app --no-create-home bbs \
|
|
&& mkdir /data && chown bbs:bbs /data
|
|
COPY --from=build /venv /venv
|
|
COPY --from=build /app /app
|
|
WORKDIR /app
|
|
ARG SENTRY_RELEASE=N/A
|
|
ENV PATH=/venv/bin:$PATH \
|
|
DJANGO_SETTINGS_MODULE=bbs.settings_prod \
|
|
PYTHONUNBUFFERED=1 \
|
|
SENTRY_RELEASE=$SENTRY_RELEASE
|
|
USER bbs
|
|
VOLUME /data
|
|
EXPOSE 8000
|
|
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "--workers", "2", "--no-control-socket", "--access-logfile", "-", "bbs.wsgi"]
|