services: app: build: context: . dockerfile: docker/php/Dockerfile restart: unless-stopped volumes: # Répertoire de travail de l'entrypoint : reçoit public/ compilé, # puis partagé avec Nginx via le mount ci-dessous. - ./data:/data # Base SQLite et migrations : persistés entre redéploiements. - ./data/database:/var/www/app/database # Cache Twig/HTMLPurifier et logs : persistés entre redémarrages. - ./data/var:/var/www/app/var # Uploads : PHP écrit dans public/media/, Nginx le sert en lecture seule. - ./data/public/media:/var/www/app/public/media # phpdotenv requiert un fichier physique sur le disque (Dotenv::createImmutable) ; # `env_file` seul ne suffit pas car il injecte uniquement dans l'environnement # du process sans créer de fichier accessible via file_get_contents. - ./.env:/var/www/app/.env:ro # Rend les variables accessibles via getenv() / $_SERVER en dehors de phpdotenv # (scripts CLI, healthchecks…). env_file: .env # Vérifie que PHP-FPM écoute sur le port 9000 avant de déclarer le service sain. environment: TRUSTED_PROXIES: ${TRUSTED_PROXIES:-*} # bash /dev/tcp est disponible sur l'image Debian php:8.4-fpm sans dépendance # supplémentaire. start_period laisse le temps à entrypoint.sh de terminer # (sync public/, migrations, seed) avant que les échecs ne comptent. healthcheck: test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/localhost/9000'"] interval: 10s timeout: 3s retries: 3 start_period: 20s nginx: image: nginx:stable restart: unless-stopped depends_on: app: condition: service_healthy ports: - "127.0.0.1:8888:80" volumes: - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro # Fichiers statiques servis directement par Nginx sans passer par PHP. - ./data/public:/var/www/app/public:ro