# Stack de production CESIZen — pour déploiement sur Coolify (type "Docker Compose"). # Les valeurs (DB, domaines) sont figées en dur ci-dessous ; APP_KEY et JWT_SECRET # sont générés au démarrage par l'entrypoint du backend (aucun secret versionné). services: postgres: image: postgres:16-alpine restart: unless-stopped environment: # Identifiants de la base figés en dur : la base n'est PAS exposée # publiquement (réseau interne Coolify), et cela évite les soucis de # substitution ${...} non fiables côté Coolify (postgres et backend # doivent partager exactement le même mot de passe). POSTGRES_DB: cesizen POSTGRES_USER: cesizen POSTGRES_PASSWORD: cesizen_secret_change_me volumes: - cesizen_pgdata_v2:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U cesizen -d cesizen"] interval: 10s timeout: 5s retries: 10 start_period: 40s backend: build: context: ./backend dockerfile: Dockerfile.prod restart: unless-stopped environment: APP_NAME: CESIZen APP_ENV: production APP_DEBUG: "false" # APP_KEY et JWT_SECRET ne sont PAS dans ce fichier (pas de secret versionné) : # l'entrypoint du backend les génère au démarrage s'ils sont absents. # Domaines figés en dur (Coolify ne propage pas les ${...} de façon fiable). APP_URL: https://api.cesizen.cleanows.fr DB_CONNECTION: pgsql DB_HOST: postgres DB_PORT: 5432 DB_DATABASE: cesizen DB_USERNAME: cesizen DB_PASSWORD: cesizen_secret_change_me JWT_TTL: "60" FRONTEND_URL: https://cesizen.cleanows.fr CACHE_STORE: database SESSION_DRIVER: database QUEUE_CONNECTION: database expose: - "8000" depends_on: postgres: condition: service_healthy healthcheck: # Route santé native de Laravel (/up). On utilise php (présent dans l'image, # contrairement à curl) ; exit 0 si l'API répond, 1 sinon. test: ["CMD", "php", "-r", "exit(@file_get_contents('http://127.0.0.1:8000/up') !== false ? 0 : 1);"] interval: 15s timeout: 5s retries: 5 # Laisse le temps aux migrations + seed du démarrage avant de vérifier. start_period: 90s frontend: build: context: ./frontend dockerfile: Dockerfile.prod args: # URL PUBLIQUE de l'API (injectée au build, visible côté navigateur) NEXT_PUBLIC_API_URL: https://api.cesizen.cleanows.fr/api/v1 restart: unless-stopped expose: - "3000" depends_on: - backend healthcheck: # node est présent dans l'image (node:20-alpine) ; on interroge la page # d'accueil. exit 0 si le serveur Next répond (<400), 1 sinon. test: ["CMD", "node", "-e", "require('http').get('http://127.0.0.1:3000/',r=>process.exit(r.statusCode<400?0:1)).on('error',()=>process.exit(1))"] interval: 15s timeout: 5s retries: 5 start_period: 40s volumes: cesizen_pgdata_v2: