version: "3.8" services: app: build: . ports: - "3000:3000" # Expose app on host port 3000 depends_on: db: condition: service_healthy # Wait for DB to be healthy redis: condition: service_started # Wait for Redis to start environment: - DB_HOST=${DB_HOST} - DB_USER=${DB_USER} - DB_PASSWORD=${DB_PASSWORD} - DB_NAME=${DB_NAME} - PORT=${PORT} - REDIS_HOST=${REDIS_HOST:-redis} - REDIS_PORT=${REDIS_PORT:-6379} - REDIS_PASSWORD=${REDIS_PASSWORD:-} restart: unless-stopped db: image: mysql:8.0 ports: - "3307:3306" # Expose DB on host port 3307 (to avoid conflict if you have local MySQL on 3306) environment: MYSQL_ROOT_PASSWORD: your_root_password # Change this MYSQL_DATABASE: ${DB_NAME} MYSQL_USER: ${DB_USER} MYSQL_PASSWORD: ${DB_PASSWORD} volumes: - mysql_data:/var/lib/mysql # Persist database data - ./init.sql:/docker-entrypoint-initdb.d/init.sql # Run init script on startup healthcheck: test: [ "CMD", "mysqladmin", "ping", "-h", "localhost", "-u$$MYSQL_USER", "-p$$MYSQL_PASSWORD", ] interval: 10s timeout: 5s retries: 5 restart: unless-stopped redis: image: redis:7-alpine ports: - "6380:6379" # Expose Redis on host port 6380 (to avoid conflict if you have local Redis on 6379) command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD:-} volumes: - redis_data:/data # Persist Redis data healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 restart: unless-stopped volumes: mysql_data: redis_data: