Files
zl-q 91c089a894 fix: resolve legal/about pages in production, update deploy docs
- Fix markdown file path resolution for SSR production builds
- Try multiple paths (public/legal, client/legal) for dev and prod
- Update deploy/README.md with frontend deployment instructions
- Document PM2, Nginx configuration, and port mapping
2026-05-11 19:09:35 +08:00

324 lines
7.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 觅爻生产部署指南
## 目录说明
`deploy/` 用于存放生产环境启动所需文件:
- `docker-compose.prod.yml`:生产 Docker Compose 启动配置,只拉取已有镜像,不负责构建。
- `.env`:生产环境变量文件,本文件包含敏感信息,不应提交到 Git。
## 前置条件
生产机器需要安装:
- Docker
- Docker Compose v2
- AWS CLI v2
- Node.js 22+ (前端 SSR 服务)
- PM2 (前端进程管理)
确认命令:
```bash
docker --version
docker compose version
aws --version
node --version # 需要 >= 22.12.0
pm2 --version
```
## 服务架构
生产环境运行以下服务:
| 服务 | 端口 | 说明 |
|------|------|------|
| Nginx | 80, 443 | 反向代理,SSL 终结 |
| 前端 SSR | 4322 | Node.js + Astro SSR |
| 后端 API | 5775 | Docker 容器 |
| Redis | 6379 | Docker 容器 |
| Worker Agent | - | Docker 容器 |
### 端口映射
```
Internet → Nginx (443)
├── /_astro/* → 静态文件 (client 目录)
├── /images/* → 静态文件 (client 目录)
└── /* → 反向代理到 localhost:4322 (前端 SSR)
前端 SSR (4322) → /api/* → 反向代理到 localhost:5775 (后端 API)
```
## 环境变量
`docker-compose.prod.yml` 默认从当前目录读取 `.env`
```bash
deploy/.env
```
必须包含 AWS ECR 镜像定位变量:
```text
AWS_ACCOUNT_ID=<你的 AWS 账号 ID>
AWS_REGION=<ECR 所在区域>
ECR_REPOSITORY=<ECR 仓库名>
```
如果本目录下的 `.env` 是从项目根目录 `.env` 复制过来的,通常还需要手动追加以上三个变量。
默认镜像地址会拼接为:
```text
${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${ECR_REPOSITORY}:latest
```
如果要手动指定完整镜像地址,可以在 `.env` 中设置:
```text
ERYAO_BACKEND_IMAGE=<完整镜像地址>
```
Web 服务端口使用项目环境变量:
```text
ERYAO_WEB__PORT=5775
```
默认只绑定本机回环地址:
```text
ERYAO_DEPLOY_BIND_HOST=127.0.0.1
```
如果生产机器没有 Nginx、ALB 或其他反向代理,需要直接对外暴露端口,可改为:
```text
ERYAO_DEPLOY_BIND_HOST=0.0.0.0
```
### 进程配置建议
生产 Compose 只启动一个 `worker-agent` 容器。Agent 任务、低频通用任务和反馈日报任务共用 `agent` 队列,不再单独常驻 `worker-general` 进程。
2 核 2G 机器建议使用:
```text
ERYAO_WEB__WORKERS=1
ERYAO_WORKER__GROUPS__AGENT__CONCURRENCY=2
```
4G 以上机器可按流量提高 Web 或 Agent worker 数量:
```text
ERYAO_WEB__WORKERS=2
ERYAO_WORKER__GROUPS__AGENT__CONCURRENCY=2
```
## 登录 ECR
进入部署目录,并把 `.env` 加载到当前 shell
```bash
cd deploy
set -a
. ./.env
set +a
```
在生产机器上配置好 AWS 凭据后执行:
```bash
aws ecr get-login-password --region "$AWS_REGION" \
| docker login --username AWS --password-stdin \
"${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com"
```
## 启动服务
启动 Web、Redis 和 worker
```bash
cd deploy
docker compose --env-file ./.env -f docker-compose.prod.yml --profile workers pull
docker compose --env-file ./.env -f docker-compose.prod.yml --profile workers up -d
```
只启动 Web 和 Redis
```bash
cd deploy
docker compose --env-file ./.env -f docker-compose.prod.yml up -d
```
## 健康检查
如果 `ERYAO_WEB__PORT=5775`
```bash
curl http://127.0.0.1:5775/health
```
期望返回:
```json
{"status":"ok"}
```
## 查看状态和日志
```bash
cd deploy
docker compose --env-file ./.env -f docker-compose.prod.yml --profile workers ps
docker logs -f eryao-prod-backend
docker logs -f eryao-prod-worker-agent
docker logs -f eryao-prod-redis
```
## 更新版本
当前 CI/CD 会在 `main` 分支构建后自动部署到生产机器:
- 推送前清空 ECR 仓库旧镜像,只保留新推送的 `latest`
- 通过 `DEPLOY_SSH_KEY` 登录生产机器。
- 在生产机器执行 ECR 登录、`docker compose pull``docker compose up -d`
- 健康检查通过后清理 7 天前未使用的本地 Docker 镜像。
Gitea Secrets 需要包含:
```text
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
AWS_REGION
AWS_ACCOUNT_ID
ECR_REPOSITORY
DEPLOY_SSH_KEY
DEPLOY_HOST
DEPLOY_USER
```
`DEPLOY_SSH_KEY` 是已加入生产机器 `ubuntu` 用户 `~/.ssh/authorized_keys` 的部署专用私钥。
当前生产机器对应:`DEPLOY_HOST=18.218.38.213``DEPLOY_USER=ubuntu`
CI 的 AWS 用户需要至少允许 ECR 登录、建仓库、推送镜像、列出镜像,以及为了覆盖式清理旧镜像所需的 `ecr:BatchDeleteImage`。如果缺少 `ecr:BatchDeleteImage`,部署仍可继续推送 `latest`,但 ECR 旧镜像不会被清空。
如需手动更新,在生产机器执行:
```bash
cd deploy
docker compose --env-file ./.env -f docker-compose.prod.yml --profile workers pull
docker compose --env-file ./.env -f docker-compose.prod.yml --profile workers up -d
```
## 停止服务
```bash
cd deploy
docker compose --env-file ./.env -f docker-compose.prod.yml --profile workers down
```
如需连 Redis 数据卷一起删除:
```bash
cd deploy
docker compose --env-file ./.env -f docker-compose.prod.yml --profile workers down -v
```
谨慎使用 `down -v`,它会删除 Redis 持久化数据。
## 前端部署
### 构建前端
在本地开发机器上:
```bash
cd web
PUBLIC_API_URL=https://api.meeyao.com npm run build
```
构建产物在 `web/dist/` 目录:
- `dist/client/` - 静态资源 (CSS, JS, 图片)
- `dist/server/` - SSR 服务端代码
### 上传到服务器
```bash
# 上传构建产物
rsync -avz -e "ssh -i xunmee.pem" web/dist/ ubuntu@18.218.38.213:/home/ubuntu/deploy/web/
# 上传依赖配置
rsync -avz -e "ssh -i xunmee.pem" web/package.json web/package-lock.json ubuntu@18.218.38.213:/home/ubuntu/deploy/web/
# 安装生产依赖
ssh -i xunmee.pem ubuntu@18.218.38.213 "cd /home/ubuntu/deploy/web && npm install --omit=dev"
```
### PM2 管理
```bash
# 启动服务
pm2 start server/entry.mjs --name meeyao-web
# 设置端口 (默认 4321,需要改为 4322)
export HOST=0.0.0.0
export PORT=4322
pm2 restart meeyao-web
# 保存进程列表 (开机自启)
pm2 save
# 查看状态
pm2 status
# 查看日志
pm2 logs meeyao-web
```
### Nginx 配置
前端 SSR 服务监听 `localhost:4322`Nginx 配置要点:
```nginx
server {
listen 443 ssl http2;
server_name meeyao.com;
# 静态资源直接从 client 目录提供
location /_astro {
root /home/ubuntu/deploy/web/client;
expires 30d;
add_header Cache-Control "public, immutable";
}
location /images {
root /home/ubuntu/deploy/web/client;
expires 30d;
}
# 其他请求代理到 Node.js SSR
location / {
proxy_pass http://127.0.0.1:4322;
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;
}
}
```
### 前端更新流程
```bash
# 1. 本地构建
cd web && PUBLIC_API_URL=https://api.meeyao.com npm run build
# 2. 上传
rsync -avz -e "ssh -i xunmee.pem" dist/ ubuntu@18.218.38.213:/home/ubuntu/deploy/web/
# 3. 重启服务
ssh -i xunmee.pem ubuntu@18.218.38.213 "pm2 restart meeyao-web"
```