Image Python 3.14-slim (même version qu'en dev local), utilisateur non-root, healthcheck sans dépendance externe, un seul worker Uvicorn (SQLite gère mal les écritures concurrentes multi-process). data/ monté en volume dans docker-compose.yml pour garder la base SQLite visible et sauvegardable directement dans le dossier du projet, comme en dev local. Non testé avec un vrai build : Docker indisponible dans cet environnement de dev, à vérifier avant un premier déploiement.
46 lines
2 KiB
Docker
46 lines
2 KiB
Docker
# Image officielle Python, même version majeure qu'en dev local (3.14).
|
|
# "slim" = Debian minimal : largement suffisant ici, aucune dépendance du
|
|
# projet ne nécessite de compilation (pas besoin d'une image complète).
|
|
FROM python:3.14-slim
|
|
|
|
# Pas de bytecode .pyc écrit sur disque (inutile dans un conteneur
|
|
# éphémère) et sortie non bufferisée (les logs uvicorn apparaissent tout
|
|
# de suite dans `docker logs`, pas seulement à la fermeture du process).
|
|
ENV PYTHONDONTWRITEBYTECODE=1 \
|
|
PYTHONUNBUFFERED=1
|
|
|
|
WORKDIR /app
|
|
|
|
# Copié avant le reste du code : cette couche ne se reconstruit que si
|
|
# requirements.txt change, ce qui accélère largement les rebuilds pendant
|
|
# le développement (le code applicatif change bien plus souvent).
|
|
COPY requirements.txt .
|
|
RUN pip install --no-cache-dir -r requirements.txt
|
|
|
|
COPY app/ app/
|
|
COPY scripts/ scripts/
|
|
|
|
# data/ (base SQLite) est destiné à être monté en volume (voir
|
|
# docker-compose.yml) pour que les données survivent aux
|
|
# rebuilds/redémarrages du conteneur.
|
|
RUN mkdir -p data
|
|
|
|
# Utilisateur non-root par sécurité. Si le volume data/ monté depuis
|
|
# l'hôte pose un problème de permissions (l'utilisateur de l'hôte n'a pas
|
|
# forcément l'UID 1000), ajustez les droits du dossier hôte avec
|
|
# `chown -R 1000:1000 data/`, ou retirez ces deux lignes pour tourner en root.
|
|
RUN useradd --create-home --uid 1000 appuser && chown -R appuser:appuser /app
|
|
USER appuser
|
|
|
|
EXPOSE 8000
|
|
|
|
# Vérifie que le serveur répond, sans dépendre d'un outil externe
|
|
# (curl/wget, absents de l'image "slim").
|
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s \
|
|
CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/materiels')" || exit 1
|
|
|
|
# Un seul worker Uvicorn : SQLite gère mal les écritures concurrentes
|
|
# depuis plusieurs process. Largement suffisant pour l'usage interne visé.
|
|
# Pas de --reload : réservé au dev local hors conteneur (voir README).
|
|
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
|