# Stage 1: build the front end. Node isn't in the final image. FROM node:24-slim AS frontend WORKDIR /src/frontend COPY frontend/package.json frontend/package-lock.json ./ RUN npm ci --no-audit --no-fund COPY frontend/ ./ RUN npm run build # writes /src/static # Stage 2: the app. FROM python:3.13-slim ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1 DATA_DIR=/data HOST=0.0.0.0 PORT=8000 WORKDIR /app COPY requirements.txt ./ RUN pip install --no-cache-dir -r requirements.txt COPY main.py ./ COPY parentcalendar/ parentcalendar/ COPY --from=frontend /src/static/ static/ RUN useradd --system --uid 1000 parentcalendar && mkdir -p /data && chown parentcalendar /data USER parentcalendar VOLUME /data EXPOSE 8000 # Set by the release workflow; printed when the server starts. Last so a new version reuses the cached layers. ARG VERSION=dev COMMIT=unknown COMMIT_DATE=unknown ENV APP_VERSION=$VERSION APP_COMMIT=$COMMIT APP_COMMIT_DATE=$COMMIT_DATE CMD ["python", "main.py"]