Files
youlegames/codes/agent/game-docker/README.md
2026-04-13 17:06:02 +08:00

1456 lines
49 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.
# YouleGames Docker 部署版
> 原项目 `codes/agent/game` 的 Docker 化改造,所有硬编码域名/IP/密码已外部化为环境变量,通过单一 `.env` 文件控制所有配置。
---
## 目录结构
```
game-docker/
├── .env.example # 环境变量模板(部署时复制为 .env
├── docker-compose.yml # Docker Compose 编排8 个服务)
├── deploy.sh # 一键部署脚本
├── init-ssl.sh # SSL 证书首次申请脚本
├── env_config.php # PHP 环境变量加载器api/ 和 dlweb/ 共用)
├── api/ # 网站1: 游戏核心 API 服务源码
├── dlweb/ # 网站2: 代理管理后台源码
├── wxserver_daoqi/ # 网站3: 微信小程序后端源码
├── docker/
│ ├── nginx/
│ │ ├── default.conf.template # Nginx 配置模板envsubst 动态域名注入)
│ │ └── ssl-params.conf # SSL 安全参数
│ ├── api/
│ │ ├── Dockerfile # API 镜像PHP 8.1 + Apache
│ │ └── docker-entrypoint.sh # 启动时 sed 替换 JS 中硬编码域名
│ ├── dlweb/
│ │ ├── Dockerfile # DLWEB 镜像PHP 8.1 + Apache + Redis ext
│ │ └── docker-entrypoint.sh # 启动时 sed 替换 JS/HTML 中硬编码域名
│ ├── wxserver/
│ │ └── Dockerfile # wxserver 镜像Node.js 18 Alpine
│ ├── syncjob/
│ │ └── sync.sh # Synchronize.php 轮询脚本(每 30s
│ ├── cronjob/
│ │ ├── entrypoint.sh # cron 容器入口
│ │ └── daily-task.sh # 每日定时任务(替代 autorun.cmd
│ └── certbot/ # SSL 证书相关
└── game/ # 原始未修改代码备份(不参与部署)
```
---
## 整体架构
```
互联网
┌──────┴──────┐
│ Nginx │ ← SSL 终端 + 域名路由
│ :80 :443 │ 域名通过 .env 注入
└──┬───┬───┬─┘
┌───────────┤ │ ├───────────┐
▼ ▼ │ ▼ │
┌────────────┐ ┌────────┴──┐ ┌──────────┐
│ API │ │ DLWEB │ │ wxserver │
│ PHP 8.1 │ │ PHP 8.1 │ │ Node.js │
│ Apache │ │ Apache │ │ :3000 │
└─────┬──────┘ └─────┬─────┘ └──────────┘
│ │
│ ┌─────────┤ Docker 内网 (youle-net)
│ │ │
│ ▼ │
│ ┌──────────┐ │ ┌───────────┐ ┌───────────┐
│ │ syncjob │◄┼────►│ cronjob │ │ certbot │
│ │ 每30s轮询 │ │ │ 每日4:00 │ │ 12h续签 │
│ └──────────┘ │ └───────────┘ └───────────┘
│ │
▼ ▼
┌──────────────────────────┐ ┌──────────┐
│ MySQL (阿里云 RDS) │ │ Redis │
│ 多实例agent_db / │ │ :6379 │
│ game_db / grade_db │ └──────────┘
└──────────────────────────┘
```
### 服务清单8 个容器)
| 容器名 | 镜像 | 作用 | 端口 |
|--------|------|------|------|
| `youle-nginx` | nginx:alpine | SSL 终端 + 域名路由反向代理 | 80, 443 |
| `youle-api` | php:8.1-apache (自定义) | 游戏核心 API登录/支付/SDK | 8081 (内部) |
| `youle-dlweb` | php:8.1-apache (自定义) | 代理管理后台 | 8082 (内部) |
| `youle-wxserver` | node:18-alpine (自定义) | 微信小程序后端 | 3000 (内部) |
| `youle-syncjob` | alpine:3.19 | 每 30s POST `Synchronize.php`(数据同步) | 无 |
| `youle-cronjob` | alpine:3.19 | 每日凌晨 4:00 执行报表同步 | 无 |
| `youle-redis` | redis:7-alpine | 缓存服务(可选) | 6379 (内部) |
| `youle-certbot` | certbot/certbot | Let's Encrypt SSL 证书自动续签 | 无 |
---
## 快速部署
### 前置要求
- 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. 上传项目到服务器
`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/
```
### 2. 准备环境变量
```bash
cd /opt/youle/game-docker
cp .env.example .env
vim .env
```
**必须修改的关键配置:**
```bash
# 父域名(三个子域名自动推导,无需单独配置)
# 将自动生成: api.<ROOT_DOMAIN> dlapi.<ROOT_DOMAIN> wxapi.<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
```
### 3. 首次申请 SSL 证书
```bash
chmod +x deploy.sh init-ssl.sh
# 先测试(不真正申请,验证域名解析是否正确)
./deploy.sh ssl-init --dry-run
# 正式申请
./deploy.sh ssl-init
```
### 4. 启动所有服务
```bash
./deploy.sh up
```
启动后验证:
```bash
# 查看所有容器状态
./deploy.sh status
# 查看特定服务日志
./deploy.sh logs api
./deploy.sh logs dlweb
./deploy.sh logs syncjob
./deploy.sh logs cronjob
```
### 5. 部署命令速查
| 命令 | 说明 |
|------|------|
| `./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` | 查看证书到期时间 |
---
## 定时任务说明
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
```
### 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
```
---
## 环境变量说明
所有硬编码的域名、数据库地址、密钥都已外部化为环境变量。**修改配置不再需要改代码,只需改 `.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
(唯一必填) │ 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` 中单独覆盖对应变量。
---
## 环境变量加载机制
### 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}` / `${WX_DOMAIN}` 占位符Nginx 容器启动时通过 `envsubst` 自动替换。
---
## 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 天自动更新,无需人工干预。
---
## 数据持久化
以下 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 证书文件 |
---
## 与原版Windows 部署)的区别
| 项目 | 原版 Windows | Docker 版 |
|------|-------------|-----------|
| 环境 | Windows + Apache/XAMPP + Node.js | Docker 容器化 |
| 配置方式 | 硬编码在 PHP/JS/HTML 中 | 统一 `.env` 文件 |
| 域名切换 | 需改 30+ 个文件 | 只改 `.env` 的 3 个域名变量 |
| 数据库密码 | 明文散布在多个配置文件 | 集中在 `.env`(不进版本库) |
| SSL | 手动申请/部署证书 | certbot 自动申请 + 12h 自动续签 |
| Synchronize 轮询 | `HttpRequestService.exe`Windows 服务) | `syncjob` 容器Alpine + curl |
| 每日定时任务 | Windows 计划任务 → `autorun.cmd` | `cronjob` 容器Alpine crond |
| 内网请求 | `localhost:80`(同机 Apache | Docker 内网 `http://dlweb`(零公网流量) |
| PHP 环境变量 | `env_config.php` `env()` 函数 | `env()` 优先读容器环境变量,回退 `.env` 文件 |
| 微信支付配置 | 硬编码在 `WxPay.Config.php` | `define()` + class const`env()` 动态读取 |
| 游戏服务器列表 | 硬编码在 `game.config.php` | 支持外部 JSON 文件覆盖(`GAME_SERVERS_CONFIG_FILE` |
---
## 常见运维操作
### 场景一:更换域名
当需要将服务迁移到新域名时(例如 `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` |
| `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` |
> **子域名不符合标准规律时**(如使用完全不同的前缀),在 `.env` 中单独覆盖对应变量即可,优先级高于自动推导:
> ```bash
> DLWEB_DOMAIN=dl-manage.newdomain.com # 覆盖单个子域名
> ```
> **其他独立 URL 变量**`DLWEB_SETTLE_URL`、`DLWEB_PROXY_URL`、`QQ_CALLBACK_URL` 等)仍需在 `.env` 中手动配置,详见 `.env.example` 中的注释。
**2. DNS 解析**
确保新域名已指向服务器 IP
```bash
# 验证 DNS 解析
nslookup api.newdomain.com
nslookup dlapi.newdomain.com
nslookup wxapi.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. 更新微信后台配置**
| 微信后台 | 配置项 | 新值 |
|---------|--------|------|
| 小程序后台 | request 合法域名 | `https://wxapi.newdomain.com` |
| 小程序后台 | 业务域名 | `wxapi.newdomain.com` |
| 公众号后台 | 业务域名 / JS接口安全域名 | `api.newdomain.com` |
| 公众号后台 | 网页授权域名 | `wxapi.newdomain.com` |
| 微信支付后台 | 支付授权目录 | `https://dlapi.newdomain.com/` |
---
### 场景二:更换数据库地址
当数据库实例迁移(例如 RDS 升级、切换区域)时:
**1. 修改 `.env` 中对应的数据库变量**
```bash
vim .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 / SynchronizeReportData.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
# 如果只改了 API 数据库
docker compose restart api
# 如果只改了 DLWEB 数据库
docker compose restart dlweb
# 如果改了外部游戏库(影响同步任务)
docker compose restart dlweb syncjob cronjob
# 如果改了多个,直接全部重启
./deploy.sh restart
```
**3. 验证连接**
```bash
# 查看 API 日志是否有数据库连接错误
docker logs --tail 20 youle-api
# 查看 DLWEB 日志
docker logs --tail 20 youle-dlweb
# 查看同步任务是否正常
docker logs --tail 10 youle-syncjob
```
> **提示:** 如果新数据库有 IP 白名单限制,需要将 Docker 宿主机的公网 IP 加入 RDS 白名单。
---
### 场景三:更换服务器(整体迁移)
将整个 Docker 部署迁移到新服务器:
**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
# 复制并修改配置(新服务器 IP 可能不同)
cp .env.example .env
vim .env
```
**4. 确认修改项**
| 检查项 | 是否需要改 | 说明 |
|--------|-----------|------|
| 域名(`*_DOMAIN` | 域名不变则不改 | DNS 需指向新服务器 IP |
| 数据库地址(`*_DB_HOST` | 通常不改 | RDS 地址不变,但需将新服务器 IP 加入白名单 |
| Redis 地址 | 不改 | Docker 内置 Redis随容器迁移 |
| 微信/支付配置 | 不改 | AppID/Secret 与服务器无关 |
| 游戏服务器查询地址 | 看情况 | `GAME_SERVER_QUERY_URL` 如果游戏服务器也迁移了需改 |
| IP 白名单 | 可能需改 | `INTERNAL_WHITELIST` 加入新 IP |
**5. 启动服务**
```bash
chmod +x deploy.sh init-ssl.sh
# 域名未变DNS 改指向后直接启动
./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://wxapi.yourdomain.com/
# 定时任务运行正常
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
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` 中的变量 | 重启命令 | 额外操作 |
|---------|---------------------|---------|---------|
| 更换域名 | `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 容器标准输出日志**`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
# 查看最近 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
# 查看某时间段之后的日志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
```
### 调整同步频率
```bash
# 修改 .env
SYNC_INTERVAL=15 # 15 秒一次
SYNC_PROCESSCOUNT=500 # 每次处理 500 条
# 重启 syncjob
docker compose restart syncjob
```
### 调整每日任务执行时间
```bash
# 修改 .env
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'"` |