1456 lines
49 KiB
Markdown
1456 lines
49 KiB
Markdown
# 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)
|
||
- 域名已解析到服务器 IP(3 个域名: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.ps1(tar 压缩单连接,比 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'"` |
|