# Stage 1: Build React + TypeScript SPA FROM node:22-slim AS frontend-builder WORKDIR /build/frontend COPY frontend/package.json frontend/package-lock.json ./ RUN npm ci COPY frontend/ ./ RUN npm run build # Stage 2: Build Python virtual environment FROM python:3.11-slim AS python-builder WORKDIR /build RUN python -m venv /opt/venv ENV PATH="/opt/venv/bin:$PATH" COPY pyproject.toml README.md version.ini ./ COPY app/ ./app/ RUN pip install --no-cache-dir --upgrade pip && pip install --no-cache-dir . # Stage 3: Production Runtime FROM python:3.11-slim AS runtime WORKDIR /app ENV PYTHONDONTWRITEBYTECODE=1 \ PYTHONUNBUFFERED=1 \ PATH="/opt/venv/bin:$PATH" \ PORT=8000 RUN groupadd --gid 1001 appgroup && \ useradd --uid 1001 --gid appgroup --create-home appuser && \ mkdir -p /data && chown -R appuser:appgroup /app /data COPY --from=python-builder /opt/venv /opt/venv COPY --chown=appuser:appgroup version.ini openapi.yaml alembic.ini ./ COPY --chown=appuser:appgroup 2dlogo_large.png 2dlogo_medium_256x256.png 2dlogo_small_64x64.png 3dlogo_large.png ./ COPY --chown=appuser:appgroup alembic/ ./alembic/ COPY --chown=appuser:appgroup app/ ./app/ COPY --from=frontend-builder --chown=appuser:appgroup /build/frontend/dist ./frontend/dist COPY --chown=appuser:appgroup docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh RUN chmod +x /usr/local/bin/docker-entrypoint.sh USER appuser EXPOSE 8000 HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=3 \ CMD python -c "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8000/health', timeout=4)" || exit 1 ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] #harbor.freshbrewed.science/library/trymeapp