Files
kami_apple_exchage/deploy/docker-compose.swarm.yml
danial cbc02a6ba9 ```
refactor(docker): 调整 Playwright 浏览器目录路径

将 Playwright 浏览器的挂载路径从 /app/data/playwright-browsers
调整为 /app/playwright-browsers,以优化容器内目录结构。同时
清理了 backend Dockerfile 中不必要的目录创建操作。
```
2025-09-20 02:23:30 +08:00

309 lines
6.9 KiB
YAML

# Apple Gift Card Exchange Platform - Docker Swarm Stack Configuration
# 适用于 Docker Swarm 生产环境部署
services:
# ===== 前端服务 =====
frontend:
build:
context: ../frontend
dockerfile: Dockerfile
environment:
- NODE_ENV=production
- NEXT_PUBLIC_ENV=production
- NEXT_PUBLIC_API_URL=http://api:8000/api
networks:
- app-network
depends_on:
- api
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
deploy:
mode: replicated
replicas: 2
update_config:
parallelism: 1
delay: 10s
failure_action: rollback
rollback_config:
parallelism: 1
delay: 10s
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
resources:
limits:
cpus: '0.5'
memory: 512M
reservations:
cpus: '0.2'
memory: 256M
ports:
- "8080:8080"
# ===== 后端 API 服务 =====
api:
build:
context: ../backend
dockerfile: Dockerfile
environment:
- SERVICE_TYPE=api
- ENVIRONMENT=production
- DATABASE_URL=postgresql+asyncpg://postgres:${POSTGRES_PASSWORD}@db:5432/apple_exchange
- REDIS_URL=redis://redis:6379/0
- WORKERS=4
volumes:
- logs:/app/logs
- data:/app/data
networks:
- app-network
depends_on:
- db
- redis
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/api/v1/health/liveness"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
deploy:
mode: replicated
replicas: 2
update_config:
parallelism: 1
delay: 10s
failure_action: rollback
rollback_config:
parallelism: 1
delay: 10s
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
resources:
limits:
cpus: '1.0'
memory: 1G
reservations:
cpus: '0.5'
memory: 512M
ports:
- "8000:8000"
# ===== Celery Worker 服务 =====
worker:
build:
context: ../backend
dockerfile: Dockerfile.worker
environment:
- SERVICE_TYPE=worker
- ENVIRONMENT=production
- DATABASE_URL=postgresql+asyncpg://postgres:${POSTGRES_PASSWORD}@db:5432/apple_exchange
- REDIS_URL=redis://redis:6379/0
- WORKER_MAX_JOBS=10
- WORKER_JOB_TIMEOUT=1800
- WORKER_MAX_TRIES=3
- WORKER_HEALTH_CHECK_INTERVAL=30
volumes:
- logs:/app/logs
- data:/app/data
- playwright_browsers:/app/playwright-browsers
networks:
- app-network
depends_on:
- db
- redis
healthcheck:
test: ["CMD", "python", "-c", "from app.core.arq_worker import get_arq_worker; worker = get_arq_worker(); print('Arq worker healthy')"]
interval: 60s
timeout: 30s
retries: 3
start_period: 60s
deploy:
mode: replicated
replicas: 3
update_config:
parallelism: 2
delay: 10s
failure_action: rollback
rollback_config:
parallelism: 2
delay: 10s
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
resources:
limits:
cpus: '2.0'
memory: 2G
reservations:
cpus: '1.0'
memory: 1G
placement:
constraints:
- node.role == worker
# ===== Celery Beat 调度服务 =====
beat:
build:
context: ../backend
dockerfile: Dockerfile
environment:
- SERVICE_TYPE=beat
- ENVIRONMENT=production
- DATABASE_URL=postgresql+asyncpg://postgres:${POSTGRES_PASSWORD}@db:5432/apple_exchange
- REDIS_URL=redis://redis:6379/0
volumes:
- logs:/app/logs
- data:/app/data
networks:
- app-network
depends_on:
- db
- redis
healthcheck:
test: ["CMD", "python", "-c", "import sys; sys.exit(0)"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s
deploy:
mode: replicated
replicas: 1
update_config:
parallelism: 1
delay: 10s
failure_action: rollback
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
resources:
limits:
cpus: '0.5'
memory: 512M
reservations:
cpus: '0.2'
memory: 256M
placement:
constraints:
- node.role == manager
# ===== PostgreSQL 数据库 =====
db:
image: postgres:17-alpine
environment:
- POSTGRES_DB=apple_exchange
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=ajNHYrqSNaTdPFq3
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- app-network
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
deploy:
mode: replicated
replicas: 1
update_config:
parallelism: 1
delay: 10s
failure_action: rollback
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
resources:
limits:
cpus: '1.0'
memory: 1G
reservations:
cpus: '0.5'
memory: 512M
placement:
constraints:
- node.role == manager
- node.labels.db == true
# ===== Redis 缓存和消息代理 =====
redis:
image: redis:7-alpine
volumes:
- redis_data:/data
networks:
- app-network
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
deploy:
mode: replicated
replicas: 1
update_config:
parallelism: 1
delay: 10s
failure_action: rollback
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
resources:
limits:
cpus: '0.5'
memory: 512M
reservations:
cpus: '0.2'
memory: 256M
placement:
constraints:
- node.role == manager
- node.labels.redis == true
# ===== 数据卷 =====
volumes:
postgres_data:
driver: local
name: apple-exchange-postgres-data
redis_data:
driver: local
name: apple-exchange-redis-data
shared_storage:
driver: local
name: apple-exchange-shared-storage
playwright_browsers:
driver: local
name: apple-exchange-playwright-browsers
logs:
driver: local
name: apple-exchange-logs
data:
driver: local
name: apple-exchange-data
screenshots:
driver: local
name: apple-exchange-screenshots
# ===== 网络 =====
networks:
app-network:
driver: overlay
name: apple-exchange-network
attachable: true