添加docker 部署agent

This commit is contained in:
2026-04-13 17:06:02 +08:00
parent 797824d01c
commit a7c2448207
2866 changed files with 1149 additions and 272838 deletions

View File

@@ -96,15 +96,112 @@ game-docker/
- 服务器 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. 上传项目到服务器
`game-docker` 目录上传到服务器 `/opt/youle/` 下:
```bash
# 方式一从本地直接上传Windows 使用 scp / WinSCP / SFTP
scp -r game-docker/ root@your-server-ip:/opt/youle/
```powershell
# 推荐:使用 sync.ps1tar 压缩单连接,比 scp -r 快约 10-50 倍
# 首次部署用 full 模式,上传全部文件(约 10 MB 压缩包)
.\sync.ps1 -Mode full
# 方式二:从 Git 仓库拉取
# 日常代码更新用 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
@@ -136,10 +233,9 @@ vim .env
**必须修改的关键配置:**
```bash
# 域名(用于 Nginx SSL 和 certbot
API_DOMAIN=api.yourdomain.com
DLWEB_DOMAIN=dlapi.yourdomain.com
WX_DOMAIN=wxapi.yourdomain.com
# 域名(三个子域名自动推导,无需单独配置
# 将自动生成: api.<ROOT_DOMAIN> dlapi.<ROOT_DOMAIN> wxapi.<ROOT_DOMAIN>
ROOT_DOMAIN=yourdomain.com
# 数据库(各服务数据库连接)
API_DB_HOST=your-rds-host
@@ -304,7 +400,7 @@ docker exec youle-cronjob /bin/sh /app/daily-task.sh
| `WX_OA_*` | 微信公众号 AppID / Secret |
| `WX_PAY_*` | 微信支付商户配置 |
| `REMOTE_CONFIG_*` | 远程配置Gitee |
| `API_DOMAIN` / `DLWEB_DOMAIN` / `WX_DOMAIN` | 3 个服务域名Nginx + SSL + 前端 JS 自动推导 |
| `ROOT_DOMAIN` | 父域名(自动推导 3 个子域名 + 所有派生 URL |
| `SITE_*` | PHP 后端各站点域名 |
| `DLWEB_*_URL` | 前端 JS/HTML 硬编码域名替换 |
| `SYNC_INTERVAL` / `SYNC_PROCESSCOUNT` | syncjob 同步参数 |
@@ -315,13 +411,19 @@ docker exec youle-cronjob /bin/sh /app/daily-task.sh
### 域名配置关系
```
.env 域名用途
─────────────────────┼──────────────────────────────────
API_DOMAIN Nginx server_name网站1+ 自动推导 DLWEB_API_BASE_URL
DLWEB_DOMAIN │ Nginx server_name网站2+ 自动推导 DLWEB_SDK_API_URL
WX_DOMAIN │ Nginx server_name网站3
.env 配置自动推导结果
─────────────────────┼──────────────────────────────────────────────────────
ROOT_DOMAIN │ API_DOMAIN = api.<ROOT_DOMAIN> Nginx 网站1
(唯一必填) │ DLWEB_DOMAIN = dlapi.<ROOT_DOMAIN> → Nginx 网站2
│ WX_DOMAIN = wxapi.<ROOT_DOMAIN> → Nginx 网站3
│ 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` 中单独覆盖对应变量。
---
## 环境变量加载机制
@@ -415,47 +517,37 @@ $host = env('API_DB_HOST', 'localhost');
### 场景一:更换域名
当需要将服务迁移到新域名时(例如 `daoqijuyou77.cn``newdomain.com`操作步骤
当需要将服务迁移到新域名时(例如 `daoqijuyou.cn``newdomain.com`只需改一个变量
**1. 修改 `.env` 中的域名变量**
**1. 修改 `.env` 中的 `ROOT_DOMAIN`**
```bash
vim .env
```
需要修改的变量(按影响范围分类):
```bash
# 改成新父域名,三个子域名自动跟随
ROOT_DOMAIN=newdomain.com
```
| 变量 | 说明 | 示例 |
|------|------|------|
| **Nginx 路由(必改)** | | |
| `API_DOMAIN` | 网站1 域名 | `api.newdomain.com` |
| `DLWEB_DOMAIN` | 网站2 域名 | `dlapi.newdomain.com` |
| `WX_DOMAIN` | 网站3 域名 | `wxapi.newdomain.com` |
| **PHP 后端域名(按需)** | | |
`docker-compose.yml` 将自动推导:
> **前端 JS 请求地址无需单独配置:** `DLWEB_API_BASE_URL`= `https://` + `API_DOMAIN`)和 `DLWEB_SDK_API_URL`= `https://` + `DLWEB_DOMAIN`)由 entrypoint 脚本自动推导。
| 推导变量 | 结果 |
|---------|------|
| `API_DOMAIN` | `api.newdomain.com` |
| `DLWEB_DOMAIN` | `dlapi.newdomain.com` |
| `WX_DOMAIN` | `wxapi.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` |
| `SITE_API_URL` | API 服务完整 URL | `https://api.newdomain.com` |
| `SITE_API2_URL` | API2 服务完整 URL | `https://api2.newdomain.com` |
| `SITE_SDK_DOMAIN` | SDK 域名(不带协议) | `sdk.newdomain.com` |
| `SITE_OPEN_URL` | 开放平台 URL | `http://open.newdomain.com` |
| `SITE_PAY_NOTIFY_URL` | 支付回调通知 URL | `http://api.newdomain.com` |
| `QQ_CALLBACK_URL` | QQ 登录回调 | `http://syhd.newdomain.com` |
| **DLWEB 前端域名(按需)** | | |
| `DLWEB_SETTLE_URL` | 结算后台地址 | `http://dlsettle.newdomain.com/mobile/` |
| `DLWEB_SETTLE_FULL_URL` | 结算后台完整地址 | `http://dlsettle.newdomain.com` |
| `DLWEB_PROXY_URL` | 代理测试地址 | `https://proxytest.newdomain.com` |
| `DLWEB_PROXY_77_URL` | 代理测试地址77 | `https://proxytest.newdomain.com` |
| `DLWEB_DL_API_V3_URL` | V3 API 地址 | `https://dlapiv3.newdomain.com` |
| `DLWEB_OPERATE_URL` | 运营后台地址 | `https://operate.newdomain.com` |
| `DLWEB_AVATAR_URL` | 默认头像地址 | `https://dlwebv3.newdomain.com/images/noavatar.png` |
| `DLWEB_SDK_API2_URL` | SDK API2 地址 | `https://api2.newdomain.com` |
| `DLWEB_DOWNLOAD_CDN_URL` | 下载页 CDN | `http://cdn.newdomain.com` |
| `DLWEB_GAME_IMAGE_URL` | 游戏图片地址 | `http://games.newdomain.com` |
| `DLWEB_SKYGAMES_URL` | Skygames 地址 | `https://skygames.newdomain.com` |
| `SITE_GAME_SERVICE_URL` | 游戏服务查询 | `http://service.newdomain.com:1089/index.html` |
> **子域名不符合标准规律时**(如使用完全不同的前缀),在 `.env` 中单独覆盖对应变量即可,优先级高于自动推导:
> ```bash
> DLWEB_DOMAIN=dl-manage.newdomain.com # 覆盖单个子域名
> ```
> **注意:** 注释掉的变量(`#` 开头)表示使用代码中的默认值。如果新域名与默认值不同,需要取消注释并修改
> **其他独立 URL 变量**`DLWEB_SETTLE_URL`、`DLWEB_PROXY_URL`、`QQ_CALLBACK_URL` 等)仍需在 `.env` 中手动配置,详见 `.env.example` 中的注释
**2. DNS 解析**
@@ -644,12 +736,98 @@ docker compose restart dlweb redis
---
### 场景五:单独开启 / 关闭特定服务
所有服务均可独立启停,不影响其他运行中的容器。
#### 服务清单与依赖关系
| 服务名 | 容器名 | 说明 | 依赖 |
|--------|--------|------|------|
| `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
cd /opt/youle/game-docker
# 启动某个服务(若镜像不存在会自动构建)
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
docker compose up -d redis
docker compose up -d nginx
docker compose up -d certbot
```
#### 关闭单个服务
```bash
# 停止并移除容器(数据 volume 不受影响)
docker compose stop api
docker compose stop syncjob
docker compose stop cronjob
# 或者 stop + 移除容器(等效于 stop + rm
docker compose rm -sf syncjob
```
> **注意:** `stop` 只停止容器,不删除;`rm -sf` 停止并删除容器(下次 `up` 会重新创建)。两种方式均不会丢失数据 volume。
#### 常见场景
**临时关闭同步任务(维护数据库时):**
```bash
docker compose stop syncjob cronjob
# 维护完成后恢复
docker compose up -d syncjob cronjob
```
**只重建并重启某个业务服务(代码更新后):**
```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` 中的变量 | 重启命令 | 额外操作 |
|---------|---------------------|---------|---------|
| 全部域名 | `*_DOMAIN` + `DLWEB_*_URL` + `SITE_*` | `./deploy.sh ssl-init && ./deploy.sh restart` | DNS 解析 + 微信后台 |
| 单个域名 | 对应的 `*_DOMAIN` + 关联 URL 变量 | `./deploy.sh ssl-init && ./deploy.sh restart` | DNS 解析 |
| 更换域名 | `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 白名单 |
@@ -658,18 +836,167 @@ docker compose restart dlweb redis
| 微信密钥 | `WX_*` | `docker compose restart api dlweb wxserver` | 微信后台 |
| 整体迁移 | 视情况 | `./deploy.sh ssl-init && ./deploy.sh up` | DNS + RDS 白名单 |
### 查看定时任务执行情况
### 场景七:查看日志
本项目日志分为两类:**Docker 容器标准输出日志**`docker logs`)和**业务调试日志**(写入 Docker Volume 的文件)。
#### 日志位置总览
| 日志类型 | 来源容器 | 查看方式 | 说明 |
|---------|---------|---------|------|
| 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 标准输出 |
---
#### 1. 查看容器标准输出日志docker logs
```bash
# syncjob 实时同步状态
# 查看最近 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
# cronjob 每日报表执行记录
docker logs --tail 50 youle-cronjob
docker logs --tail 50 youle-wxserver
# dlweb 容器内的同步调试日志
docker exec youle-dlweb ls /var/www/html/api/ext/debug/synchronize/
docker exec youle-dlweb ls /var/www/html/api/ext/debug/SynchronizeReportData/
# 实时跟踪日志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
# 查看某时间段之后的日志ISO 8601 格式)
docker logs --since 2026-04-13T10:00:00 youle-api
docker logs --since 1h youle-syncjob # 最近 1 小时
```
> **提示:** `docker logs` 查看的是容器的 stdout/stderr 输出PHP Fatal Error 和 Apache 错误均会出现在这里。
---
#### 2. 查看业务调试日志文件Volume 文件)
业务调试日志写入 Docker Volume按日期分文件`YYYY-MM-DD.log`)。
```bash
# --- API 业务日志 ---
# 列出所有日志文件
docker exec youle-api ls -lh /var/www/html/logs/
# 查看今天的 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
# 查看完整内容
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/
# 查看今天的 DLWEB 业务日志
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/
# 查看今天的同步日志(最近 50 行)
docker exec youle-dlweb tail -50 /var/www/html/api/ext/debug/synchronize/$(date +%Y-%m-%d).log
# 实时跟踪同步日志(每 30s 刷新)
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
```
---
#### 3. 一键查看所有关键日志(汇总命令)
```bash
# 快速健康检查:同时查看 syncjob 状态 + 今天的同步调试日志末尾
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
```
---
#### 4. 查看 Nginx 访问日志(请求排查)
```bash
# Nginx 访问日志(最近 100 条请求)
docker logs --tail 100 youle-nginx
# 过滤 HTTP 500 错误
docker logs youle-nginx 2>&1 | grep ' 500 '
# 过滤特定 IP 的请求
docker logs youle-nginx 2>&1 | grep '客户端IP地址'
# 过滤 SSL/TLS 握手错误(客户端发送了非 HTTPS 请求到 80 端口)
docker logs youle-nginx 2>&1 | grep 'SSL_do_handshake\|no required SSL'
```
---
#### 5. 使用 deploy.sh 快捷查看
```bash
# 等效于 docker logs --tail 100 + 实时跟踪
./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
```
### 调整同步频率
@@ -692,3 +1019,437 @@ CRON_SCHEDULE=30 3 * * * # 改为凌晨 3:30
# 重启 cronjob
docker compose restart cronjob
```
---
### 场景六:卸载和清理
根据需求选择卸载范围,操作不可逆,请提前备份重要数据。
#### 卸载前:备份关键数据
```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 证书Let's Encrypt
docker run --rm -v game-docker_certbot-certs:/etc/letsencrypt certbot/certbot delete \
--cert-name "${API_DOMAIN}" --non-interactive 2>/dev/null || true
docker run --rm -v game-docker_certbot-certs:/etc/letsencrypt certbot/certbot delete \
--cert-name "${DLWEB_DOMAIN}" --non-interactive 2>/dev/null || true
docker run --rm -v game-docker_certbot-certs:/etc/letsencrypt certbot/certbot delete \
--cert-name "${WX_DOMAIN}" --non-interactive 2>/dev/null || true
# 或直接删除证书 volume
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
# 停止并删除 syncjob / cronjob 容器
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` | 无 |
---
### 场景八:清除日志
> **说明:** Volume 文件日志(业务调试日志)和 Docker 容器日志stdout需要分别清理。清理前建议先备份或确认不再需要这些日志。
#### 1. 清除 Docker 容器日志stdout/stderr
Docker 容器的标准输出日志存储在宿主机 `/var/lib/docker/containers/<容器ID>/<容器ID>-json.log`,直接清空该文件即可。
```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)
truncate -s 0 $(docker inspect --format='{{.LogPath}}' youle-cronjob)
truncate -s 0 $(docker inspect --format='{{.LogPath}}' youle-wxserver)
# 一键清空所有 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
```
> **注意:** `truncate -s 0` 清空文件内容,不删除文件,容器无需重启,后续日志正常写入。
---
#### 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'
# --- 清除同步任务调试日志 ---
# 删除 30 天前的旧日志
docker exec youle-dlweb find /var/www/html/api/ext/debug/ -name '*.log' -mtime +30 -delete
# 删除所有历史日志(保留今天)
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 truncate -s 0 /var/www/html/api/ext/debug/synchronize/$(date +%Y-%m-%d).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
'
```
---
#### 3. 一键清理所有日志docker logs + 业务日志)
> **警告:** 以下脚本将清空所有容器日志和全部业务日志文件,执行前请确认不需要保留现有日志。
```bash
#!/bin/bash
# 一键清理所有日志(在服务器 /opt/youle/game-docker/ 目录下执行)
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 '=== 清空业务日志文件 ==='
# API 业务日志
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"'
# DLWEB 业务日志 + 调试日志
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 '=== 完成 ==='
```
将以上内容保存为服务器上的 `/opt/youle/game-docker/clear-logs.sh`,赋予执行权限后使用:
```bash
chmod +x /opt/youle/game-docker/clear-logs.sh
/opt/youle/game-docker/clear-logs.sh
```
---
#### 4. 日志清理速查
| 目标 | 命令 |
|------|------|
| 清空某容器 docker logs | `truncate -s 0 $(docker inspect --format='{{.LogPath}}' 容器名)` |
| 清空今天 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` |
| 删除所有调试历史日志 | `docker exec youle-dlweb find /var/www/html/api/ext/debug/ -name '*.log' -mtime +30 -delete` |
| 一键清理全部日志 | `./clear-logs.sh` |
```
---
### 场景九:从 Windows 本地查看和删除业务日志
> 以下命令在 **Windows PowerShell** 中执行,通过 SSH 直接读取服务器上的业务日志文件。
> 日志来源目录(本地代码映射到容器的 Volume
> - `api/logs/` → 容器内 `/var/www/html/logs/`
> - `dlweb/api/ext/debug/` → 容器内 `/var/www/html/api/ext/debug/`
---
#### 查看日志
```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/"
# 查看今天的 API 业务日志(末尾 50 行)
ssh root@47.98.203.17 "docker exec youle-api tail -50 /var/www/html/logs/$today.log"
# 查看今天的 API 业务日志(完整内容)
ssh root@47.98.203.17 "docker exec youle-api cat /var/www/html/logs/$today.log"
# 实时跟踪今天的 API 业务日志Ctrl+C 停止)
ssh root@47.98.203.17 "docker exec youle-api tail -f /var/www/html/logs/$today.log"
# ── dlweb/api/ext/debug/synchronize ──────────────────────────────
# 列出所有同步调试日志文件
ssh root@47.98.203.17 "docker exec youle-dlweb ls -lh /var/www/html/api/ext/debug/synchronize/"
# 查看今天的同步调试日志(末尾 50 行)
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 cat /var/www/html/api/ext/debug/synchronize/$today.log"
# 实时跟踪同步调试日志Ctrl+C 停止)
ssh root@47.98.203.17 "docker exec youle-dlweb tail -f /var/www/html/api/ext/debug/synchronize/$today.log"
# ── dlweb/api/ext/debug/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"
# ── dlweb/api/ext/debug/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/logs ─────────────────────────────────────────────────────
# 清空今天的 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 rm -f /var/www/html/logs/$today.log"
# 删除所有 API 业务日志(保留今天)
ssh root@47.98.203.17 "docker exec youle-api sh -c `"find /var/www/html/logs/ -name '*.log' ! -name '$today.log' -delete`""
# 删除全部 API 业务日志(含今天)
ssh root@47.98.203.17 "docker exec youle-api sh -c 'rm -f /var/www/html/logs/*.log'"
# ── dlweb/api/ext/debug ──────────────────────────────────────────
# 清空今天的同步调试日志(保留文件,清空内容)
ssh root@47.98.203.17 "docker exec youle-dlweb truncate -s 0 /var/www/html/api/ext/debug/synchronize/$today.log"
# 删除今天的同步调试日志文件
ssh root@47.98.203.17 "docker exec youle-dlweb rm -f /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"
# 删除所有调试日志(保留今天,三个子目录)
ssh root@47.98.203.17 "docker exec youle-dlweb sh -c `"find /var/www/html/api/ext/debug/ -name '*.log' ! -name '$today.log' -delete`""
# 删除全部调试日志(含今天,三个子目录)
ssh root@47.98.203.17 @"
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
'
"@
# ── 一键清理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"
"@
```
---
#### 快捷速查表
| 操作 | PowerShell 命令 |
|------|----------------|
| 查看 api/logs 今天日志 | `ssh root@47.98.203.17 "docker exec youle-api cat /var/www/html/logs/$(Get-Date -Format 'yyyy-MM-dd').log"` |
| 查看同步调试日志 | `ssh root@47.98.203.17 "docker exec youle-dlweb tail -50 /var/www/html/api/ext/debug/synchronize/$(Get-Date -Format 'yyyy-MM-dd').log"` |
| 实时跟踪同步日志 | `ssh root@47.98.203.17 "docker exec youle-dlweb tail -f /var/www/html/api/ext/debug/synchronize/$(Get-Date -Format 'yyyy-MM-dd').log"` |
| 清空 api/logs 今天日志 | `ssh root@47.98.203.17 "docker exec youle-api truncate -s 0 /var/www/html/logs/$(Get-Date -Format 'yyyy-MM-dd').log"` |
| 清空同步调试日志 | `ssh root@47.98.203.17 "docker exec youle-dlweb truncate -s 0 /var/www/html/api/ext/debug/synchronize/$(Get-Date -Format 'yyyy-MM-dd').log"` |
| 删除全部调试日志 | `ssh root@47.98.203.17 "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'"` |