# LifeTrack API — FastAPI + SQLAlchemy 2.0 on Python 3.12 (DESIGN.md, "Stack"). # Build context = repository root (docker-compose.yml). FROM python:3.12-slim AS builder ENV PIP_DISABLE_PIP_VERSION_CHECK=1 \ PIP_NO_CACHE_DIR=1 \ PIP_ROOT_USER_ACTION=ignore WORKDIR /build COPY apps/api/requirements.txt . RUN python -m venv /opt/venv \ && /opt/venv/bin/pip install -r requirements.txt FROM python:3.12-slim ENV PATH="/opt/venv/bin:$PATH" \ PYTHONUNBUFFERED=1 \ PYTHONDONTWRITEBYTECODE=1 WORKDIR /srv COPY --from=builder /opt/venv /opt/venv COPY apps/api/app ./app # Non-root runtime (C7): the API never writes to disk — imports are parsed in # memory and everything is persisted in PostgreSQL — so the whole tree can stay # read-only for the service account. RUN useradd --system --create-home --uid 10001 --shell /usr/sbin/nologin lifetrack \ && chown -R lifetrack:lifetrack /srv USER lifetrack EXPOSE 8000 # `python` is the venv interpreter (see PATH): no curl/wget needed in the image. # start-period covers the first boot: metadata.create_all() builds 28 tables. HEALTHCHECK --interval=15s --timeout=5s --start-period=45s --retries=5 \ CMD ["python", "-c", "import sys, urllib.request; sys.exit(0 if urllib.request.urlopen('http://127.0.0.1:8000/api/healthz', timeout=4).status == 200 else 1)"] CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]