| # Image unique : API FastAPI + WebSocket + PWA, servis sur le port 7860. | |
| # Fonctionne en local (`docker run -p 7860:7860 ...`) et comme Space Docker | |
| # Hugging Face (tier gratuit : 2 vCPU, 16 Go de RAM, 1 Go sur /data). | |
| FROM python:3.11-slim | |
| LABEL org.opencontainers.image.title="MSG MOTOC" \ | |
| org.opencontainers.image.description="Messagerie de groupe temps réel (PWA) — images en P2P" \ | |
| org.opencontainers.image.licenses="MIT" | |
| ENV PYTHONUNBUFFERED=1 \ | |
| PYTHONDONTWRITEBYTECODE=1 \ | |
| PIP_NO_CACHE_DIR=1 | |
| # Hugging Face impose de tourner en uid 1000. | |
| RUN useradd -m -u 1000 user | |
| WORKDIR /home/user/app | |
| COPY --chown=user requirements.txt . | |
| RUN pip install --no-cache-dir -r requirements.txt | |
| COPY --chown=user app ./app | |
| COPY --chown=user static ./static | |
| COPY --chown=user scripts ./scripts | |
| # Volume persistant : base SQLite, clés VAPID, secret de signature. | |
| # Sur Hugging Face, /data est monté automatiquement si le Space a du stockage ; | |
| # sinon on retombe sur ce répertoire, non persistant entre deux redémarrages. | |
| RUN mkdir -p /data && chown user:user /data | |
| VOLUME ["/data"] | |
| USER user | |
| # Rétention calée sur la cible réelle : 110 groupes x ~500 messages sur 5 jours | |
| # de festival, soit ~27 Mo mesurés (voir scripts/load_test.py). | |
| ENV HOST=0.0.0.0 \ | |
| PORT=7860 \ | |
| DATA_DIR=/data \ | |
| APP_NAME="MSG MOTOC" \ | |
| KEEP_MESSAGES_PER_GROUP=500 \ | |
| RETENTION_DAYS=30 \ | |
| SEED_DEMO=1 | |
| EXPOSE 7860 | |
| HEALTHCHECK --interval=60s --timeout=5s --start-period=15s --retries=3 \ | |
| CMD python -c "import urllib.request,sys; sys.exit(0 if urllib.request.urlopen('http://127.0.0.1:7860/api/health',timeout=4).status==200 else 1)" | |
| # Au démarrage : le jeu de test (comptes et groupes préfixés `test_`) si | |
| # SEED_DEMO=1, puis le serveur. Le seed est idempotent — un redémarrage ne | |
| # duplique rien — et les PIN viennent des secrets SEED_SUPER_PIN / SEED_DEMO_PIN, | |
| # jamais du dépôt. Mettre SEED_DEMO=0 pour un déploiement sans jeu d'essai. | |
| # | |
| # Un seul worker, volontairement : le hub WebSocket, le rate limiter et les | |
| # compteurs anti-spam vivent en mémoire du process. Passer à plusieurs workers | |
| # exigerait un backend partagé (Redis) — inutile à l'échelle visée. | |
| CMD ["sh", "-c", "if [ \"${SEED_DEMO}\" = \"1\" ]; then python scripts/seed_benevoles.py || echo 'seed ignoré'; fi; exec uvicorn app.main:app --host 0.0.0.0 --port ${PORT:-7860} --workers 1 --no-server-header --proxy-headers --forwarded-allow-ips='*' --ws-ping-interval 25 --ws-ping-timeout 60"] | |