Files
thebet365/docs/Docker部署指南.md
2026-06-13 22:16:14 +08:00

339 lines
10 KiB
Markdown
Raw 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.
# TheBet365 Docker 全栈部署指南
本文档说明如何使用 Docker **一键部署** API、玩家前台、管理后台、PostgreSQL 与 Redis。
> 本地开发仍可使用根目录 `docker-compose.yml` 仅启动数据库,应用在本机 `pnpm dev` 运行。
---
## 一、架构
```text
浏览器
└─ 宝塔/Nginx HTTPS 反代
├─ 127.0.0.1:8082 player (Nginx) ── /api、/uploads ──► api (NestJS :3000)
└─ 127.0.0.1:8081 admin (Nginx) ── /api、/uploads ──► api (NestJS :3000)
api ──► postgres:5432
└──► redis:6379
```
| 容器 | 默认端口 | 说明 |
|------|----------|------|
| `thebet365-player` | 127.0.0.1:8082 | 玩家 H5 前台 |
| `thebet365-admin` | 127.0.0.1:8081 | 管理后台(平台 + 代理) |
| `thebet365-api` | 不对外暴露 | NestJS API / Swagger / 健康检查 |
| `thebet365-postgres` | 不对外暴露 | PostgreSQL 16 |
| `thebet365-redis` | 不对外暴露 | Redis 7 |
---
## 二、服务器要求
| 项目 | 要求 |
|------|------|
| 系统 | Linux推荐 Ubuntu 22.04+ |
| Docker | 24+ |
| Docker Compose | v2`docker compose` |
| 内存 | 建议 ≥ 2 GB首次构建需更多 |
| 磁盘 | 建议 ≥ 10 GB |
宝塔面板:左侧 **Docker** → 确认 Docker 服务已安装并运行。
---
## 三、首次部署(命令行)
### 1. 上传代码
将项目放到服务器,例如 `/www/wwwroot/thebet365`(宝塔 **文件** 上传或 `git clone`)。
### 2. 配置环境变量
```bash
cd /www/wwwroot/thebet365
cp .env.docker.example .env.docker
```
**生产环境务必修改:**
- `POSTGRES_PASSWORD` — 数据库密码
- `JWT_SECRET` — 足够长的随机字符串
- `IMAGE_TAG=latest` — 首次部署可保留;后续用 `--tag` 发布时脚本会写回真实版本
- `BIND_ADDR=127.0.0.1` — 默认只允许宝塔本机反代访问 player/admin 端口
- `RUN_MIGRATIONS_ON_START=false` — 迁移由部署脚本执行API 容器启动时不重复跑迁移
- `BACKUP_RETENTION_DAYS=` — 留空表示不自动清理备份;填数字时脚本会清理更旧备份
- `SEED_DATABASE=false` — 保持默认即可;首次部署脚本会在没有 `admin` 时一次性执行生产 seed
### 3. 首次部署
```bash
chmod +x scripts/*.sh
./scripts/deploy-first.sh
```
脚本会执行:
- 启动 PostgreSQL / Redis
- 构建 API、玩家端、管理端镜像
- 执行 `prisma migrate deploy`
- 启动全栈容器
- 如果数据库中没有 `admin`,执行一次生产 seed
如果服务器已经提前 `docker load` 了镜像,不想在服务器构建:
```bash
./scripts/deploy-first.sh --no-build
```
如果上传的是版本化镜像包,可让脚本自动加载镜像并记录发布 tag
```bash
./scripts/deploy-first.sh --images thebet365-images-v1.2.3.tar --tag v1.2.3
```
镜像包文件名符合 `thebet365-images-<tag>.tar` 时,脚本也会自动推断 tag显式传 `--tag` 更清晰。
如需全量初始化生产数据(会清空业务表,仅限全新库或明确重置):
```bash
./scripts/deploy-first.sh --init-db
```
### 4. 查看状态
```bash
docker compose -f docker-compose.prod.yml --env-file .env.docker ps
docker compose -f docker-compose.prod.yml --env-file .env.docker logs -f api
```
启动成功后访问:
| 服务 | 地址 |
|------|------|
| 玩家前台 | 宝塔绑定的玩家域名,或服务器本机 `http://127.0.0.1:8082` |
| 管理后台 | 宝塔绑定的管理域名,或服务器本机 `http://127.0.0.1:8081` |
API 只在 Docker 网络内暴露,前端容器通过 `/api` 代理到 API。player/admin 默认只绑定 `127.0.0.1`,外层域名和 HTTPS 由宝塔网站反代处理。临时需要公网 IP 直连时,才在 `.env.docker` 中设置 `BIND_ADDR=0.0.0.0`
---
## 四、宝塔面板操作
### 方式 A容器编排推荐
1. **文件** — 上传/克隆项目到 `/www/wwwroot/thebet365`
2. **终端** — 执行 `cp .env.docker.example .env.docker` 并编辑密钥
3. **Docker****容器编排****添加**
- 编排文件:选择 `docker-compose.prod.yml`
- 环境文件:选择 `.env.docker`(若面板支持)
4. **构建并启动**
若面板不支持指定 env 文件,在 **终端** 中执行第三节第 3 步脚本即可。
### 方式 B绑定域名Nginx 反代)
在宝塔 **网站** 中为玩家站、管理站分别建站,**不**使用 PHP只做反向代理
**玩家站**(根目录可留空或任意):
```nginx
location / {
proxy_pass http://127.0.0.1:8082;
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;
}
```
**管理站** — 将 `8082` 改为 `8081`
API 端口 3000 不在生产 compose 中公网映射Swagger 如需临时查看,建议只在内网或通过 VPN 暴露。
---
## 五、默认账号
生产 seed 仅创建平台管理员与基础赛事/内容数据,不创建代理/玩家演示账号;详见 [默认数据说明.md](./默认数据说明.md)。
| 角色 | 用户名 | 密码 | 入口 |
|------|--------|------|------|
| 平台管理员 | admin | Admin@123 | 管理后台 :8081 |
---
## 六、常用命令
```bash
# 停止
docker compose -f docker-compose.prod.yml --env-file .env.docker down
# 停止并删除数据卷(清空数据库,慎用)
docker compose -f docker-compose.prod.yml --env-file .env.docker down -v
# 仅重建 API
docker compose -f docker-compose.prod.yml --env-file .env.docker up -d --build api
# 手动备份数据库
./scripts/backup-db.sh
# 完整生产备份:数据库 + uploads
./scripts/backup-prod.sh --prefix pre-release
# 全量初始化(生产上线:仅 admin + WC2026 赛事,会先备份到 ./backups/
CONFIRM=YES ./scripts/prod-init-db.sh
# Windows PowerShell:
# $env:CONFIRM = "YES"; .\scripts\prod-init-db.ps1
# 查看 API 日志
docker compose -f docker-compose.prod.yml --env-file .env.docker logs -f api
# 回滚应用镜像到指定 tag不自动回滚数据库
./scripts/rollback.sh --to v1.2.2
```
根目录 `package.json` 快捷脚本(需已存在 `.env.docker`
```bash
pnpm docker:up
pnpm docker:down
pnpm docker:logs
pnpm docker:ps
```
---
## 七、数据持久化
| 卷名 | 内容 |
|------|------|
| `postgres_data` | 数据库 |
| `redis_data` | Redis |
| `uploads_data` | Banner、充值截图、支付二维码等用户上传文件 |
备份示例:
```bash
# 仅数据库:生成 backups/thebet365-db-*.sql.gz 和 .sha256
./scripts/backup-db.sh
# 数据库 + uploads生成 .sql.gz、.tar.gz 和对应 .sha256
./scripts/backup-prod.sh --prefix manual
```
`BACKUP_RETENTION_DAYS` 留空时不自动删除历史备份;设置为数字时,部署和备份脚本会清理更早的备份文件。
---
## 八、后续更新部署
**推荐:先删旧代码再解压新 zip**(避免 `packages/shared/public/球员` 等中文目录残留导致 Vite 构建失败)。
推荐主流程是:本地或构建机生成版本化镜像包 → 上传 tar 与 manifest → 服务器执行 `deploy-update.sh --images ... --tag ...`。详细步骤见:[docker/镜像构建与导出.md](./docker/镜像构建与导出.md)(脚本位于 `docs/docker/build-and-export-images.ps1` / `build-and-export-images.sh`)。
### 方式 A服务器直接拉代码并构建
```bash
cd /www/wwwroot/thebet365
./scripts/deploy-update.sh --pull
```
### 方式 B上传 zip 后在服务器构建
保留原来的 `.env.docker`,替换代码后执行:
```bash
cd /www/wwwroot/thebet365
./scripts/deploy-update.sh
```
### 方式 C上传已构建镜像包
```bash
cd /www/wwwroot/thebet365
./scripts/deploy-update.sh --images thebet365-images-v1.2.3.tar --tag v1.2.3
```
更新脚本默认会:
- 先备份 PostgreSQL 与 uploads 到 `./backups/`,并生成 `.sha256`
- 构建或加载指定 tag 的新镜像
- 使用新 API 镜像执行 `prisma migrate deploy`
- 启动/替换 API、玩家端、管理端容器
- 等待 API、玩家端、管理端健康检查通过
- 执行 `prisma migrate status` 检查数据库迁移状态
- 将当前发布写入 `.deploy/current-release.env`,并保留上一次发布到 `.deploy/previous-release.env`
除非已经手工确认有其他备份,否则不要使用 `--no-backup`
### 回滚应用镜像
```bash
cd /www/wwwroot/thebet365
./scripts/rollback.sh --to v1.2.2
```
回滚脚本只切换 `api` / `player` / `admin` 镜像 tag不自动恢复数据库。若新版本包含不可逆迁移或已写入不兼容数据需要先按 `backups/` 中的 `.sql.gz` 备份手工恢复 PostgreSQL再执行镜像回滚。
---
## 九、故障排查
### 1. API 一直重启
```bash
docker logs thebet365-api
```
常见原因:数据库未就绪(稍等重试)、`DATABASE_URL` 密码与 `POSTGRES_PASSWORD` 不一致、`/api/health/ready` 检查 DB/Redis 失败。
### 2. 前端 502 / 接口失败
确认 `thebet365-api` 为 healthy且 player/admin 容器能解析主机名 `api`(同一 compose 网络)。
```bash
docker compose -f docker-compose.prod.yml --env-file .env.docker ps
docker compose -f docker-compose.prod.yml --env-file .env.docker logs --tail=120 api
```
### 3. player/admin 端口无法从公网 IP 直连
生产默认只绑定 `127.0.0.1`,需要通过宝塔网站反代访问。临时调试公网 IP 直连时,在 `.env.docker` 中设置:
```bash
BIND_ADDR=0.0.0.0
```
然后重新执行部署脚本。
### 4. 构建慢或内存不足
首次 `docker compose build` 会安装 pnpm 依赖并编译三端,建议服务器 ≥ 2 GB 内存;可在低峰期构建。
### 5. 端口被占用
修改 `.env.docker` 中的 `PLAYER_PORT` / `ADMIN_PORT` 后重新部署。API 不对公网映射端口。
### 6. player/admin 构建报错 `ENOENT ... packages/shared/public/球员`
旧版中文目录 `球员` 在 Linux 上编码异常。确认已使用含 `packages/shared/public/players/` 的新代码包,并:
```bash
find packages/shared/public -mindepth 1 -maxdepth 1 -type d \
! -name flags ! -name players -exec rm -rf {} +
docker compose -f docker-compose.prod.yml --env-file .env.docker build --no-cache player admin
```
---
## 十、与本地开发的区别
| 场景 | 命令 |
|------|------|
| 本地开发(仅 DB 用 Docker | `docker compose up -d` + `pnpm dev` |
| 生产首次部署 | `./scripts/deploy-first.sh` |
| 生产后续更新 | `./scripts/deploy-update.sh` |
相关文档:[项目启动指南.md](./项目启动指南.md)