# Stage 1: build the frontend SPA FROM node:20-alpine AS frontend WORKDIR /fe COPY frontend/package.json ./ RUN npm install COPY frontend/ ./ RUN npm run build # Stage 2: backend runtime, serving the built SPA FROM python:3.12-slim ENV PYTHONDONTWRITEBYTECODE=1 \ PYTHONUNBUFFERED=1 \ PIP_NO_CACHE_DIR=1 \ PIP_DISABLE_PIP_VERSION_CHECK=1 WORKDIR /app COPY backend/requirements.txt . RUN pip install --upgrade pip && pip install -r requirements.txt COPY backend/ . 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"]