docs: 拆分 README.md 为多个子文档,README 简化为架构引导大纲

This commit is contained in:
2026-04-14 12:23:31 +08:00
parent 7758930a01
commit f98091bb54
9 changed files with 1459 additions and 1636 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,249 @@
# 快速部署指南
> 首次将 YouleGames Docker 版部署到服务器的完整步骤。
---
## 前置要求
- Linux 服务器(推荐 Ubuntu 22.04 / CentOS 8+,最低 2C 2G
- 域名已解析到服务器 IP3 个域名API / DLWEB / wxserver
- 服务器 80 和 443 端口可用
- Docker 和 Docker Compose如未安装`deploy.sh` 会自动安装并配置国内镜像加速)
---
## 步骤 0配置 SSH 密钥认证(必须)
`sync.ps1` 每次执行会调用多次 `scp` / `ssh`,如果未配置密钥认证,每条命令都会弹出密码提示导致脚本中断。以下步骤在 **Windows PowerShell** 中完成Windows 10/11 内置 OpenSSH 客户端,无需额外安装)。
### 第一步:检查是否已有 SSH 密钥
```powershell
# 默认密钥路径
Test-Path "$env:USERPROFILE\.ssh\id_ed25519"
# 输出 True 表示已有密钥,可跳到第三步
```
如果已有 RSA 旧密钥(`id_rsa`),同样可用,把下面命令中的 `id_ed25519` 替换为 `id_rsa`
### 第二步:生成密钥对
```powershell
# 生成 Ed25519 密钥(更安全、更短)
ssh-keygen -t ed25519 -C "youle-deploy" -f "$env:USERPROFILE\.ssh\id_ed25519"
# 提示 passphrase 时直接回车两次(不设密码,脚本才能自动运行)
```
执行后生成两个文件:
| 文件 | 说明 |
|------|------|
| `~/.ssh/id_ed25519` | **私钥**,绝不上传服务器,本地保管 |
| `~/.ssh/id_ed25519.pub` | **公钥**,要发给服务器 |
### 第三步:将公钥上传到服务器
> 此步骤会要求输入一次密码,之后不再需要。
```powershell
# 一行命令:读取公钥 → 追加到服务器 authorized_keys
cat "$env:USERPROFILE\.ssh\id_ed25519.pub" | ssh root@47.98.203.17 `
"mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys"
```
### 第四步:验证免密登录
```powershell
# 直接登录,不弹密码提示则成功
ssh root@47.98.203.17 "echo 'SSH key auth OK'"
```
输出 `SSH key auth OK` 即表示配置成功,`sync.ps1` 可正常使用。
### 可选:配置 SSH 别名(简化命令)
`C:\Users\<你的用户名>\.ssh\config`(文件不存在则新建)中添加:
```
Host youle
HostName 47.98.203.17
User root
IdentityFile ~/.ssh/id_ed25519
ServerAliveInterval 60
```
配置后可使用短名称操作:
```powershell
ssh youle # 直接登录
# sync.ps1 使用别名
.\sync.ps1 -Server youle
```
### 可选:多台电脑共用同一台服务器
把每台电脑生成的 `id_ed25519.pub` 内容都追加到服务器的 `~/.ssh/authorized_keys`(一行一个),不需要删除旧的公钥:
```powershell
# 在第二台电脑上执行同样的上传命令即可(>> 追加而不是覆盖)
cat "$env:USERPROFILE\.ssh\id_ed25519.pub" | ssh root@47.98.203.17 `
"cat >> ~/.ssh/authorized_keys"
```
---
## 步骤 1检查并修复行尾符LF
> **为什么需要这步?** Windows 的 Git 默认 `core.autocrlf=true`,可能将脚本文件写成 CRLF。CRLF 格式的 shell 脚本在 Linux 容器中会报 `not found` / `syntax error` 错误,导致容器无法启动。
在上传前运行 `fix-lf.ps1`,自动扫描所有关键文件并修复:
```powershell
.\fix-lf.ps1
```
> **根本修复(一次性,之后无需再跑):** 执行以下命令让 `.gitattributes` 永久接管行尾符,此后任何机器 clone 均自动生效:
> ```powershell
> git config core.autocrlf false
> git add --renormalize .
> git commit -m "fix: normalize all line endings to LF"
> git push
> ```
---
## 步骤 2上传项目到服务器
`game-docker` 目录上传到服务器 `/opt/youle/` 下:
```powershell
# 推荐:使用 sync.ps1tar 压缩单连接,比 scp -r 快约 10-50 倍)
# 首次部署用 full 模式,上传全部文件(约 10 MB 压缩包)
.\sync.ps1 -Mode full
# 日常代码更新用 app 模式(排除文档/测试,约 7 MB
.\sync.ps1
# 仅更新 Docker 配置文件docker-compose.yml、deploy.sh 等,不到 1 MB
.\sync.ps1 -Mode config
```
> **前提:** 已完成步骤 0 的 SSH 密钥认证配置,否则 `sync.ps1` 会反复弹密码提示。
`sync.ps1` 会自动在服务器上创建 `/opt/youle/game-docker/` 目录(如不存在)。
如不使用 `sync.ps1`,也可手动上传:
```bash
# 从 Git 仓库拉取
ssh root@your-server-ip
mkdir -p /opt/youle
cd /opt/youle
git clone <仓库地址> game-docker
```
上传后服务器上的目录结构:
```
/opt/youle/game-docker/
├── .env.example
├── docker-compose.yml
├── deploy.sh
├── init-ssl.sh
├── api/
├── dlweb/
├── wxserver_daoqi/
└── docker/
```
---
## 步骤 3准备环境变量
```bash
cd /opt/youle/game-docker
cp .env.example .env
vim .env
```
**必须修改的关键配置:**
```bash
# 父域名(三个子域名自动推导,无需单独配置)
# 将自动生成: api.<ROOT_DOMAIN> dlapi.<ROOT_DOMAIN>
ROOT_DOMAIN=yourdomain.com
# 数据库(各服务数据库连接)
API_DB_HOST=your-rds-host
API_DB_PASSWORD=your-password
DLWEB_DB_HOST=your-rds-host
DLWEB_DB_PASSWORD=your-password
# ... 其他数据库配置
# 微信配置
WX_MINI_APPID=your-appid
WX_MINI_APPSECRET=your-secret
WX_PAY_MCHID=your-mchid
WX_PAY_KEY=your-key
# SSL 邮箱
SSL_EMAIL=your-email@example.com
```
> 完整变量说明见 [环境变量配置](./03-env-variables.md)。
---
## 步骤 4首次申请 SSL 证书
```bash
chmod +x deploy.sh init-ssl.sh
# 先测试(不真正申请,验证域名解析是否正确)
./deploy.sh ssl-init --dry-run
# 正式申请
./deploy.sh ssl-init
```
> SSL 证书详细管理见 [SSL 证书管理](./04-ssl.md)。
---
## 步骤 5启动所有服务
```bash
./deploy.sh up
```
启动后验证:
```bash
# 查看所有容器状态
./deploy.sh status
# 查看特定服务日志
./deploy.sh logs api
./deploy.sh logs dlweb
./deploy.sh logs syncjob
./deploy.sh logs cronjob
```
---
## 步骤 6部署命令速查
| 命令 | 说明 |
|------|------|
| `./deploy.sh up` | 构建并启动所有服务 |
| `./deploy.sh down` | 停止并移除所有容器 |
| `./deploy.sh restart` | 重启所有服务 |
| `./deploy.sh rebuild` | 无缓存重建所有镜像 |
| `./deploy.sh rebuild api` | 只重建指定服务 |
| `./deploy.sh logs [service]` | 查看日志(支持 `-f` 实时跟踪) |
| `./deploy.sh status` | 查看容器运行状态 |
| `./deploy.sh ssl-init` | 首次申请 SSL 证书 |
| `./deploy.sh ssl-init --staging` | 用 Let's Encrypt 测试环境申请 |
| `./deploy.sh ssl-renew` | 手动续签证书 |
| `./deploy.sh ssl-status` | 查看证书到期时间 |

View File

@@ -0,0 +1,110 @@
# 定时任务说明
Docker 部署包含两个定时任务容器,替代原 Windows 环境的 `HttpRequestService.exe``autorun.cmd`
---
## syncjob — 实时同步任务
**替代:** Windows `HttpRequestService.exe`(通过 `HttpRequest.exe.json` 配置)
**作用:** 每 30 秒 POST 请求 `dlweb/ext/Synchronize.php`,从游戏数据库 `ct_user_process_log` 表消费未处理日志,将玩家/代理数据同步到代理后台数据库。
**运行方式:** 通过 Docker 内网直连 `http://dlweb/ext/Synchronize.php`,不经过公网域名,零流量消耗。
### 可配置项(`.env`
```bash
# 轮询间隔(秒),默认 30
SYNC_INTERVAL=30
# 每次处理的日志条数,默认 200
SYNC_PROCESSCOUNT=200
```
### 查看同步日志
```bash
./deploy.sh logs syncjob
# 或实时查看
docker logs -f youle-syncjob
```
### 调整同步频率
```bash
# 修改 .env
SYNC_INTERVAL=15 # 15 秒一次
SYNC_PROCESSCOUNT=500 # 每次处理 500 条
# 重启 syncjob
docker compose restart syncjob
```
---
## cronjob — 每日定时任务
**替代:** Windows 计划任务调用的 `tools-docker/autorun.cmd`
**作用:** 每日凌晨 4:00 执行以下流程(与原 `autorun.cmd` 完全一致):
| 步骤 | 原 autorun.cmd | Docker cronjob |
|------|---------------|----------------|
| 1. 停止同步服务 | `net stop HttpRequestService` | 创建 `/shared/syncjob.pause` 信号文件 |
| 2. 等待当前请求完成 | Windows 服务立即停止) | `sleep 5` |
| 3. 同步报表数据 | `HttpRequest.exe POST SynchronizeReportData.php` | `curl POST http://dlweb/ext/SynchronizeReportData.php` |
| 4. 恢复同步服务 | `net start HttpRequestService` | 删除 `/shared/syncjob.pause` 信号文件 |
> **暂停机制:** `syncjob` 和 `cronjob` 通过共享 Docker volume`shared-signal`)通信。`cronjob` 创建 `/shared/syncjob.pause` 文件时,`syncjob` 会自动跳过轮询,报表同步完成后删除该文件恢复。
### 可配置项(`.env`
```bash
# cron 表达式,默认凌晨 4:00
CRON_SCHEDULE=0 4 * * *
```
**修改执行时间示例:**
```bash
# 凌晨 3:30 执行
CRON_SCHEDULE=30 3 * * *
# 每天凌晨 2:00 和 14:00 各执行一次
CRON_SCHEDULE=0 2,14 * * *
```
### 查看执行日志
```bash
./deploy.sh logs cronjob
# 或实时查看
docker logs -f youle-cronjob
```
### 手动触发(测试用)
```bash
docker exec youle-cronjob /bin/sh /app/daily-task.sh
```
### 调整每日任务执行时间
```bash
# 修改 .env
CRON_SCHEDULE=30 3 * * * # 改为凌晨 3:30
# 重启 cronjob
docker compose restart cronjob
```
---
## 临时停止定时任务(维护数据库时)
```bash
docker compose stop syncjob cronjob
# 维护完成后恢复
docker compose up -d syncjob cronjob
```

View File

@@ -0,0 +1,141 @@
# 环境变量配置
所有硬编码的域名、数据库地址、密钥都已外部化为环境变量。**修改配置不再需要改代码,只需改 `.env` 文件。**
---
## 变量分组总览
| 变量分组 | 说明 |
|---------|------|
| `API_DB_*` | 游戏核心 API 数据库 |
| `DLWEB_DB_*` | 代理后台主库 |
| `DLWEB_SLAVE_DB_*` | 代理后台从库 |
| `EXT_GAME_DB_*` | 外部游戏数据库Synchronize / SynchronizeReportData |
| `EXT_GRADE_DB_*` | 战绩数据库game.php |
| `EXT_DEV_DB_*` | 开发数据库DEBUG 模式) |
| `REDIS_*` | Redis 配置 |
| `WX_MINI_*` | 微信小程序 AppID / Secret |
| `WX_OA_*` | 微信公众号 AppID / Secret |
| `WX_PAY_*` | 微信支付商户配置 |
| `REMOTE_CONFIG_*` | 远程配置Gitee |
| `ROOT_DOMAIN` | 父域名(自动推导 3 个子域名 + 所有派生 URL |
| `SITE_*` | PHP 后端各站点域名 |
| `DLWEB_*_URL` | 前端 JS/HTML 硬编码域名替换 |
| `SYNC_INTERVAL` / `SYNC_PROCESSCOUNT` | syncjob 同步参数 |
| `CRON_SCHEDULE` | cronjob 执行时间 |
| `GAME_SERVER_QUERY_URL` | 游戏服务器查询地址 |
| `INTERNAL_WHITELIST` | IP 白名单(逗号分隔) |
---
## 域名配置关系
```
.env 配置 │ 自动推导结果
─────────────────────┼──────────────────────────────────────────────────────
ROOT_DOMAIN │ API_DOMAIN = api.<ROOT_DOMAIN> → Nginx 网站1含 wxserver /wx/ 路由)
(唯一必填) │ DLWEB_DOMAIN = dlapi.<ROOT_DOMAIN> → Nginx 网站2
│ SITE_API_URL = https://api.<ROOT_DOMAIN>
│ SITE_PAY_NOTIFY_URL = https://api.<ROOT_DOMAIN>
│ SITE_OPEN_URL = http://open.<ROOT_DOMAIN>
│ DLWEB_DL_API_V3_URL = https://dlapi.<ROOT_DOMAIN>
```
> 推导由 `docker-compose.yml` 的 `environment:` 块完成,容器内所有派生变量均无需手动配置。如子域名不符合 `<前缀>.<ROOT_DOMAIN>` 规律,可在 `.env` 中单独覆盖对应变量。
---
## 环境变量加载机制
### PHP 服务env_config.php
所有 PHP 文件通过 `env($key, $default)` 函数读取配置:
```php
// 优先读 OS 环境变量Docker 场景),回退读 .env 文件
$host = env('API_DB_HOST', 'localhost');
```
加载优先级Docker 容器环境变量(`docker-compose env_file`> `.env` 文件 > 代码默认值。
### Node.js 服务wxserver_daoqi
直接使用 `process.env.VARIABLE_NAME`,由 `docker-compose env_file` 注入。
### 前端 JS / HTML
前端静态文件无法读取环境变量,通过 Docker entrypoint 脚本在容器启动时用 `sed` 替换硬编码域名:
- `docker/api/docker-entrypoint.sh` — 替换 API 服务中的 JS 文件
- `docker/dlweb/docker-entrypoint.sh` — 替换 DLWEB 服务中的 30+ 个 JS/HTML 文件
### Nginx 域名注入
`default.conf.template` 使用 `${API_DOMAIN}` / `${DLWEB_DOMAIN}` 占位符Nginx 容器启动时通过 `envsubst` 自动替换。wxserver 不独立占用域名,通过 `api.xxx/wx/*` 路由接入。
---
## 文件修改与生效方式
不同文件在镜像中的处理方式不同,决定了改完代码后需要执行哪种操作。
### 文件 → 操作对照表
| 文件路径 | 所属容器 | 载入方式 | 修改后需要执行的操作 |
|---------|---------|---------|-------------------|
| `api/**` | `youle-api` | `COPY` 进镜像 | `./deploy.sh rebuild api` 重建镜像 |
| `dlweb/**` | `youle-dlweb` | `COPY` 进镜像 | `./deploy.sh rebuild dlweb` 重建镜像 |
| `wxserver_daoqi/**` | `youle-wxserver` | `COPY` 进镜像 | `./deploy.sh rebuild wxserver` 重建镜像 |
| `env_config.php` | `youle-api` / `youle-dlweb` | `COPY` 进镜像 | `./deploy.sh rebuild api dlweb` 重建两个镜像 |
| `docker/api/Dockerfile` | `youle-api` | 构建定义 | `./deploy.sh rebuild api` |
| `docker/api/docker-entrypoint.sh` | `youle-api` | `COPY` 进镜像 | `./deploy.sh rebuild api` |
| `docker/dlweb/Dockerfile` | `youle-dlweb` | 构建定义 | `./deploy.sh rebuild dlweb` |
| `docker/dlweb/docker-entrypoint.sh` | `youle-dlweb` | `COPY` 进镜像 | `./deploy.sh rebuild dlweb` |
| `docker/wxserver/Dockerfile` | `youle-wxserver` | 构建定义 | `./deploy.sh rebuild wxserver` |
| `docker/nginx/default.conf.template` | `youle-nginx` | volume 挂载(`:ro` | `scp` 上传 → `docker restart youle-nginx` |
| `docker/nginx/ssl-params.conf` | `youle-nginx` | volume 挂载(`:ro` | `scp` 上传 → `docker restart youle-nginx` |
| `docker/syncjob/sync.sh` | `youle-syncjob` | volume 挂载(`:ro` | `scp` 上传 → `docker restart youle-syncjob` |
| `docker/cronjob/entrypoint.sh` | `youle-cronjob` | volume 挂载(`:ro` | `scp` 上传 → `docker restart youle-cronjob` |
| `docker/cronjob/daily-task.sh` | `youle-cronjob` | volume 挂载(`:ro` | `scp` 上传 → `docker restart youle-cronjob` |
| `docker-compose.yml` | 所有容器 | compose 编排 | `docker compose up -d`(有变动的容器自动重建) |
| `.env` | 所有容器 | compose `env_file` | `docker compose up -d`(重新注入环境变量) |
> **COPY vs 挂载的区别:**
> - **`COPY` 进镜像** — 文件被打进 Docker 镜像层,修改后必须重新 build 才能生效
> - **volume 挂载** — 只需 `scp` 传到服务器后重启容器即可,**无需重建镜像**
### 操作命令速查
```bash
# ── 需要重建镜像的操作(修改源码/Dockerfile/entrypoint 等 COPY 文件)──
./deploy.sh rebuild api # 只重建 API
./deploy.sh rebuild dlweb # 只重建 DLWEB
./deploy.sh rebuild wxserver # 只重建 wxserver
./deploy.sh rebuild api dlweb # 同时重建多个
./deploy.sh rebuild # 重建所有服务
# ── 只需 scp + 重启的操作(修改 volume 挂载文件,秒级生效)──
# Nginx 配置
scp docker/nginx/ssl-params.conf root@47.98.203.17:/opt/youle/game-docker/docker/nginx/ssl-params.conf
scp docker/nginx/default.conf.template root@47.98.203.17:/opt/youle/game-docker/docker/nginx/default.conf.template
ssh root@47.98.203.17 "docker restart youle-nginx"
# syncjob 脚本
scp docker/syncjob/sync.sh root@47.98.203.17:/opt/youle/game-docker/docker/syncjob/sync.sh
ssh root@47.98.203.17 "docker restart youle-syncjob"
# cronjob 脚本
scp docker/cronjob/entrypoint.sh root@47.98.203.17:/opt/youle/game-docker/docker/cronjob/entrypoint.sh
scp docker/cronjob/daily-task.sh root@47.98.203.17:/opt/youle/game-docker/docker/cronjob/daily-task.sh
ssh root@47.98.203.17 "docker restart youle-cronjob"
# ── .env / docker-compose.yml 变更 ──
ssh root@47.98.203.17 "cd /opt/youle/game-docker && docker compose up -d"
# compose 会对比配置差异,只重启有变更的容器
```

View File

@@ -0,0 +1,68 @@
# SSL 证书管理
使用 Let's Encrypt 免费证书,由 `certbot` 容器自动管理。
---
## 常用命令
```bash
# 首次申请(必须先确保域名已解析)
./deploy.sh ssl-init
# 用测试环境验证(不消耗申请限额)
./deploy.sh ssl-init --staging
# 手动续签
./deploy.sh ssl-renew
# 查看证书状态
./deploy.sh ssl-status
```
`certbot` 容器每 12 小时自动检查续签,证书到期前 30 天自动更新,无需人工干预。
---
## 更换域名后重新申请
更换 `ROOT_DOMAIN` 后需要重新申请证书:
```bash
# 1. 测试验证(不消耗申请限额)
./deploy.sh ssl-init --staging
# 2. 正式申请
./deploy.sh ssl-init
# 3. 重启所有服务
./deploy.sh restart
```
> Let's Encrypt 有频率限制:每 7 天同一域名最多申请 5 次。调试阶段务必用 `--staging` 参数。
---
## 验证文件放置
微信后台添加授权域名时,要求在域名根目录放置 `.txt` 验证文件:
1. 将微信提供的验证文件(如 `MP_verify_xxx.txt`)放入 `api/` 根目录
2. 重建 api 镜像使其生效:
```bash
./deploy.sh rebuild api
```
---
## 数据持久化
SSL 相关的 Docker Volume
| Volume | 挂载点 | 说明 |
|--------|--------|------|
| `certbot-webroot` | /var/www/certbot | ACME 域名验证文件 |
| `certbot-certs` | /etc/letsencrypt | SSL 证书文件 |
> 卸载时若删除 `certbot-certs` volume证书将丢失需重新申请。详见 [卸载和清理](./07-uninstall.md)。

View File

@@ -0,0 +1,319 @@
# 常见运维操作
---
## 场景一:更换域名
当需要将服务迁移到新域名时(例如 `daoqijuyou.cn``newdomain.com`),只需改一个变量。
### 1. 修改 `.env` 中的 `ROOT_DOMAIN`
```bash
vim .env
```
```bash
# 改成新父域名,三个子域名自动跟随
ROOT_DOMAIN=newdomain.com
```
`docker-compose.yml` 将自动推导:
| 推导变量 | 结果 |
|---------|------|
| `API_DOMAIN` | `api.newdomain.com` |
| `DLWEB_DOMAIN` | `dlapi.newdomain.com` |
| `SITE_API_URL` | `https://api.newdomain.com` |
| `SITE_PAY_NOTIFY_URL` | `https://api.newdomain.com` |
| `SITE_OPEN_URL` | `http://open.newdomain.com` |
| `DLWEB_DL_API_V3_URL` | `https://dlapi.newdomain.com` |
> **子域名不符合标准规律时**,在 `.env` 中单独覆盖对应变量即可:
> ```bash
> DLWEB_DOMAIN=dl-manage.newdomain.com
> ```
> **其他独立 URL 变量**`DLWEB_SETTLE_URL`、`DLWEB_PROXY_URL`、`QQ_CALLBACK_URL` 等)仍需在 `.env` 中手动配置,详见 `.env.example` 中的注释。
### 2. DNS 解析
```bash
# 验证 DNS 解析
nslookup api.newdomain.com
nslookup dlapi.newdomain.com
```
### 3. 重新申请 SSL 证书
```bash
./deploy.sh ssl-init --staging # 测试验证
./deploy.sh ssl-init # 正式申请
```
### 4. 重启所有服务
```bash
./deploy.sh restart
```
重启时自动完成:
- Nginx 使用新域名的 `server_name` 和 SSL 证书
- `docker-entrypoint.sh` 用新域名替换 JS/HTML 中的硬编码 URL
- PHP `env()` 读取新的环境变量值
### 5. 更新微信后台配置
> **关键路由说明:** Nginx 在 `api.newdomain.com` 上配置了 `/wx/` 前缀路由——以 `/wx/` 开头的请求被反向代理到 wxserverNode.js其余请求仍由 PHP API 处理。
#### 5.1 微信小程序后台
> **入口:** [mp.weixin.qq.com](https://mp.weixin.qq.com) → 开发 → 开发管理 → 开发设置 → 服务器域名
| 配置项 | 新值 | 不更新时的现象 |
|--------|------|--------------|
| **request 合法域名** | `https://api.newdomain.com` | `wx.request``invalid url`,所有网络请求失败 |
| **业务域名** | `api.newdomain.com` | web-view 提示"不在业务域名列表中" |
> 小程序域名配置每月只能修改 5 次,且每项域名必须已备案并启用 HTTPS。
#### 5.2 微信公众号后台
> **入口:** [mp.weixin.qq.com](https://mp.weixin.qq.com) → 设置与开发 → 公众号设置 → 功能设置
| 配置项 | 填写值 | 不更新时的现象 |
|--------|--------|--------------|
| 业务域名 | `api.newdomain.com` | 微信内置浏览器提示"域名不合法" |
| 网页授权域名 | `api.newdomain.com` | 授权跳转被微信拦截,永久头像功能不可用 |
| JS 接口安全域名 | `api.newdomain.com` | `wx.config()` 签名验证失败,微信支付按钮无法唤起 |
> **⚠️ 远程配置也需同步修改:** `WX_OA_REDIRECT_DOMAIN` 未配置时wxserver 从远程配置文件读取 `minipro_api_url`。建议同步更新 Gitee Raw 配置 `minipro_api_url` 为 `api.newdomain.com/wx`。
#### 5.3 微信支付商户后台
> **入口:** [pay.weixin.qq.com](https://pay.weixin.qq.com) → 账户中心 → 商户信息 → 支付配置 → JSAPI 支付授权目录
| 配置值 | 用途 |
|--------|------|
| `https://api.newdomain.com/` | JSAPI 支付页面所在目录(必须包含末尾斜杠) |
不更新的后果:下单时提示"当前 URL 未注册"JSAPI 支付彻底无法使用。
#### 配置清单汇总
| 平台 | 配置项 | 填写值 |
|------|--------|--------|
| 微信小程序后台 | request 合法域名 | `https://api.newdomain.com` |
| 微信小程序后台 | 业务域名 | `api.newdomain.com` |
| 微信公众号后台 | 业务域名 | `api.newdomain.com` |
| 微信公众号后台 | 网页授权域名 | `api.newdomain.com` |
| 微信公众号后台 | JS 接口安全域名 | `api.newdomain.com` |
| 微信支付商户后台 | JSAPI 支付授权目录 | `https://api.newdomain.com/` |
---
## 场景二:更换数据库地址
当数据库实例迁移(例如 RDS 升级、切换区域)时:
### 1. 修改 `.env` 中对应的数据库变量
| 数据库 | 需修改的变量 | 使用者 |
|--------|-------------|--------|
| API 主库 | `API_DB_HOST`, `API_DB_PORT`, `API_DB_USER`, `API_DB_PASSWORD` | api 服务 |
| 代理后台主库 | `DLWEB_DB_HOST`, `DLWEB_DB_PORT`, `DLWEB_DB_USER`, `DLWEB_DB_PASSWORD` | dlweb 服务 |
| 代理后台从库 | `DLWEB_SLAVE_DB_HOST`, `DLWEB_SLAVE_DB_PORT`, `DLWEB_SLAVE_DB_USER`, `DLWEB_SLAVE_DB_PASSWORD` | dlweb 读操作 |
| 外部游戏库 | `EXT_GAME_DB_HOST`, `EXT_GAME_DB_PORT`, `EXT_GAME_DB_USER`, `EXT_GAME_DB_PASSWORD` | Synchronize.php |
| 战绩库 | `EXT_GRADE_DB_HOST`, `EXT_GRADE_DB_PORT`, `EXT_GRADE_DB_USER`, `EXT_GRADE_DB_PASSWORD` | game.php |
| 开发库 | `EXT_DEV_DB_HOST`, `EXT_DEV_DB_PORT`, `EXT_DEV_DB_USER`, `EXT_DEV_DB_PASSWORD` | DEBUG 模式 |
### 2. 重启受影响的服务
```bash
docker compose restart api # 只改了 API 数据库
docker compose restart dlweb # 只改了 DLWEB 数据库
docker compose restart dlweb syncjob cronjob # 改了外部游戏库
./deploy.sh restart # 改了多个,全部重启
```
### 3. 验证连接
```bash
docker logs --tail 20 youle-api
docker logs --tail 20 youle-dlweb
docker logs --tail 10 youle-syncjob
```
> 如果新数据库有 IP 白名单限制,需要将 Docker 宿主机的公网 IP 加入 RDS 白名单。
---
## 场景三:更换服务器(整体迁移)
### 1. 打包项目文件(旧服务器)
```bash
cd /path/to/game-docker
tar czf game-docker.tar.gz --exclude='.env' --exclude='game/' .
```
### 2. 传输到新服务器
```bash
scp game-docker.tar.gz newserver:/opt/
```
### 3. 在新服务器上部署
```bash
cd /opt
tar xzf game-docker.tar.gz -C game-docker
cd game-docker
cp .env.example .env
vim .env
```
### 4. 确认修改项
| 检查项 | 是否需要改 | 说明 |
|--------|-----------|------|
| 域名(`*_DOMAIN` | 域名不变则不改 | DNS 需指向新服务器 IP |
| 数据库地址(`*_DB_HOST` | 通常不改 | RDS 地址不变,但需将新服务器 IP 加入白名单 |
| Redis 地址 | 不改 | Docker 内置 Redis随容器迁移 |
| 微信/支付配置 | 不改 | AppID/Secret 与服务器无关 |
| 游戏服务器查询地址 | 看情况 | 游戏服务器也迁移了则需改 |
| IP 白名单 | 可能需改 | `INTERNAL_WHITELIST` 加入新 IP |
### 5. 启动服务
```bash
chmod +x deploy.sh init-ssl.sh
./deploy.sh ssl-init # 新服务器需重新申请证书
./deploy.sh up
```
### 6. 验证所有服务
```bash
./deploy.sh status
curl -k https://api.yourdomain.com/
curl -k https://dlapi.yourdomain.com/
curl -k https://api.yourdomain.com/wx/api/login
docker logs --tail 5 youle-syncjob
docker logs --tail 5 youle-cronjob
```
---
## 场景四:更改 Redis 配置
```bash
vim .env
# 修改以下变量:
# REDIS_HOST=new-redis-host
# REDIS_PORT=6379
# REDIS_PASSWORD=new-password
docker compose restart dlweb redis
```
> 使用 Docker 内置 Redis默认`REDIS_HOST` 应设为 `redis`Docker 服务名),不是 `localhost`。
---
## 场景五:单独开启 / 关闭特定服务
### 服务清单与依赖关系
| 服务名 | 容器名 | 说明 | 依赖 |
|--------|--------|------|------|
| `nginx` | `youle-nginx` | 反向代理 + SSL | api / dlweb / wxserver |
| `api` | `youle-api` | 游戏核心 API | — |
| `dlweb` | `youle-dlweb` | 代理管理后台 | redis |
| `wxserver` | `youle-wxserver` | 微信小程序后端 | — |
| `syncjob` | `youle-syncjob` | 每 30s 数据同步 | dlweb内网 |
| `cronjob` | `youle-cronjob` | 每日凌晨报表任务 | dlweb内网 |
| `redis` | `youle-redis` | 缓存 | — |
| `certbot` | `youle-certbot` | 证书自动续签 | — |
### 开启单个服务
```bash
docker compose up -d api
docker compose up -d dlweb
docker compose up -d wxserver
docker compose up -d syncjob
docker compose up -d cronjob
```
### 关闭单个服务
```bash
docker compose stop api
docker compose stop syncjob
# stop + 删除容器(下次 up 会重新创建)
docker compose rm -sf syncjob
```
> `stop` 只停止容器,不删除;`rm -sf` 停止并删除容器(均不会丢失数据 volume
### 常见场景
**只重建并重启某个业务服务(代码更新后):**
```bash
docker compose up -d --build api
docker compose up -d --build dlweb
docker compose up -d --build wxserver
```
**关闭 certbot 自动续签(调试期间避免请求频率限制):**
```bash
docker compose stop certbot
docker compose up -d certbot # 恢复
```
**仅重启 nginx修改配置后生效**
```bash
docker compose restart nginx
# 或热重载(不中断连接)
docker exec youle-nginx nginx -s reload
```
**查看所有服务当前状态:**
```bash
docker compose ps
# 或
./deploy.sh status
```
---
## 操作速查表
| 变更内容 | 修改 `.env` 中的变量 | 重启命令 | 额外操作 |
|---------|---------------------|---------|---------|
| 更换域名 | `ROOT_DOMAIN`(子域名不标准时单独覆盖) | `./deploy.sh ssl-init && ./deploy.sh restart` | DNS 解析 + 微信后台 |
| API 数据库 | `API_DB_*` | `docker compose restart api` | RDS 白名单 |
| DLWEB 数据库 | `DLWEB_DB_*` | `docker compose restart dlweb` | RDS 白名单 |
| 游戏数据库 | `EXT_GAME_DB_*` | `docker compose restart dlweb syncjob cronjob` | RDS 白名单 |
| 战绩数据库 | `EXT_GRADE_DB_*` | `docker compose restart dlweb` | RDS 白名单 |
| Redis | `REDIS_*` | `docker compose restart dlweb redis` | — |
| 微信密钥 | `WX_*` | `docker compose restart api dlweb wxserver` | 微信后台 |
| 整体迁移 | 视情况 | `./deploy.sh ssl-init && ./deploy.sh up` | DNS + RDS 白名单 |
---
## 数据持久化
以下 Docker Volume 用于持久化存储:
| Volume | 挂载点 | 说明 |
|--------|--------|------|
| `api-logs` | /var/www/html/logs | API 服务日志 |
| `api-source-logs` | /var/www/html/source/logs | API source 模块日志 |
| `dlweb-logs` | /var/www/html/api/logs | DLWEB 服务日志 |
| `dlweb-debug` | /var/www/html/api/ext/debug | DLWEB 同步/报表调试日志 |
| `redis-data` | /data | Redis 持久化数据 |
| `shared-signal` | /shared | syncjob ↔ cronjob 暂停信号文件 |
| `certbot-webroot` | /var/www/certbot | ACME 域名验证文件 |
| `certbot-certs` | /etc/letsencrypt | SSL 证书文件 |

View File

@@ -0,0 +1,310 @@
# 日志管理
---
## 日志位置总览
| 日志类型 | 来源容器 | 查看方式 | 说明 |
|---------|---------|---------|------|
| Nginx 访问/错误日志 | `youle-nginx` | `docker logs` | HTTP 请求记录、SSL 错误 |
| API Apache 错误日志 | `youle-api` | `docker logs` | PHP Fatal Error、Apache 500 |
| API PHP 错误日志 | `youle-api` | `docker logs` | PHP Warning/Notice写入 Apache 错误流)|
| API 业务日志 | `youle-api` | Volume 文件 | `/var/www/html/logs/YYYY-MM-DD.log` |
| API source 模块日志 | `youle-api` | Volume 文件 | `/var/www/html/source/logs/` |
| DLWEB Apache 错误日志 | `youle-dlweb` | `docker logs` | PHP Fatal Error、Apache 500 |
| DLWEB 业务日志 | `youle-dlweb` | Volume 文件 | `/var/www/html/api/logs/` |
| 同步任务调试日志 | `youle-dlweb` | Volume 文件 | `/var/www/html/api/ext/debug/synchronize/YYYY-MM-DD.log` |
| 报表同步调试日志 | `youle-dlweb` | Volume 文件 | `/var/www/html/api/ext/debug/SynchronizeReportData/YYYY-MM-DD.log` |
| 自动任务调试日志 | `youle-dlweb` | Volume 文件 | `/var/www/html/api/ext/debug/autotask/YYYY-MM-DD.log` |
| syncjob 运行日志 | `youle-syncjob` | `docker logs` | curl 请求结果,每 30s 一条 |
| cronjob 调度日志 | `youle-cronjob` | `docker logs` | cron 触发记录 |
| wxserver 运行日志 | `youle-wxserver` | `docker logs` | Node.js 标准输出 |
---
## 一、查看容器标准输出日志docker logs
```bash
# 查看最近 50 行(快速概览)
docker logs --tail 50 youle-nginx
docker logs --tail 50 youle-api
docker logs --tail 50 youle-dlweb
docker logs --tail 50 youle-syncjob
docker logs --tail 50 youle-cronjob
docker logs --tail 50 youle-wxserver
# 实时跟踪日志Ctrl+C 退出)
docker logs -f youle-api
docker logs -f youle-syncjob
# 查看最近 100 行并实时跟踪
docker logs --tail 100 -f youle-dlweb
# 查看带时间戳的日志
docker logs -t --tail 50 youle-nginx
# 查看某时间段之后的日志
docker logs --since 2026-04-13T10:00:00 youle-api
docker logs --since 1h youle-syncjob # 最近 1 小时
```
### 使用 deploy.sh 快捷查看
```bash
./deploy.sh logs api
./deploy.sh logs dlweb
./deploy.sh logs syncjob
./deploy.sh logs cronjob
./deploy.sh logs nginx
./deploy.sh logs wxserver
# 加 -f 实时跟踪
./deploy.sh logs -f api
./deploy.sh logs -f syncjob
```
---
## 二、查看业务调试日志文件Volume 文件)
业务调试日志写入 Docker Volume按日期分文件`YYYY-MM-DD.log`)。
```bash
# --- API 业务日志 ---
docker exec youle-api ls -lh /var/www/html/logs/
docker exec youle-api tail -50 /var/www/html/logs/$(date +%Y-%m-%d).log
docker exec youle-api tail -f /var/www/html/logs/$(date +%Y-%m-%d).log
docker exec youle-api cat /var/www/html/logs/$(date +%Y-%m-%d).log
# --- API source 模块日志 ---
docker exec youle-api ls -lhR /var/www/html/source/logs/
docker exec youle-api tail -50 /var/www/html/source/logs/$(date +%Y-%m-%d).log
# --- DLWEB 业务日志 ---
docker exec youle-dlweb ls -lh /var/www/html/api/logs/
docker exec youle-dlweb tail -50 /var/www/html/api/logs/$(date +%Y-%m-%d).log
# --- 同步任务调试日志Synchronize.php---
docker exec youle-dlweb ls -lh /var/www/html/api/ext/debug/synchronize/
docker exec youle-dlweb tail -50 /var/www/html/api/ext/debug/synchronize/$(date +%Y-%m-%d).log
docker exec youle-dlweb tail -f /var/www/html/api/ext/debug/synchronize/$(date +%Y-%m-%d).log
# --- 报表同步调试日志SynchronizeReportData.php---
docker exec youle-dlweb ls -lh /var/www/html/api/ext/debug/SynchronizeReportData/
docker exec youle-dlweb tail -50 /var/www/html/api/ext/debug/SynchronizeReportData/$(date +%Y-%m-%d).log
# --- 自动任务调试日志autotask---
docker exec youle-dlweb ls -lh /var/www/html/api/ext/debug/autotask/
docker exec youle-dlweb tail -50 /var/www/html/api/ext/debug/autotask/$(date +%Y-%m-%d).log
```
### 一键健康检查(汇总命令)
```bash
echo '=== syncjob 容器日志最近20行==='
docker logs --tail 20 youle-syncjob
echo
echo '=== 同步调试日志最近20行==='
docker exec youle-dlweb tail -20 /var/www/html/api/ext/debug/synchronize/$(date +%Y-%m-%d).log
echo
echo '=== API 业务日志最近20行==='
docker exec youle-api tail -20 /var/www/html/logs/$(date +%Y-%m-%d).log
```
### Nginx 访问日志过滤
```bash
# 过滤 HTTP 500 错误
docker logs youle-nginx 2>&1 | grep ' 500 '
# 过滤特定 IP 的请求
docker logs youle-nginx 2>&1 | grep '客户端IP地址'
# 过滤 SSL/TLS 握手错误
docker logs youle-nginx 2>&1 | grep 'SSL_do_handshake\|no required SSL'
```
---
## 三、清除日志
### 1. 清除 Docker 容器日志stdout/stderr
```bash
# 清空单个容器的 docker logs容器保持运行不中断服务
truncate -s 0 $(docker inspect --format='{{.LogPath}}' youle-syncjob)
truncate -s 0 $(docker inspect --format='{{.LogPath}}' youle-api)
truncate -s 0 $(docker inspect --format='{{.LogPath}}' youle-dlweb)
truncate -s 0 $(docker inspect --format='{{.LogPath}}' youle-nginx)
# 一键清空所有 youle-* 容器的 docker logs
for name in youle-nginx youle-api youle-dlweb youle-wxserver youle-syncjob youle-cronjob youle-redis youle-certbot; do
logpath=$(docker inspect --format='{{.LogPath}}' $name 2>/dev/null)
[ -n "$logpath" ] && truncate -s 0 "$logpath" && echo "Cleared: $name"
done
```
### 2. 清除业务调试日志文件Volume 内)
```bash
# --- 清除 API 业务日志 ---
docker exec youle-api sh -c "find /var/www/html/logs/ -name '*.log' ! -name '$(date +%Y-%m-%d).log' -delete"
docker exec youle-api truncate -s 0 /var/www/html/logs/$(date +%Y-%m-%d).log
docker exec youle-api sh -c 'rm -f /var/www/html/logs/*.log'
# --- 清除 DLWEB 业务日志 ---
docker exec youle-dlweb sh -c "find /var/www/html/api/logs/ -name '*.log' ! -name '$(date +%Y-%m-%d).log' -delete"
docker exec youle-dlweb sh -c 'rm -f /var/www/html/api/logs/*.log'
# --- 清除同步任务调试日志 ---
docker exec youle-dlweb find /var/www/html/api/ext/debug/ -name '*.log' -mtime +30 -delete # 删 30 天前
docker exec youle-dlweb sh -c "find /var/www/html/api/ext/debug/ -name '*.log' ! -name '$(date +%Y-%m-%d).log' -delete"
docker exec youle-dlweb sh -c '
rm -f /var/www/html/api/ext/debug/synchronize/*.log
rm -f /var/www/html/api/ext/debug/SynchronizeReportData/*.log
rm -f /var/www/html/api/ext/debug/autotask/*.log
'
```
### 3. 一键清理脚本(所有日志)
将以下内容保存为服务器上的 `/opt/youle/game-docker/clear-logs.sh`
```bash
#!/bin/bash
echo '=== 清空 Docker 容器日志 ==='
for name in youle-nginx youle-api youle-dlweb youle-wxserver youle-syncjob youle-cronjob youle-redis youle-certbot; do
logpath=$(docker inspect --format='{{.LogPath}}' $name 2>/dev/null)
if [ -n "$logpath" ] && [ -f "$logpath" ]; then
truncate -s 0 "$logpath"
echo " Cleared docker log: $name"
fi
done
echo '=== 清空业务日志文件 ==='
docker exec youle-api sh -c 'rm -f /var/www/html/logs/*.log /var/www/html/source/logs/*.log 2>/dev/null; echo " Cleared api logs"'
docker exec youle-dlweb sh -c '
rm -f /var/www/html/api/logs/*.log 2>/dev/null
rm -f /var/www/html/api/ext/debug/synchronize/*.log 2>/dev/null
rm -f /var/www/html/api/ext/debug/SynchronizeReportData/*.log 2>/dev/null
rm -f /var/www/html/api/ext/debug/autotask/*.log 2>/dev/null
echo " Cleared dlweb logs"
'
echo '=== 完成 ==='
```
```bash
chmod +x /opt/youle/game-docker/clear-logs.sh
/opt/youle/game-docker/clear-logs.sh
```
---
## 四、Windows PowerShell 远程操作
> 以下命令在 **Windows PowerShell** 中执行,通过 SSH 直接读取服务器上的业务日志。
### 查看日志
```powershell
$today = (Get-Date -Format "yyyy-MM-dd")
# api/logs
ssh root@47.98.203.17 "docker exec youle-api ls -lh /var/www/html/logs/"
ssh root@47.98.203.17 "docker exec youle-api tail -50 /var/www/html/logs/$today.log"
ssh root@47.98.203.17 "docker exec youle-api cat /var/www/html/logs/$today.log"
ssh root@47.98.203.17 "docker exec youle-api tail -f /var/www/html/logs/$today.log" # 实时
# synchronize
ssh root@47.98.203.17 "docker exec youle-dlweb ls -lh /var/www/html/api/ext/debug/synchronize/"
ssh root@47.98.203.17 "docker exec youle-dlweb tail -50 /var/www/html/api/ext/debug/synchronize/$today.log"
ssh root@47.98.203.17 "docker exec youle-dlweb tail -f /var/www/html/api/ext/debug/synchronize/$today.log" # 实时
# SynchronizeReportData
ssh root@47.98.203.17 "docker exec youle-dlweb ls -lh /var/www/html/api/ext/debug/SynchronizeReportData/"
ssh root@47.98.203.17 "docker exec youle-dlweb tail -50 /var/www/html/api/ext/debug/SynchronizeReportData/$today.log"
# autotask
ssh root@47.98.203.17 "docker exec youle-dlweb ls -lh /var/www/html/api/ext/debug/autotask/"
ssh root@47.98.203.17 "docker exec youle-dlweb tail -50 /var/www/html/api/ext/debug/autotask/$today.log"
# 一键汇总(同时查看三个目录今天的日志末尾)
$today = (Get-Date -Format "yyyy-MM-dd")
ssh root@47.98.203.17 @"
echo '=== api/logs/$today.log ==='
docker exec youle-api tail -30 /var/www/html/logs/$today.log
echo
echo '=== synchronize/$today.log ==='
docker exec youle-dlweb tail -30 /var/www/html/api/ext/debug/synchronize/$today.log
echo
echo '=== SynchronizeReportData/$today.log ==='
docker exec youle-dlweb tail -30 /var/www/html/api/ext/debug/SynchronizeReportData/$today.log
"@
```
### 删除日志
```powershell
$today = (Get-Date -Format "yyyy-MM-dd")
# 清空今天的 API 业务日志(保留文件)
ssh root@47.98.203.17 "docker exec youle-api truncate -s 0 /var/www/html/logs/$today.log"
# 删除全部 API 业务日志
ssh root@47.98.203.17 "docker exec youle-api sh -c 'rm -f /var/www/html/logs/*.log'"
# 清空今天的同步调试日志
ssh root@47.98.203.17 "docker exec youle-dlweb truncate -s 0 /var/www/html/api/ext/debug/synchronize/$today.log"
# 删除 30 天前的旧调试日志
ssh root@47.98.203.17 "docker exec youle-dlweb find /var/www/html/api/ext/debug/ -name '*.log' -mtime +30 -delete"
# 一键清理api/logs + dlweb/api/ext/debug 全部日志
ssh root@47.98.203.17 @"
docker exec youle-api sh -c 'rm -f /var/www/html/logs/*.log'
docker exec youle-dlweb sh -c '
rm -f /var/www/html/api/ext/debug/synchronize/*.log
rm -f /var/www/html/api/ext/debug/SynchronizeReportData/*.log
rm -f /var/www/html/api/ext/debug/autotask/*.log
'
echo "Done"
"@
```
---
## 快捷速查表
> 以下命令在 SSH 登录服务器后直接执行。
### 查看日志
| 目标 | 命令 |
|------|------|
| nginx 访问日志末尾50行 | `docker logs --tail 50 youle-nginx` |
| nginx 访问日志(实时跟踪) | `docker logs -f youle-nginx` |
| wxserver 日志末尾50行 | `docker logs --tail 50 youle-wxserver` |
| API PHP 错误日志末尾50行 | `docker exec youle-api tail -50 /var/log/apache2/php_errors.log` |
| API 业务日志_今天末尾50行 | `docker exec youle-api tail -50 /var/www/html/logs/$(date +%Y-%m-%d).log` |
| API 业务日志_今天实时跟踪 | `docker exec youle-api tail -f /var/www/html/logs/$(date +%Y-%m-%d).log` |
| 列出 API 业务日志文件 | `docker exec youle-api ls -lh /var/www/html/logs/` |
| 同步调试日志_今天末尾50行 | `docker exec youle-dlweb tail -50 /var/www/html/api/ext/debug/synchronize/$(date +%Y-%m-%d).log` |
| 同步调试日志_今天实时跟踪 | `docker exec youle-dlweb tail -f /var/www/html/api/ext/debug/synchronize/$(date +%Y-%m-%d).log` |
| syncjob 任务日志末尾50行 | `docker logs --tail 50 youle-syncjob` |
| cronjob 任务日志末尾50行 | `docker logs --tail 50 youle-cronjob` |
### 清理日志
| 目标 | 命令 |
|------|------|
| 清空 nginx docker logs | `truncate -s 0 $(docker inspect --format='{{.LogPath}}' youle-nginx)` |
| 清空 API docker logs | `truncate -s 0 $(docker inspect --format='{{.LogPath}}' youle-api)` |
| 清空 dlweb docker logs | `truncate -s 0 $(docker inspect --format='{{.LogPath}}' youle-dlweb)` |
| 清空所有容器 docker logs | `for n in youle-nginx youle-api youle-dlweb youle-wxserver youle-syncjob youle-cronjob youle-redis youle-certbot; do truncate -s 0 $(docker inspect --format='{{.LogPath}}' $n 2>/dev/null) 2>/dev/null; done` |
| 清空今天 API 业务日志 | `docker exec youle-api truncate -s 0 /var/www/html/logs/$(date +%Y-%m-%d).log` |
| 清空今天同步调试日志 | `docker exec youle-dlweb truncate -s 0 /var/www/html/api/ext/debug/synchronize/$(date +%Y-%m-%d).log` |
| 删除 API 全部历史日志 | `docker exec youle-api sh -c 'rm -f /var/www/html/logs/*.log'` |
| 删除调试日志 30 天前旧文件 | `docker exec youle-dlweb find /var/www/html/api/ext/debug/ -name '*.log' -mtime +30 -delete` |
| 删除调试日志全部文件 | `docker exec youle-dlweb sh -c 'rm -f /var/www/html/api/ext/debug/synchronize/*.log /var/www/html/api/ext/debug/SynchronizeReportData/*.log /var/www/html/api/ext/debug/autotask/*.log'` |
| 一键清理全部日志 | `/opt/youle/game-docker/clear-logs.sh` |

View File

@@ -0,0 +1,144 @@
# 卸载和清理
根据需求选择卸载范围。以下操作不可逆,请提前备份重要数据。
---
## 卸载前:备份关键数据
```bash
cd /opt/youle/game-docker
# 1. 备份 .env包含所有密钥不在版本库中
cp .env ~/youle-env-backup.env
# 2. 备份 Redis 数据(如有业务数据存储在 Redis 中)
docker exec youle-redis redis-cli -a "${REDIS_PASSWORD}" BGSAVE
# 或直接备份 volume
docker run --rm -v game-docker_redis-data:/data -v ~/:/backup alpine \
tar czf /backup/redis-data-backup.tar.gz /data
# 3. 备份日志(按需)
docker cp youle-api:/var/www/html/logs ~/api-logs-backup
docker cp youle-dlweb:/var/www/html/api/logs ~/dlweb-logs-backup
```
---
## 仅停止所有容器(保留镜像和数据,可随时恢复)
```bash
cd /opt/youle/game-docker
docker compose stop
# 验证
docker compose ps
```
恢复运行:
```bash
docker compose start
```
---
## 停止并删除容器保留镜像、volumes 和项目文件)
```bash
cd /opt/youle/game-docker
docker compose down
# 验证容器已删除
docker ps -a | grep youle
```
> 此操作不会删除数据 volume 和已构建的镜像,再次 `docker compose up -d` 可快速恢复,无需重新构建。
---
## 完全卸载(删除容器 + volumes + 镜像)
> **警告:** 以下操作将删除 Redis 缓存和所有日志数据,不可恢复。
```bash
cd /opt/youle/game-docker
# 停止并删除容器 + 所有相关 volumes
docker compose down -v
# 删除本项目构建的镜像
docker rmi game-docker-api game-docker-dlweb game-docker-wxserver 2>/dev/null || true
# 验证
docker volume ls | grep game-docker
docker images | grep game-docker
```
---
## 彻底清理(删除容器 + volumes + 镜像 + 项目目录 + SSL 证书)
> **警告:** SSL 证书删除后需重新申请Let's Encrypt 有频率限制,每 7 天最多 5 次)。
```bash
cd /opt/youle/game-docker
# 1. 停止并删除容器 + volumes
docker compose down -v
# 2. 删除构建镜像
docker rmi game-docker-api game-docker-dlweb game-docker-wxserver 2>/dev/null || true
# 3. 清理 Docker 悬空资源(可选)
docker system prune -f
# 4. 删除 SSL 证书
docker volume rm game-docker_certbot-certs game-docker_certbot-webroot 2>/dev/null || true
# 5. 删除项目目录
rm -rf /opt/youle/game-docker
```
---
## 删除单个服务的容器和镜像
```bash
cd /opt/youle/game-docker
# 以 dlweb 为例
docker compose stop dlweb
docker compose rm -sf dlweb
docker rmi game-docker-dlweb
# 下次启动时会重新构建
docker compose up -d --build dlweb
```
---
## 清理定时任务残留
```bash
docker compose stop syncjob cronjob
docker compose rm -sf syncjob cronjob
# 清理共享信号 volume如有残留暂停文件
docker run --rm -v game-docker_shared-signal:/shared alpine rm -f /shared/syncjob.pause
# 如需完全删除共享 volume
docker volume rm game-docker_shared-signal
```
---
## 卸载操作速查
| 目标 | 命令 | 保留内容 |
|------|------|----------|
| 临时停止(可恢复) | `docker compose stop` | 容器 / 镜像 / volumes / 文件 |
| 删除容器 | `docker compose down` | 镜像 / volumes / 文件 |
| 删除容器 + volumes | `docker compose down -v` | 镜像 / 文件 |
| 删除容器 + volumes + 镜像 | `docker compose down -v` + `docker rmi ...` | 文件 |
| 完全清理 | 上述全部 + `rm -rf /opt/youle/game-docker` | 无 |

View File

@@ -0,0 +1,85 @@
# 数据库远程管理Navicat SSH 隧道)
> RDS 白名单仅开放服务器 `47.98.203.17`,任何设备需通过 SSH 隧道访问数据库,无需开放公网 IP安全可控。
---
## 原理
```
本机 Navicat ──SSH加密隧道──▶ 47.98.203.17 ──内网──▶ RDS MySQL
```
---
## 数据库与 RDS 实例对应关系
| 数据库 | RDS 主机 |
|--------|---------|
| `agent_db``agent_db_temp``game_field``youlehudong` | `rm-bp1btyuwq77591x0jpo.mysql.rds.aliyuncs.com` |
| `game_db``grade_db` | `rm-bp1749tfxu2rpq670lo.mysql.rds.aliyuncs.com` |
---
## Navicat 连接配置(以 agent_db 为例)
### 第一步SSH 标签页
| 字段 | 值 |
|------|----|
| 使用 SSH 通道 | ✅ 勾选 |
| 主机 | `47.98.203.17` |
| 端口 | `22` |
| 用户名 | `root` |
| 验证方法 | **公钥** |
| 私钥文件 | `C:\Users\{你的用户名}\.ssh\id_ed25519` |
> **注意**:当前服务器已授权的密钥为 `id_ed25519`(标识 `youle-deploy`),选错密钥会导致认证失败。
### 第二步:常规标签页
| 字段 | 值 |
|------|----|
| 主机名/IP | `rm-bp1btyuwq77591x0jpo.mysql.rds.aliyuncs.com` |
| 端口 | `3306` |
| 用户名 | `games` |
| 密码 | `Games0791!!` |
| 数据库 | `agent_db`(可留空后再选) |
> ⚠️ **常见错误2013 错误)**:常规标签的主机名填了 `127.0.0.1` 或 `localhost`,会连接到服务器本机而非 RDS导致握手失败。必须填 RDS 完整域名。
---
## 新设备接入
在新设备上执行以下步骤:
```powershell
# 1. 生成密钥对(如没有)
ssh-keygen -t ed25519 -C "设备标识备注"
# 2. 查看公钥内容
Get-Content "$env:USERPROFILE\.ssh\id_ed25519.pub"
```
将公钥内容追加到服务器:
```bash
ssh root@47.98.203.17 "echo 'ssh-ed25519 AAAA...你的公钥内容...' >> ~/.ssh/authorized_keys"
```
之后 Navicat SSH 标签填写该设备的私钥路径即可。
---
## 命令行手动隧道(可选)
如需在命令行工具(如 mysql CLI中使用可手动建立隧道
```bash
# 建立隧道(保持此终端运行,另开终端连接)
ssh -L 3307:rm-bp1btyuwq77591x0jpo.mysql.rds.aliyuncs.com:3306 root@47.98.203.17 -N
# 另开终端,连接本地转发端口
mysql -h 127.0.0.1 -P 3307 -u games -p agent_db
```