# stage 1 FROM python:3.11-alpine AS backend ARG USER_UID=1000 ARG GROUP_UID=1000 RUN apk update \ && apk add --no-cache \ vim \ curl \ gettext RUN addgroup -g $USER_UID newsreader && adduser -Du $GROUP_UID -G newsreader newsreader RUN mkdir --parents /app/src /app/logs /app/media /app/bin /app/static \ && chown -R newsreader:newsreader /app WORKDIR /app USER newsreader COPY --chown=newsreader:newsreader uv.lock pyproject.toml /app/ COPY --from=ghcr.io/astral-sh/uv:latest /uv /bin/uv RUN --mount=type=cache,target=$HOME/.cache/uv \ uv sync --frozen --no-default-groups --no-install-project COPY --chown=newsreader:newsreader ./bin/docker-entrypoint.sh /app/bin/docker-entrypoint.sh VOLUME ["/app/logs", "/app/media", "/app/static"] # stage 2 FROM node:lts-alpine AS frontend-build ARG BUILD_ARG=prod WORKDIR /app RUN chown node:node /app USER node COPY --chown=node:node ./package*.json ./webpack.*.js ./babel.config.js /app/ RUN --mount=type=cache,target=$HOME/.npm \ npm ci COPY --chown=node:node ./src /app/src RUN npm run build:$BUILD_ARG # stage 3 FROM backend AS production COPY --from=frontend-build --chown=newsreader:newsreader \ /app/src/newsreader/static /app/src/newsreader/static RUN --mount=type=cache,target=$HOME/.cache/uv \ uv sync --frozen --only-group production --extra sentry COPY --chown=newsreader:newsreader ./src /app/src # Note that the static volume will have to be recreated to be pre-populated # correctly with the latest static files. See # https://docs.docker.com/storage/volumes/#populate-a-volume-using-a-container RUN uv run --no-sync -- src/manage.py collectstatic --noinput # (optional) stage 4 FROM backend AS development RUN --mount=type=cache,target=$HOME/.cache/uv \ uv sync --frozen --group development