# Build/version info. APP_VERSION comes from the committed VERSION file (always correct, # even for a plain `docker compose build`); GIT_SHA/BUILD_DATE are best-effort build-args # the deploy scripts pass. An explicit APP_VERSION build-arg still overrides the file. ARG APP_VERSION= ARG GIT_SHA=unknown ARG BUILD_DATE= # Stage 1: build the frontend SPA FROM node:20-alpine AS frontend ARG APP_VERSION ARG GIT_SHA ARG BUILD_DATE WORKDIR /fe COPY frontend/package.json ./ RUN npm install COPY frontend/ ./ COPY VERSION ./.version # Vite inlines VITE_*-prefixed env at build time; version falls back to the VERSION file. RUN VITE_APP_VERSION="${APP_VERSION:-$(cat ./.version)}" \ VITE_GIT_SHA="$GIT_SHA" \ VITE_BUILD_DATE="$BUILD_DATE" \ npm run build # Stage 2: backend runtime, serving the built SPA FROM python:3.12-slim ARG GIT_SHA ARG BUILD_DATE ENV PYTHONDONTWRITEBYTECODE=1 \ PYTHONUNBUFFERED=1 \ PIP_NO_CACHE_DIR=1 \ PIP_DISABLE_PIP_VERSION_CHECK=1 \ GIT_SHA=$GIT_SHA \ BUILD_DATE=$BUILD_DATE WORKDIR /app COPY backend/requirements.txt . RUN pip install --upgrade pip && pip install -r requirements.txt COPY backend/ . # Read at runtime by config.py as the app_version (a committed single source of truth). COPY VERSION ./VERSION COPY --from=frontend /fe/dist ./app/static_spa RUN adduser --disabled-password --gecos "" appuser && chown -R appuser /app USER appuser EXPOSE 8000 CMD ["sh", "entrypoint.sh"]