c9247778f7
playwright E2E 测试发现: 1. compose.yml 和 nginx.conf 从 deploy/local/ 目录被意外删除 2. Docker 项目 'local' 的配置文件丢失,容器重启后无法重建 3. 添加 deploy/local/data/ 到 .gitignore 防止 Docker 运行时数据被提交 Playwright 测试验证结果: - /fl/login 登录页加载正常 (HTTP 200) - admin/admin 登录成功,跳转到后台页面 - 无 JS 控制台错误 - 静态资源(CSS/favicon)加载正常 - API /health 健康检查正常
228 lines
6.5 KiB
YAML
228 lines
6.5 KiB
YAML
services:
|
|
proxy:
|
|
image: docker.m.daocloud.io/library/nginx:1.27-alpine
|
|
container_name: ${COMPOSE_PROJECT_NAME}-proxy
|
|
ports:
|
|
- "${PROXY_PORT}:3000"
|
|
volumes:
|
|
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
|
|
depends_on:
|
|
- web
|
|
restart: unless-stopped
|
|
|
|
db:
|
|
image: ${POSTGRES_IMAGE}
|
|
container_name: ${COMPOSE_PROJECT_NAME}-db
|
|
environment:
|
|
POSTGRES_DB: ${POSTGRES_DB}
|
|
POSTGRES_USER: ${POSTGRES_USER}
|
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
|
PGDATA: /var/lib/postgresql/data/pgdata
|
|
ports:
|
|
- "${POSTGRES_PORT}:5432"
|
|
volumes:
|
|
- ./data/postgres:/var/lib/postgresql/data
|
|
restart: unless-stopped
|
|
|
|
redis:
|
|
image: ${REDIS_IMAGE}
|
|
container_name: ${COMPOSE_PROJECT_NAME}-redis
|
|
ports:
|
|
- "${REDIS_PORT}:6379"
|
|
volumes:
|
|
- ./data/redis:/data
|
|
command:
|
|
- redis-server
|
|
- --appendonly
|
|
- "yes"
|
|
- --requirepass
|
|
- ${REDIS_PASSWORD}
|
|
- --save
|
|
- ""
|
|
- --stop-writes-on-bgsave-error
|
|
- "no"
|
|
restart: unless-stopped
|
|
|
|
minio:
|
|
image: ${MINIO_IMAGE}
|
|
container_name: ${COMPOSE_PROJECT_NAME}-minio
|
|
command: server /data --console-address ":9001"
|
|
environment:
|
|
MINIO_ROOT_USER: ${MINIO_ACCESS_KEY}
|
|
MINIO_ROOT_PASSWORD: ${MINIO_SECRET_KEY}
|
|
ports:
|
|
- "${MINIO_API_PORT}:9000"
|
|
- "${MINIO_CONSOLE_PORT}:9001"
|
|
volumes:
|
|
- ./data/minio:/data
|
|
restart: unless-stopped
|
|
|
|
minio-init:
|
|
image: ${MINIO_MC_IMAGE}
|
|
container_name: ${COMPOSE_PROJECT_NAME}-minio-init
|
|
depends_on:
|
|
- minio
|
|
entrypoint: /bin/sh
|
|
command:
|
|
- -c
|
|
- >
|
|
until mc alias set local "$${MINIO_ENDPOINT}" "$${MINIO_ACCESS_KEY}" "$${MINIO_SECRET_KEY}"; do
|
|
sleep 1;
|
|
done;
|
|
mc mb -p "local/$${MINIO_BUCKET}" || true;
|
|
environment:
|
|
MINIO_ENDPOINT: ${MINIO_ENDPOINT}
|
|
MINIO_ACCESS_KEY: ${MINIO_ACCESS_KEY}
|
|
MINIO_SECRET_KEY: ${MINIO_SECRET_KEY}
|
|
MINIO_BUCKET: ${MINIO_BUCKET}
|
|
restart: "no"
|
|
|
|
api:
|
|
image: fquiz-worker:local
|
|
container_name: ${COMPOSE_PROJECT_NAME}-api
|
|
depends_on:
|
|
- db
|
|
- redis
|
|
- minio
|
|
- minio-init
|
|
environment:
|
|
API_HOST: 0.0.0.0
|
|
API_PORT: 8000
|
|
DB_HOST: db
|
|
DB_PORT: 5432
|
|
DB_NAME: fquiz
|
|
DB_USERNAME: ${DB_USERNAME}
|
|
DB_PASSWORD: ${DB_PASSWORD}
|
|
DB_SCHEMA: public
|
|
USER_USERNAME_COLUMN: username
|
|
USER_PASSWORD_COLUMN: password_hash
|
|
USER_STATUS_COLUMN: status
|
|
DATABASE_URL: postgresql+psycopg://${DB_USERNAME}:${DB_PASSWORD}@db:5432/fquiz
|
|
MINIO_ENABLED: "true"
|
|
MINIO_ENDPOINT: http://minio:9000
|
|
MINIO_ACCESS_KEY: ${MINIO_ACCESS_KEY}
|
|
MINIO_SECRET_KEY: ${MINIO_SECRET_KEY}
|
|
MINIO_BUCKET: ${MINIO_BUCKET}
|
|
MINIO_REGION: us-east-1
|
|
CELERY_BROKER_URL: redis://:${REDIS_PASSWORD}@redis:6379/0
|
|
CELERY_RESULT_BACKEND: redis://:${REDIS_PASSWORD}@redis:6379/1
|
|
CELERY_TIMEZONE: Asia/Shanghai
|
|
FLOWER_BASIC_AUTH: ${FLOWER_BASIC_AUTH}
|
|
FLOWER_API_BASE_URL: http://flower:5555
|
|
FLOWER_API_TIMEOUT_SECONDS: 10
|
|
JWT_SECRET_KEY: ${JWT_SECRET_KEY}
|
|
ACCESS_TOKEN_EXPIRE_MINUTES: ${ACCESS_TOKEN_EXPIRE_MINUTES}
|
|
REFRESH_TOKEN_EXPIRE_DAYS: ${REFRESH_TOKEN_EXPIRE_DAYS}
|
|
REFRESH_COOKIE_SECURE: "false"
|
|
REFRESH_COOKIE_SAMESITE: lax
|
|
API_CORS_ORIGINS: http://localhost:3000,http://127.0.0.1:3000
|
|
WORKER_REGISTRY_TTL_SECONDS: 90
|
|
WINE_BINARY_PATH: wine
|
|
WINE_ALLOWED_ROOT: /app/data/wine
|
|
WINE_DEFAULT_TIMEOUT_SECONDS: 300
|
|
WINE_MAX_TIMEOUT_SECONDS: 1800
|
|
FILE_VFS_ROOT: /app/data/vfs
|
|
ports:
|
|
- "${API_PORT}:8000"
|
|
volumes:
|
|
- ./data/app:/app/data
|
|
restart: unless-stopped
|
|
|
|
celery-worker:
|
|
image: fquiz-worker:local
|
|
container_name: ${COMPOSE_PROJECT_NAME}-celery-worker
|
|
command:
|
|
- celery
|
|
- -A
|
|
- app.core.celery_app.celery_app
|
|
- worker
|
|
- --loglevel=${CELERY_LOG_LEVEL}
|
|
- --concurrency=${CELERY_WORKER_CONCURRENCY}
|
|
- --queues=${CELERY_WORKER_QUEUES}
|
|
depends_on:
|
|
- api
|
|
- redis
|
|
environment:
|
|
DB_HOST: db
|
|
DB_PORT: 5432
|
|
DB_NAME: fquiz
|
|
DB_USERNAME: ${DB_USERNAME}
|
|
DB_PASSWORD: ${DB_PASSWORD}
|
|
DB_SCHEMA: public
|
|
DATABASE_URL: postgresql+psycopg://${DB_USERNAME}:${DB_PASSWORD}@db:5432/fquiz
|
|
CELERY_BROKER_URL: redis://:${REDIS_PASSWORD}@redis:6379/0
|
|
CELERY_RESULT_BACKEND: redis://:${REDIS_PASSWORD}@redis:6379/1
|
|
CELERY_TIMEZONE: Asia/Shanghai
|
|
MINIO_ENABLED: "true"
|
|
MINIO_ENDPOINT: http://minio:9000
|
|
MINIO_ACCESS_KEY: ${MINIO_ACCESS_KEY}
|
|
MINIO_SECRET_KEY: ${MINIO_SECRET_KEY}
|
|
MINIO_BUCKET: ${MINIO_BUCKET}
|
|
MINIO_REGION: us-east-1
|
|
WINE_BINARY_PATH: wine
|
|
WINE_ALLOWED_ROOT: /app/data/wine
|
|
WINE_DEFAULT_TIMEOUT_SECONDS: 300
|
|
WINE_MAX_TIMEOUT_SECONDS: 1800
|
|
volumes:
|
|
- ./data/app:/app/data
|
|
restart: unless-stopped
|
|
|
|
celery-beat:
|
|
image: fquiz-worker:local
|
|
container_name: ${COMPOSE_PROJECT_NAME}-celery-beat
|
|
command:
|
|
- celery
|
|
- -A
|
|
- app.core.celery_app.celery_app
|
|
- beat
|
|
- --loglevel=${CELERY_LOG_LEVEL}
|
|
- --schedule=/app/data/celery/beat-schedule
|
|
depends_on:
|
|
- api
|
|
- redis
|
|
environment:
|
|
DB_HOST: db
|
|
DB_PORT: 5432
|
|
DB_NAME: fquiz
|
|
DATABASE_URL: postgresql+psycopg://${DB_USERNAME}:${DB_PASSWORD}@db:5432/fquiz
|
|
CELERY_BROKER_URL: redis://:${REDIS_PASSWORD}@redis:6379/0
|
|
CELERY_RESULT_BACKEND: redis://:${REDIS_PASSWORD}@redis:6379/1
|
|
CELERY_TIMEZONE: Asia/Shanghai
|
|
volumes:
|
|
- ./data/app:/app/data
|
|
restart: unless-stopped
|
|
|
|
flower:
|
|
image: fquiz-worker:local
|
|
container_name: ${COMPOSE_PROJECT_NAME}-flower
|
|
command:
|
|
- celery
|
|
- -A
|
|
- app.core.celery_app.celery_app
|
|
- flower
|
|
- --address=0.0.0.0
|
|
- --port=5555
|
|
- --persistent=False
|
|
- --basic-auth=${FLOWER_BASIC_AUTH}
|
|
depends_on:
|
|
- redis
|
|
environment:
|
|
CELERY_BROKER_URL: redis://:${REDIS_PASSWORD}@redis:6379/0
|
|
CELERY_RESULT_BACKEND: redis://:${REDIS_PASSWORD}@redis:6379/1
|
|
CELERY_TIMEZONE: Asia/Shanghai
|
|
FLOWER_BASIC_AUTH: ${FLOWER_BASIC_AUTH:-admin:admin}
|
|
ports:
|
|
- "${FLOWER_PORT}:5555"
|
|
restart: unless-stopped
|
|
|
|
web:
|
|
image: fquiz-web:local
|
|
container_name: ${COMPOSE_PROJECT_NAME}-web
|
|
depends_on:
|
|
- api
|
|
environment:
|
|
NEXT_PUBLIC_API_BASE_URL: http://localhost:8000
|
|
NEXT_PUBLIC_APP_BASE_PATH: /fl
|
|
NODE_ENV: production
|
|
restart: unless-stopped
|