services: # ============================================================================= # BACKEND API - PHP 8.5 + FrankenPHP # ============================================================================= php: build: context: ./backend dockerfile: Dockerfile target: dev container_name: classeo_php environment: APP_ENV: dev APP_DEBUG: 1 DATABASE_URL: postgresql://classeo:classeo@db:5432/classeo_master?serverVersion=18&charset=utf8 REDIS_URL: redis://redis:6379 MESSENGER_TRANSPORT_DSN: amqp://guest:guest@rabbitmq:5672/%2f/messages MERCURE_URL: http://mercure/.well-known/mercure MERCURE_PUBLIC_URL: http://localhost:3000/.well-known/mercure MERCURE_JWT_SECRET: mercure_publisher_secret_change_me_in_production MEILISEARCH_URL: http://meilisearch:7700 MEILISEARCH_API_KEY: masterKey MAILER_DSN: smtp://mailpit:1025 ports: - "18000:8000" # Port externe 18000 pour eviter conflit volumes: - ./backend:/app:cached depends_on: db: condition: service_healthy redis: condition: service_healthy rabbitmq: condition: service_healthy healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8000/api"] interval: 10s timeout: 5s retries: 5 start_period: 30s restart: unless-stopped # ============================================================================= # FRONTEND - SvelteKit + Node.js # ============================================================================= frontend: build: context: ./frontend dockerfile: Dockerfile target: dev container_name: classeo_frontend environment: PUBLIC_API_URL: http://localhost:18000/api PUBLIC_MERCURE_URL: http://localhost:3000/.well-known/mercure ports: - "5174:5173" # Port externe 5174 pour eviter conflit volumes: - ./frontend:/app:cached - frontend_node_modules:/app/node_modules healthcheck: test: ["CMD", "wget", "-q", "--spider", "http://localhost:5173/"] interval: 10s timeout: 5s retries: 5 start_period: 30s restart: unless-stopped # ============================================================================= # DATABASE - PostgreSQL 18.1 # ============================================================================= db: image: postgres:18.1-alpine container_name: classeo_db environment: POSTGRES_DB: classeo_master POSTGRES_USER: classeo POSTGRES_PASSWORD: classeo ports: - "5433:5432" # Port externe 5433 pour eviter conflit avec PostgreSQL local volumes: - postgres_data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U classeo -d classeo_master"] interval: 10s timeout: 5s retries: 5 start_period: 10s restart: unless-stopped # ============================================================================= # CACHE & SESSIONS - Redis 7.4 # ============================================================================= redis: image: redis:7.4-alpine container_name: classeo_redis command: redis-server --appendonly yes ports: - "6380:6379" # Port externe 6380 pour eviter conflit avec Redis local volumes: - redis_data:/data healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 start_period: 5s restart: unless-stopped # ============================================================================= # MESSAGE QUEUE - RabbitMQ 4.2 # ============================================================================= rabbitmq: image: rabbitmq:4.2-management-alpine container_name: classeo_rabbitmq environment: RABBITMQ_DEFAULT_USER: guest RABBITMQ_DEFAULT_PASS: guest ports: - "5672:5672" - "15672:15672" volumes: - rabbitmq_data:/var/lib/rabbitmq healthcheck: test: ["CMD", "rabbitmq-diagnostics", "-q", "ping"] interval: 30s timeout: 10s retries: 5 start_period: 30s restart: unless-stopped # ============================================================================= # REAL-TIME SSE - Mercure # ============================================================================= mercure: image: dunglas/mercure:latest container_name: classeo_mercure environment: MERCURE_PUBLISHER_JWT_KEY: "mercure_publisher_secret_change_me_in_production" MERCURE_SUBSCRIBER_JWT_KEY: "mercure_subscriber_secret_change_me_in_production" SERVER_NAME: ":80" MERCURE_EXTRA_DIRECTIVES: | cors_origins http://localhost:5174 anonymous ports: - "3000:80" healthcheck: test: ["CMD", "wget", "-q", "--spider", "http://localhost/.well-known/mercure"] interval: 10s timeout: 5s retries: 5 start_period: 10s restart: unless-stopped # ============================================================================= # FULL-TEXT SEARCH - Meilisearch 1.12 # ============================================================================= meilisearch: image: getmeili/meilisearch:v1.12 container_name: classeo_meilisearch environment: MEILI_MASTER_KEY: "masterKey" MEILI_ENV: "development" ports: - "7700:7700" volumes: - meilisearch_data:/meili_data healthcheck: test: ["CMD", "wget", "-q", "--spider", "http://localhost:7700/health"] interval: 10s timeout: 5s retries: 5 start_period: 10s restart: unless-stopped # ============================================================================= # EMAIL TESTING - Mailpit # ============================================================================= mailpit: image: axllent/mailpit:latest container_name: classeo_mailpit ports: - "1025:1025" - "8025:8025" healthcheck: test: ["CMD", "wget", "-q", "--spider", "http://localhost:8025"] interval: 10s timeout: 5s retries: 5 start_period: 5s restart: unless-stopped # ============================================================================= # VOLUMES PERSISTANTS # ============================================================================= volumes: postgres_data: redis_data: rabbitmq_data: meilisearch_data: frontend_node_modules: