# ChatOne Service Docker 部署(Compose) 本文提供单机 Docker Compose 部署方案,包含 `app`(数据库与 Redis 使用远程实例)。 域名、HTTPS、反向代理统一在宿主机 Nginx 处理。 ## 1. 文件位置 - `deploy/docker/Dockerfile` - `deploy/docker/app.entrypoint.sh` - `deploy/docker/ecosystem.config.cjs` - `deploy/docker/docker-compose.yml` - `deploy/docker/.env.example` ## 2. 初始化 ```bash cd deploy/docker cp .env.example .env ``` 修改 `.env` 中所有密钥与密码,至少包括: - `JWT_ACCESS_SECRET` - `JWT_REFRESH_SECRET` - `QWEN_API_KEY`(如使用) - `DATABASE_URL` - `REDIS_PASSWORD` - `IMAGE_REPO` - `IMAGE_TAG` 请将 `DATABASE_URL`、`REDIS_HOST`、`REDIS_PASSWORD` 替换为远程实例配置。 镜像发布模式说明: - CI 负责构建并推送 `${IMAGE_REPO}:${IMAGE_TAG}` - 目标服务器仅执行 `docker compose pull + up` 端口统一约定: - `PORT`:容器内应用监听端口 - `HOST_BIND_PORT`:宿主机绑定端口(供宿主机 Nginx 反代) ## 3. 启动 在项目根目录执行: ```bash docker compose -f deploy/docker/docker-compose.yml --env-file deploy/docker/.env up -d --build ``` 查看状态: ```bash docker compose -f deploy/docker/docker-compose.yml ps docker compose -f deploy/docker/docker-compose.yml logs -f app ``` ## 4. 验证 ```bash curl -i http://127.0.0.1:${HOST_BIND_PORT}/api/docs ``` SSE 冒烟: - `POST /api/client/v1/chat/completions/stream` ## 5. 发布升级 拉取新代码后执行: ```bash docker compose -f deploy/docker/docker-compose.yml --env-file deploy/docker/.env up -d --build app ``` 数据库迁移会在 `app` 容器启动时自动执行(`npx prisma migrate deploy`)。 应用进程由容器内 `pm2-runtime` 管理。 ## 6. 回滚 推荐在发布前打镜像标签,例如: ```bash docker build -f deploy/docker/Dockerfile -t chat-one-service:20260426 . ``` 回滚时将 compose 中 `app.image` 改为旧标签,然后: ```bash docker compose -f deploy/docker/docker-compose.yml --env-file deploy/docker/.env up -d app ``` ## 7. 生产建议 - 不要把 `.env` 提交到仓库。 - `app` 仅监听本机 `127.0.0.1:${HOST_BIND_PORT}`,由宿主机 Nginx 反向代理。 - PostgreSQL/Redis 建议使用托管或远程实例,并通过白名单限制访问来源。 - HTTPS 由宿主机 Nginx 统一终止,保留 SSE 反代配置(`proxy_buffering off`、长超时)。 - 定时备份 Postgres: - `pg_dump` 每日一次,保留 7-14 天并异地存储。 ## 8. 宿主机 Nginx 配置示例 将域名流量转发到本机 `127.0.0.1:${HOST_BIND_PORT}`(容器 app 端口),并确保 SSE 可用。 ### 8.1 HTTP 示例 ```nginx server { listen 80; server_name api.your-domain.com; client_max_body_size 20m; location / { proxy_pass http://127.0.0.1:${HOST_BIND_PORT}; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # SSE support proxy_buffering off; proxy_cache off; proxy_read_timeout 3600; proxy_send_timeout 3600; chunked_transfer_encoding off; } } ``` ### 8.2 HTTPS 示例(推荐) ```nginx server { listen 443 ssl http2; server_name api.your-domain.com; ssl_certificate /etc/letsencrypt/live/api.your-domain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/api.your-domain.com/privkey.pem; client_max_body_size 20m; location / { proxy_pass http://127.0.0.1:${HOST_BIND_PORT}; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_buffering off; proxy_cache off; proxy_read_timeout 3600; proxy_send_timeout 3600; chunked_transfer_encoding off; } } ``` 应用配置后执行: ```bash sudo nginx -t && sudo systemctl reload nginx ```