Files
MeeJayandClaude Opus 5 93f0689c1e Initial import: LifeTrack v1 (santé, vape, finances)
Tracker de vie auto-hébergé : suivi poids/calories/sport avec planning de
pesées, sevrage tabac (vape) avec modèle de coût DIY et économies, et
finances personnelles avec import de relevés bancaires.

Architecture : FastAPI + SQLAlchemy 2.0 + PostgreSQL 16, React 18 + TS +
Vite + Tailwind + ECharts, déploiement Docker Compose. Modules
auto-découverts des deux côtés (pkgutil / import.meta.glob) et framework
de connecteurs à deux voies (importeurs de fichiers + ingestion JSON)
pour brancher de nouvelles sources sans toucher au noyau.

Validé : 292 tests pytest, tsc + vite build, contrat API/web vérifié
contre le schéma OpenAPI, et déploiement Docker réel sur PostgreSQL 16
(28 tables, SPA servie par nginx, wizard de premier démarrage).

Documentation : README.md, docs/GUIDE.md, CONVENTIONS.md, et les
documents de conception et de recherche dans docs/.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-14 10:48:57 +02:00

34 lines
1.4 KiB
Docker

# 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"]