准备部署
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
# ============================================================
|
||||
# 青叶 (QingYe) —— 生产环境 Docker Compose(自包含)
|
||||
# ------------------------------------------------------------
|
||||
# 启动命令:
|
||||
# docker compose --env-file .env.prod -f docker-compose.prod.yml up -d --build
|
||||
#
|
||||
# 说明:
|
||||
# * 此文件为「生产专用」,与开发用的 docker-compose.yml 完全独立。
|
||||
# 生产服务器上请始终带 -f docker-compose.prod.yml,切勿运行裸 docker compose up。
|
||||
# * 所有密钥通过 --env-file .env.prod 注入(密钥文件已在 .gitignore 中)。
|
||||
# * 后端必须「单进程」运行:WebSocket 连接管理器为进程内存单例
|
||||
# (见 backend/app/websocket/manager.py),多 worker / gunicorn 会导致
|
||||
# 跨用户、跨标签页的实时消息丢失。镜像 Dockerfile.prod 已固定为单进程。
|
||||
# * postgres / redis 不向主机暴露端口,仅容器内网互通。
|
||||
# * backend / frontend 仅绑定 127.0.0.1,由宿主机 Nginx 反向代理对外。
|
||||
# ============================================================
|
||||
|
||||
services:
|
||||
# ==================== PostgreSQL ====================
|
||||
postgres:
|
||||
image: postgres:16-alpine
|
||||
container_name: qingye-postgres
|
||||
restart: always
|
||||
environment:
|
||||
POSTGRES_DB: ${POSTGRES_DB:-qingye}
|
||||
POSTGRES_USER: ${POSTGRES_USER:-qingye}
|
||||
# 密钥必填:缺失时 compose 会直接报错,绝不回退到弱口令
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?请在 .env.prod 中设置 POSTGRES_PASSWORD}
|
||||
volumes:
|
||||
- pgdata:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-qingye} -d ${POSTGRES_DB:-qingye}"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
networks:
|
||||
- qingye-network
|
||||
# 生产环境不向宿主机映射 5432 端口(安全)
|
||||
|
||||
# ==================== Redis ====================
|
||||
# Redis 非可选:flash_service 原子计数 / draft_service 草稿等依赖它
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
container_name: qingye-redis
|
||||
restart: always
|
||||
command: redis-server --appendonly yes
|
||||
volumes:
|
||||
- redisdata:/data
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "ping"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
networks:
|
||||
- qingye-network
|
||||
# 生产环境不向宿主机映射 6379 端口(安全)
|
||||
|
||||
# ==================== Backend (FastAPI) ====================
|
||||
backend:
|
||||
build:
|
||||
context: ./backend
|
||||
dockerfile: Dockerfile.prod
|
||||
container_name: qingye-backend
|
||||
restart: always
|
||||
ports:
|
||||
- "127.0.0.1:8000:8000" # 仅本机可达,由宿主机 Nginx 反向代理
|
||||
environment:
|
||||
# DATABASE_URL 由上面的 POSTGRES_* 变量自动拼接,保持口令一致
|
||||
DATABASE_URL: postgresql+asyncpg://${POSTGRES_USER:-qingye}:${POSTGRES_PASSWORD:?请在 .env.prod 中设置 POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-qingye}
|
||||
REDIS_URL: redis://redis:6379/0
|
||||
JWT_SECRET_KEY: ${JWT_SECRET_KEY:?请在 .env.prod 中设置 JWT_SECRET_KEY}
|
||||
JWT_REFRESH_SECRET_KEY: ${JWT_REFRESH_SECRET_KEY:?请在 .env.prod 中设置 JWT_REFRESH_SECRET_KEY}
|
||||
CORS_ORIGINS: ${CORS_ORIGINS:-https://www.e4s.world}
|
||||
ADMIN_PASSWORD: ${ADMIN_PASSWORD:?请在 .env.prod 中设置 ADMIN_PASSWORD}
|
||||
APP_ENV: production
|
||||
volumes:
|
||||
- upload_data:/app/uploads # 仅持久化用户上传文件,不挂载源码(运行镜像内已打包的代码)
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- qingye-network
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
|
||||
# ==================== Frontend (Vue 3 构建产物 + Nginx) ====================
|
||||
frontend:
|
||||
build:
|
||||
context: ./frontend
|
||||
dockerfile: Dockerfile.prod
|
||||
# 生产构建为「域名无关」:不传入任何 VITE_* 变量,
|
||||
# 前端代码会自动使用页面同源地址(/api/v1 与 wss://当前域名)。
|
||||
container_name: qingye-frontend
|
||||
restart: always
|
||||
ports:
|
||||
- "127.0.0.1:8080:80" # 仅本机可达,由宿主机 Nginx 反向代理
|
||||
depends_on:
|
||||
- backend
|
||||
networks:
|
||||
- qingye-network
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
|
||||
# ==================== 数据卷 ====================
|
||||
volumes:
|
||||
pgdata:
|
||||
redisdata:
|
||||
upload_data:
|
||||
|
||||
# ==================== 网络 ====================
|
||||
networks:
|
||||
qingye-network:
|
||||
driver: bridge
|
||||
Reference in New Issue
Block a user