services: # PHP-FPM 服務 app: # 構建配置 build: context: . # 使用當前目錄作為構建上下文 dockerfile: Dockerfile # 指定 Dockerfile 路徑 image: cfdive-platform # 構建的鏡像名稱 container_name: cfdive-app # 容器名稱 restart: unless-stopped # 自動重啟策略:除非手動停止,否則自動重啟 working_dir: /var/www/ # 工作目錄 # 卷掛載:將本地代碼掛載到容器中 volumes: - ./:/var/www # 本地代碼目錄掛載到容器中的 /var/www # 環境變數:設置 Laravel 數據庫連接 environment: - DB_CONNECTION=mysql # 數據庫類型 - DB_HOST=db # 數據庫主機名 - DB_PORT=3306 # 數據庫端口 - DB_DATABASE=${DB_DATABASE:-CFDivePlatform} # 數據庫名稱 - DB_USERNAME=${DB_USERNAME:-cfdiveuser} # 數據庫用戶名 - DB_PASSWORD=${DB_PASSWORD} # 數據庫密碼 # 網絡配置 networks: - cfdive-network # 連接到自定義網絡 - proxy_net # 依賴關係:確保 db 和 redis 服務先啟動 depends_on: db: # 依賴 db 服務 condition: service_healthy # 等待數據庫健康檢查通過 redis: # 依賴 redis 服務 condition: service_started # 等待服務啟動 # 健康檢查配置 healthcheck: test: ["CMD-SHELL", "nc -z 127.0.0.1 9000 || exit 1"] interval: 30s timeout: 10s retries: 3 start_period: 40s nginx: image: nginx:alpine container_name: cfdive-nginx restart: unless-stopped ports: - "127.0.0.1:8080:80" volumes: - ./:/var/www - ./docker/nginx/conf.d/:/etc/nginx/conf.d/ networks: - cfdive-network - proxy_net depends_on: app: condition: service_healthy healthcheck: # busybox wget 對 localhost 會先解析到 IPv6 ::1,但 nginx 只 listen IPv4,須用 127.0.0.1 test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://127.0.0.1/"] interval: 30s timeout: 10s retries: 3 frontend: build: context: ./frontend dockerfile: Dockerfile args: VITE_API_URL: ${VITE_API_URL:-https://api.hank-space.com} VITE_REVERB_APP_KEY: ${VITE_REVERB_APP_KEY} VITE_REVERB_HOST: ${VITE_REVERB_HOST:-localhost} VITE_REVERB_PORT: ${VITE_REVERB_PORT:-8085} VITE_REVERB_SCHEME: ${VITE_REVERB_SCHEME:-http} image: cfdive-frontend container_name: cfdive-frontend restart: unless-stopped ports: - "127.0.0.1:5173:80" networks: - cfdive-network - proxy_net db: image: mysql:8.0 container_name: cfdive-db restart: unless-stopped environment: MYSQL_DATABASE: ${DB_DATABASE:-CFDivePlatform} MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} MYSQL_USER: ${DB_USERNAME:-cfdiveuser} MYSQL_PASSWORD: ${DB_PASSWORD} SERVICE_TAGS: dev SERVICE_NAME: mysql volumes: - mysql-data:/var/lib/mysql networks: - cfdive-network healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] interval: 30s timeout: 10s retries: 5 start_period: 30s ports: - "127.0.0.1:3306:3306" # 只綁 localhost,不對外 scheduler: image: cfdive-platform container_name: cfdive-scheduler restart: unless-stopped working_dir: /var/www/ command: php artisan schedule:work volumes: - ./:/var/www environment: - DB_CONNECTION=mysql - DB_HOST=db - DB_PORT=3306 - DB_DATABASE=${DB_DATABASE:-CFDivePlatform} - DB_USERNAME=${DB_USERNAME:-cfdiveuser} - DB_PASSWORD=${DB_PASSWORD} networks: - cfdive-network depends_on: app: condition: service_healthy queue-worker: image: cfdive-platform container_name: cfdive-queue restart: unless-stopped working_dir: /var/www/ command: php artisan queue:work --sleep=3 --tries=3 --timeout=60 volumes: - ./:/var/www environment: - DB_CONNECTION=mysql - DB_HOST=db - DB_PORT=3306 - DB_DATABASE=${DB_DATABASE:-CFDivePlatform} - DB_USERNAME=${DB_USERNAME:-cfdiveuser} - DB_PASSWORD=${DB_PASSWORD} networks: - cfdive-network depends_on: app: condition: service_healthy redis: image: redis:alpine container_name: cfdive-redis restart: unless-stopped networks: - cfdive-network volumes: - redis-data:/data healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 30s timeout: 10s retries: 3 reverb: image: cfdive-platform container_name: cfdive-reverb restart: unless-stopped working_dir: /var/www/ entrypoint: ["php", "artisan", "reverb:start", "--host=0.0.0.0", "--port=8080"] ports: - "127.0.0.1:8085:8080" volumes: - ./:/var/www environment: - APP_KEY=${APP_KEY} - REVERB_APP_ID=${REVERB_APP_ID} - REVERB_APP_KEY=${REVERB_APP_KEY} - REVERB_APP_SECRET=${REVERB_APP_SECRET} - REVERB_HOST=reverb - REVERB_PORT=8080 - REDIS_HOST=redis - DB_CONNECTION=mysql - DB_HOST=db - DB_PORT=3306 - DB_DATABASE=${DB_DATABASE:-CFDivePlatform} - DB_USERNAME=${DB_USERNAME:-cfdiveuser} - DB_PASSWORD=${DB_PASSWORD} networks: - cfdive-network - proxy_net depends_on: app: condition: service_healthy networks: cfdive-network: driver: bridge proxy_net: external: true volumes: mysql-data: driver: local redis-data: driver: local