version: '3.8' services: mysql: image: mysql:8.0 container_name: todo_mysql restart: unless-stopped environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-rootpassword} MYSQL_DATABASE: ${MYSQL_DATABASE:-todo_system} MYSQL_USER: ${MYSQL_USER:-todouser} MYSQL_PASSWORD: ${MYSQL_PASSWORD:-todopass} TZ: Asia/Taipei ports: - "${MYSQL_PORT:-3306}:3306" volumes: - ./mysql/data:/var/lib/mysql - ./mysql/init:/docker-entrypoint-initdb.d command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci networks: - todo_network redis: image: redis:7-alpine container_name: todo_redis restart: unless-stopped ports: - "${REDIS_PORT:-6379}:6379" volumes: - ./redis/data:/data networks: - todo_network backend: build: context: ./backend dockerfile: Dockerfile container_name: todo_backend restart: unless-stopped depends_on: - mysql - redis environment: - FLASK_ENV=${FLASK_ENV:-development} - MYSQL_HOST=mysql - MYSQL_PORT=3306 - MYSQL_DATABASE=${MYSQL_DATABASE:-todo_system} - MYSQL_USER=${MYSQL_USER:-todouser} - MYSQL_PASSWORD=${MYSQL_PASSWORD:-todopass} - REDIS_URL=redis://redis:6379/0 ports: - "${BACKEND_PORT:-5000}:5000" volumes: - ./backend:/app - ./uploads:/app/uploads - ./logs:/app/logs networks: - todo_network frontend: build: context: ./frontend dockerfile: Dockerfile container_name: todo_frontend restart: unless-stopped depends_on: - backend environment: - NODE_ENV=${NODE_ENV:-development} - NEXT_PUBLIC_API_URL=${API_URL:-http://localhost:5000} ports: - "${FRONTEND_PORT:-3000}:3000" volumes: - ./frontend:/app - /app/node_modules - /app/.next networks: - todo_network nginx: image: nginx:alpine container_name: todo_nginx restart: unless-stopped depends_on: - backend - frontend ports: - "${NGINX_PORT:-80}:80" - "${NGINX_SSL_PORT:-443}:443" volumes: - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro - ./nginx/conf.d:/etc/nginx/conf.d:ro - ./nginx/ssl:/etc/nginx/ssl:ro networks: - todo_network networks: todo_network: driver: bridge volumes: mysql_data: redis_data: