From f98091bb54e2921907a68fa7b0aba46336637abc Mon Sep 17 00:00:00 2001 From: Joywayer Date: Tue, 14 Apr 2026 12:23:31 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=8B=86=E5=88=86=20README.md=20?= =?UTF-8?q?=E4=B8=BA=E5=A4=9A=E4=B8=AA=E5=AD=90=E6=96=87=E6=A1=A3=EF=BC=8C?= =?UTF-8?q?README=20=E7=AE=80=E5=8C=96=E4=B8=BA=E6=9E=B6=E6=9E=84=E5=BC=95?= =?UTF-8?q?=E5=AF=BC=E5=A4=A7=E7=BA=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- codes/agent/game-docker/README.md | 1669 +---------------- codes/agent/game-docker/docs/01-deployment.md | 249 +++ .../game-docker/docs/02-scheduled-tasks.md | 110 ++ .../game-docker/docs/03-env-variables.md | 141 ++ codes/agent/game-docker/docs/04-ssl.md | 68 + codes/agent/game-docker/docs/05-operations.md | 319 ++++ codes/agent/game-docker/docs/06-logging.md | 310 +++ codes/agent/game-docker/docs/07-uninstall.md | 144 ++ .../game-docker/docs/08-database-remote.md | 85 + 9 files changed, 1459 insertions(+), 1636 deletions(-) create mode 100644 codes/agent/game-docker/docs/01-deployment.md create mode 100644 codes/agent/game-docker/docs/02-scheduled-tasks.md create mode 100644 codes/agent/game-docker/docs/03-env-variables.md create mode 100644 codes/agent/game-docker/docs/04-ssl.md create mode 100644 codes/agent/game-docker/docs/05-operations.md create mode 100644 codes/agent/game-docker/docs/06-logging.md create mode 100644 codes/agent/game-docker/docs/07-uninstall.md create mode 100644 codes/agent/game-docker/docs/08-database-remote.md diff --git a/codes/agent/game-docker/README.md b/codes/agent/game-docker/README.md index 3a37c08..851d181 100644 --- a/codes/agent/game-docker/README.md +++ b/codes/agent/game-docker/README.md @@ -12,29 +12,20 @@ game-docker/ ├── docker-compose.yml # Docker Compose 编排(8 个服务) ├── deploy.sh # 一键部署脚本 ├── init-ssl.sh # SSL 证书首次申请脚本 +├── sync.ps1 # Windows 本地 → 服务器文件同步脚本 ├── 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/ # Nginx 配置模板 + SSL 参数 +│ ├── api/ # API 镜像(PHP 8.1 + Apache) +│ ├── dlweb/ # DLWEB 镜像(PHP 8.1 + Apache + Redis ext) +│ ├── wxserver/ # wxserver 镜像(Node.js 18 Alpine) +│ ├── syncjob/ # Synchronize.php 轮询脚本(每 30s) +│ ├── cronjob/ # 每日定时任务(替代 autorun.cmd) +│ └── certbot/ # SSL 证书相关 +└── docs/ # 详细文档(见下方文档导航) ``` --- @@ -87,1649 +78,55 @@ game-docker/ --- -## 快速部署 - -### 前置要求 - -- 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. 检查并修复行尾符(LF) - -> **为什么需要这步?** Windows 的 Git 默认 `core.autocrlf=true`,可能将脚本文件写成 CRLF。CRLF 格式的 shell 脚本在 Linux 容器中会报 `not found` / `syntax error` 错误,导致容器无法启动。 - -在上传前运行 `fix-lf.ps1`,自动扫描所有关键文件并修复: - -```powershell -.\fix-lf.ps1 -``` - -> **根本修复(一次性,之后无需再跑):** 执行以下命令让 `.gitattributes` 永久接管行尾符,此后任何机器 clone 均自动生效: -> ```powershell -> git config core.autocrlf false -> git add --renormalize . -> git commit -m "fix: normalize all line endings to LF" -> git push -> ``` - ---- - -### 2. 上传项目到服务器 - -将 `game-docker` 目录上传到服务器 `/opt/youle/` 下: - -```powershell -# 推荐:使用 sync.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/ -``` - -### 3. 准备环境变量 - -```bash -cd /opt/youle/game-docker -cp .env.example .env -vim .env -``` - -**必须修改的关键配置:** - -```bash -# 父域名(三个子域名自动推导,无需单独配置) -# 将自动生成: api. dlapi. -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 -``` - -### 4. 首次申请 SSL 证书 - -```bash -chmod +x deploy.sh init-ssl.sh - -# 先测试(不真正申请,验证域名解析是否正确) -./deploy.sh ssl-init --dry-run - -# 正式申请 -./deploy.sh ssl-init -``` - -### 5. 启动所有服务 - -```bash -./deploy.sh up -``` - -启动后验证: - -```bash -# 查看所有容器状态 -./deploy.sh status - -# 查看特定服务日志 -./deploy.sh logs api -./deploy.sh logs dlweb -./deploy.sh logs syncjob -./deploy.sh logs cronjob -``` - -### 6. 部署命令速查 - -| 命令 | 说明 | -|------|------| -| `./deploy.sh up` | 构建并启动所有服务 | -| `./deploy.sh down` | 停止并移除所有容器 | -| `./deploy.sh restart` | 重启所有服务 | -| `./deploy.sh rebuild` | 无缓存重建所有镜像 | -| `./deploy.sh rebuild api` | 只重建指定服务 | -| `./deploy.sh logs [service]` | 查看日志(支持 `-f` 实时跟踪) | -| `./deploy.sh status` | 查看容器运行状态 | -| `./deploy.sh ssl-init` | 首次申请 SSL 证书 | -| `./deploy.sh ssl-init --staging` | 用 Let's Encrypt 测试环境申请 | -| `./deploy.sh ssl-renew` | 手动续签证书 | -| `./deploy.sh ssl-status` | 查看证书到期时间 | - ---- - -## 定时任务说明 - -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. → Nginx 网站1(含 wxserver /wx/ 路由) -(唯一必填) │ DLWEB_DOMAIN = dlapi. → Nginx 网站2 - │ SITE_API_URL = https://api. - │ SITE_PAY_NOTIFY_URL = https://api. - │ SITE_OPEN_URL = http://open. - │ DLWEB_DL_API_V3_URL = https://dlapi. -``` - -> 推导由 `docker-compose.yml` 的 `environment:` 块完成,容器内所有派生变量均无需手动配置。如子域名不符合 `<前缀>.` 规律,可在 `.env` 中单独覆盖对应变量。 - ---- - -## 环境变量加载机制 - -### PHP 服务(env_config.php) - -所有 PHP 文件通过 `env($key, $default)` 函数读取配置: - -```php -// 优先读 OS 环境变量(Docker 场景),回退读 .env 文件 -$host = env('API_DB_HOST', 'localhost'); -``` - -加载优先级:Docker 容器环境变量(`docker-compose env_file`)> `.env` 文件 > 代码默认值。 - -### Node.js 服务(wxserver_daoqi) - -直接使用 `process.env.VARIABLE_NAME`,由 `docker-compose env_file` 注入。 - -### 前端 JS / HTML - -前端静态文件无法读取环境变量,通过 Docker entrypoint 脚本在容器启动时用 `sed` 替换硬编码域名: - -- `docker/api/docker-entrypoint.sh` — 替换 API 服务中的 JS 文件 -- `docker/dlweb/docker-entrypoint.sh` — 替换 DLWEB 服务中的 30+ 个 JS/HTML 文件 - -### Nginx 域名注入 - -`default.conf.template` 使用 `${API_DOMAIN}` / `${DLWEB_DOMAIN}` 占位符,Nginx 容器启动时通过 `envsubst` 自动替换。wxserver 不独立占用域名,通过 `api.xxx/wx/*` 路由接入。 - ---- - -## 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 个域名变量 | +| 域名切换 | 需改 30+ 个文件 | 只改 `.env` 的 1 个域名变量 | | 数据库密码 | 明文散布在多个配置文件 | 集中在 `.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` | -| `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 -``` - -**3. 重新申请 SSL 证书** - -```bash -# 测试验证(不消耗申请限额) -./deploy.sh ssl-init --staging - -# 正式申请 -./deploy.sh ssl-init -``` - -**4. 重启所有服务** - -```bash -./deploy.sh restart -``` - -重启时会自动完成: -- Nginx 使用新域名的 `server_name` 和 SSL 证书 -- `docker-entrypoint.sh` 用新域名替换 JS/HTML 中的硬编码 URL -- PHP `env()` 读取新的环境变量值 - -**5. 更新微信后台配置** - -更换域名后,必须同步更新微信三个后台的域名白名单,否则对应功能会直接报错或静默失败。 - -> **关键路由说明:** Nginx 在 `api.newdomain.com` 上配置了 `/wx/` 前缀路由——以 `/wx/` 开头的请求会被反向代理到 wxserver(Node.js),其余请求仍由 PHP API 处理。wxserver 所有接口(包括小程序登录、公众号 OAuth)均通过 `api.newdomain.com/wx/*` 访问。 +| 文档 | 内容 | +|------|------| +| [快速部署](./docs/01-deployment.md) | SSH 密钥配置、上传文件、环境变量准备、首次部署完整步骤 | +| [定时任务说明](./docs/02-scheduled-tasks.md) | syncjob / cronjob 原理、配置参数、日志查看 | +| [环境变量配置](./docs/03-env-variables.md) | 所有变量分组说明、域名推导关系、加载机制、文件修改生效方式 | +| [SSL 证书管理](./docs/04-ssl.md) | 首次申请、续签、更换域名后重新申请 | +| [常见运维操作](./docs/05-operations.md) | 更换域名、更换数据库、服务器迁移、服务管理、数据持久化 | +| [日志管理](./docs/06-logging.md) | 日志位置总览、查看命令、清除命令、Windows 远程操作 | +| [卸载和清理](./docs/07-uninstall.md) | 停止、删除容器、彻底清理的分级操作 | +| [数据库远程管理](./docs/08-database-remote.md) | Navicat SSH 隧道配置、RDS 实例对应关系、新设备接入 | --- -#### 5.1 微信小程序后台 - -> **入口:** [mp.weixin.qq.com](https://mp.weixin.qq.com) → 开发 → 开发管理 → 开发设置 → 服务器域名 - -| 配置项 | 作用 | 新值 | 不更新时的现象 | -|--------|------|------|--------------| -| **request 合法域名** | 小程序调用 `wx.request()` 请求 wxserver 后端接口 | `https://api.newdomain.com` | `wx.request` 直接报 `invalid url`,所有网络请求失败 | -| **业务域名** | 小程序 `` 组件加载公众号授权页(获取永久头像流程) | `api.newdomain.com` | 打开 web-view 时提示"不在业务域名列表中",授权页无法加载 | - -> **注意:** 小程序域名配置每月只能修改 5 次,且每项域名必须已备案并启用 HTTPS。 - ---- - -#### 5.2 微信公众号后台 - -> **入口:** [mp.weixin.qq.com](https://mp.weixin.qq.com) → 设置与开发 → 公众号设置 → 功能设置 - -**① 业务域名** - -| 配置值 | 用途 | -|--------|------| -| `api.newdomain.com` | 在公众号内打开的网页所在域名 | - -用户在微信内置浏览器中打开的游戏支付页(`api.newdomain.com`)必须在业务域名列表内,否则页面会被提示"域名不合法"或无法正常访问。 - -> **验证文件:** 添加业务域名时,微信要求在该域名根目录放置 `.txt` 验证文件。将微信提供的文件(如 `MP_verify_xxx.txt`)放入 `api/` 根目录,然后 `./deploy.sh rebuild api`。 - ---- - -**② 网页授权域名(最重要)** - -| 配置值 | 用途 | -|--------|------| -| `api.newdomain.com` | 公众号 OAuth2 授权回调域名 | - -**为什么是 `api.newdomain.com`:** -小程序内嵌 web-view 跳转到 `https://api.newdomain.com/wx/auth/oa/login`,Nginx `/wx/` 路由将此请求反向代理到 wxserver 的 `/auth/oa/login`,wxserver 再把用户重定向到微信授权页,`redirect_uri` 为 `https://api.newdomain.com/wx/auth/oa/callback`(通过 `WX_OA_REDIRECT_DOMAIN` 环境变量控制)。微信要求 `redirect_uri` 的域名必须在公众号后台的授权域名列表内,所以填 `api.newdomain.com`。 - -不更新的后果:授权跳转时微信直接拦截,显示 "redirect_uri 域名与后台配置不一致" 错误,永久头像获取功能完全不可用。 - -> **⚠️ 远程配置也需要同步修改:** `WX_OA_REDIRECT_DOMAIN` 未配置时,wxserver 会从远程配置文件读取 `minipro_api_url` key 作为回调域名(见 `wxserver_daoqi/config/index.js`)。即使 `.env` 中已正确填写 `WX_OA_REDIRECT_DOMAIN`,仍建议同步更新远程配置,避免环境变量配置丢失时出现静默回退至旧域名的问题。 -> -> 远程配置文件地址(Gitee Raw):`https://gitee.com/daoqijuyou/config/raw/master/update_jsonv2.txt` -> 找到 `minipro_api_url` 字段,更新值为:`api.newdomain.com/wx`(不含 `https://`,wxserver 会自动补充) - -> **验证文件:** 添加授权域名时,微信要求在该域名根目录放置一个 `.txt` 验证文件。将微信提供的验证文件(如 `MP_verify_xxx.txt`)直接放入 `api/` 根目录,然后重建 api 镜像使其生效: -> ```bash -> ./deploy.sh rebuild api -> ``` - ---- - -**② JS 接口安全域名** - -| 配置值 | 用途 | -|--------|------| -| `api.newdomain.com` | 微信 JS-SDK(`wx.config()`)页面所在域名 | - -**为什么是 `api.newdomain.com`:** -API 服务(`youle-api`)的 PHP 页面使用 jsapi_ticket 签名,生成 `wx.config()` 参数,使用微信 JS-SDK 调起支付(`WeixinJSBridge.invoke(getBrandWCPayRequest)`)。微信要求调用 JS-SDK 的页面所在域名必须在安全域名列表内。 - -不更新的后果:`wx.config()` 签名验证失败,微信支付按钮无法唤起支付界面,用户点击支付无反应。 - ---- - -#### 5.3 微信支付商户后台 - -> **入口:** [pay.weixin.qq.com](https://pay.weixin.qq.com) → 账户中心 → 商户信息 → 支付配置 → JSAPI 支付授权目录 - -| 配置值 | 用途 | -|--------|------| -| `https://api.newdomain.com/` | JSAPI 支付页面所在目录(必须包含末尾斜杠) | - -**为什么是 `api.newdomain.com`:** -JSAPI 支付页面(`api/source/apis/pay.php`)运行在 `api.newdomain.com` 域名下,统一下单时的 `notify_url`(支付回调通知地址)也由 `SITE_PAY_NOTIFY_URL`(默认值 `https://api.newdomain.com`)指定。微信支付要求发起支付的页面域名必须在授权目录白名单内。 - -不更新的后果:下单时提示"当前URL未注册",JSAPI 支付彻底无法使用。 - ---- - -#### 配置清单汇总 - -| 平台 | 入口页面 | 配置项 | 填写值 | -|------|---------|--------|--------| -| **微信小程序后台** | 开发 → 开发管理 → 开发设置 → 服务器域名 | request 合法域名 | `https://api.newdomain.com` | -| **微信小程序后台** | 开发 → 开发管理 → 开发设置 → 服务器域名 | 业务域名 | `api.newdomain.com` | -| **微信公众号后台** | 设置与开发 → 公众号设置 → 功能设置 | 业务域名 | `api.newdomain.com` | -| **微信公众号后台** | 设置与开发 → 公众号设置 → 功能设置 | 网页授权域名 | `api.newdomain.com` | -| **微信公众号后台** | 设置与开发 → 公众号设置 → 功能设置 | JS 接口安全域名 | `api.newdomain.com` | -| **微信支付商户后台** | 账户中心 → 商户信息 → 支付配置 | JSAPI 支付授权目录 | `https://api.newdomain.com/` | - ---- - -### 场景二:更换数据库地址 - -当数据库实例迁移(例如 RDS 升级、切换区域)时: - -**1. 修改 `.env` 中对应的数据库变量** +## 快速启动 ```bash -vim .env -``` +# 1. 上传项目(Windows 本地执行) +.\sync.ps1 -Mode full -按数据库分组: +# 2. 进入服务器 +ssh root@47.98.203.17 +cd /opt/youle/game-docker -| 数据库 | 需修改的变量 | 使用者 | -|--------|-------------|--------| -| 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 可能不同) +# 3. 配置环境变量 cp .env.example .env -vim .env -``` +vim .env # 至少填写 ROOT_DOMAIN、DB 连接、微信配置 -**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 # 新服务器需重新申请证书 +# 4. 首次申请 SSL 并启动 +./deploy.sh ssl-init ./deploy.sh up -# 域名变了:参照「场景一:更换域名」 -``` - -**6. 验证所有服务** - -```bash -# 容器状态 -./deploy.sh status - -# 各服务健康检查 -curl -k https://api.yourdomain.com/ -curl -k https://dlapi.yourdomain.com/ -curl -k https://api.yourdomain.com/wx/api/login # wxserver 健康检查 - -# 定时任务运行正常 -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 -# 或 +# 5. 确认状态 ./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 白名单 | - ---- - -### 场景:修改本地文件后如何生效 - -不同文件在镜像中的处理方式不同,决定了改完代码后需要执行哪种操作。 - -#### 文件 → 操作对照表 - -| 文件路径 | 所属容器 | 载入方式 | 修改后需要执行的操作 | -|---------|---------|---------|-------------------| -| `api/**` | `youle-api` | `COPY` 进镜像 | `./deploy.sh rebuild api` 重建镜像 | -| `dlweb/**` | `youle-dlweb` | `COPY` 进镜像 | `./deploy.sh rebuild dlweb` 重建镜像 | -| `wxserver_daoqi/**` | `youle-wxserver` | `COPY` 进镜像 | `./deploy.sh rebuild wxserver` 重建镜像 | -| `env_config.php` | `youle-api` / `youle-dlweb` | `COPY` 进镜像 | `./deploy.sh rebuild api dlweb` 重建两个镜像 | -| `docker/api/Dockerfile` | `youle-api` | 构建定义 | `./deploy.sh rebuild api` | -| `docker/api/docker-entrypoint.sh` | `youle-api` | `COPY` 进镜像 | `./deploy.sh rebuild api` | -| `docker/dlweb/Dockerfile` | `youle-dlweb` | 构建定义 | `./deploy.sh rebuild dlweb` | -| `docker/dlweb/docker-entrypoint.sh` | `youle-dlweb` | `COPY` 进镜像 | `./deploy.sh rebuild dlweb` | -| `docker/wxserver/Dockerfile` | `youle-wxserver` | 构建定义 | `./deploy.sh rebuild wxserver` | -| `docker/nginx/default.conf.template` | `youle-nginx` | volume 挂载(`:ro`) | `scp` 上传 → `docker restart youle-nginx` | -| `docker/nginx/ssl-params.conf` | `youle-nginx` | volume 挂载(`:ro`) | `scp` 上传 → `docker restart youle-nginx` | -| `docker/syncjob/sync.sh` | `youle-syncjob` | volume 挂载(`:ro`) | `scp` 上传 → `docker restart youle-syncjob` | -| `docker/cronjob/entrypoint.sh` | `youle-cronjob` | volume 挂载(`:ro`) | `scp` 上传 → `docker restart youle-cronjob` | -| `docker/cronjob/daily-task.sh` | `youle-cronjob` | volume 挂载(`:ro`) | `scp` 上传 → `docker restart youle-cronjob` | -| `docker-compose.yml` | 所有容器 | compose 编排 | `docker compose up -d`(有变动的容器自动重建) | -| `.env` | 所有容器 | compose `env_file` | `docker compose up -d`(重新注入环境变量) | - -> **COPY vs 挂载的区别:** -> - **`COPY` 进镜像** — 文件被打进 Docker 镜像层,修改后必须重新 build 才能生效,容器内的文件是镜像的副本 -> - **volume 挂载** — 容器启动时直接挂载宿主机文件,只需 `scp` 传到服务器后重启容器即可,**无需重建镜像** - -#### 操作命令速查 - -```bash -# ── 需要重建镜像的操作(修改源码/Dockerfile/entrypoint 等 COPY 文件)── - -# 重建单个服务(无缓存,约 1-5 分钟) -./deploy.sh rebuild api # 只重建 API -./deploy.sh rebuild dlweb # 只重建 DLWEB -./deploy.sh rebuild wxserver # 只重建 wxserver -./deploy.sh rebuild api dlweb # 同时重建多个 - -# 重建所有服务 -./deploy.sh rebuild - - -# ── 只需 scp + 重启的操作(修改 volume 挂载文件,秒级生效)── - -# Nginx 配置 -scp docker/nginx/ssl-params.conf root@47.98.203.17:/opt/youle/game-docker/docker/nginx/ssl-params.conf -scp docker/nginx/default.conf.template root@47.98.203.17:/opt/youle/game-docker/docker/nginx/default.conf.template -ssh root@47.98.203.17 "docker restart youle-nginx" - -# syncjob 脚本 -scp docker/syncjob/sync.sh root@47.98.203.17:/opt/youle/game-docker/docker/syncjob/sync.sh -ssh root@47.98.203.17 "docker restart youle-syncjob" - -# cronjob 脚本 -scp docker/cronjob/entrypoint.sh root@47.98.203.17:/opt/youle/game-docker/docker/cronjob/entrypoint.sh -scp docker/cronjob/daily-task.sh root@47.98.203.17:/opt/youle/game-docker/docker/cronjob/daily-task.sh -ssh root@47.98.203.17 "docker restart youle-cronjob" - - -# ── .env / docker-compose.yml 变更 ── - -ssh root@47.98.203.17 "cd /opt/youle/game-docker && docker compose up -d" -# compose 会对比配置差异,只重启有变更的容器 -``` - ---- - -### 场景七:查看日志 - -本项目日志分为两类:**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 -# 或直接删除证书 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. 日志清理速查 - -> 以下命令在 **SSH 登录服务器后**直接执行(无需 `ssh root@...` 前缀)。 - -**查看日志** - -| 目标 | 命令 | -|------|------| -| nginx 访问日志(末尾50行) | `docker logs --tail 50 youle-nginx` | -| nginx 访问日志(实时跟踪) | `docker logs -f youle-nginx` | -| wxserver 日志(末尾50行) | `docker logs --tail 50 youle-wxserver` | -| wxserver 日志(实时跟踪) | `docker logs -f youle-wxserver` | -| API PHP 错误日志(末尾50行) | `docker exec youle-api tail -50 /var/log/apache2/php_errors.log` | -| API 业务日志_今天(末尾50行) | `docker exec youle-api tail -50 /var/www/html/logs/$(date +%Y-%m-%d).log` | -| API 业务日志_今天(完整) | `docker exec youle-api cat /var/www/html/logs/$(date +%Y-%m-%d).log` | -| API 业务日志_今天(实时跟踪) | `docker exec youle-api tail -f /var/www/html/logs/$(date +%Y-%m-%d).log` | -| 列出 API 业务日志文件 | `docker exec youle-api ls -lh /var/www/html/logs/` | -| 同步调试日志_今天(末尾50行) | `docker exec youle-dlweb tail -50 /var/www/html/api/ext/debug/synchronize/$(date +%Y-%m-%d).log` | -| 同步调试日志_今天(实时跟踪) | `docker exec youle-dlweb tail -f /var/www/html/api/ext/debug/synchronize/$(date +%Y-%m-%d).log` | -| 列出同步调试日志文件 | `docker exec youle-dlweb ls -lh /var/www/html/api/ext/debug/synchronize/` | -| syncjob 任务日志(末尾50行) | `docker logs --tail 50 youle-syncjob` | -| cronjob 任务日志(末尾50行) | `docker logs --tail 50 youle-cronjob` | - -**清理日志** - -| 目标 | 命令 | -|------|------| -| 清空 nginx docker logs | `truncate -s 0 $(docker inspect --format='{{.LogPath}}' youle-nginx)` | -| 清空 wxserver docker logs | `truncate -s 0 $(docker inspect --format='{{.LogPath}}' youle-wxserver)` | -| 清空 API docker logs | `truncate -s 0 $(docker inspect --format='{{.LogPath}}' youle-api)` | -| 清空 dlweb docker logs | `truncate -s 0 $(docker inspect --format='{{.LogPath}}' youle-dlweb)` | -| 清空所有容器 docker logs | `for n in youle-nginx youle-api youle-dlweb youle-wxserver youle-syncjob youle-cronjob youle-redis youle-certbot; do truncate -s 0 $(docker inspect --format='{{.LogPath}}' $n 2>/dev/null) 2>/dev/null; done` | -| 清空今天 API 业务日志 | `docker exec youle-api truncate -s 0 /var/www/html/logs/$(date +%Y-%m-%d).log` | -| 清空今天同步调试日志 | `docker exec youle-dlweb truncate -s 0 /var/www/html/api/ext/debug/synchronize/$(date +%Y-%m-%d).log` | -| 删除 API 全部历史日志 | `docker exec youle-api sh -c 'rm -f /var/www/html/logs/*.log'` | -| 删除调试日志 30 天前旧文件 | `docker exec youle-dlweb find /var/www/html/api/ext/debug/ -name '*.log' -mtime +30 -delete` | -| 删除调试日志全部文件 | `docker exec youle-dlweb sh -c 'rm -f /var/www/html/api/ext/debug/synchronize/*.log /var/www/html/api/ext/debug/SynchronizeReportData/*.log /var/www/html/api/ext/debug/autotask/*.log'` | -| 一键清理全部日志 | `/opt/youle/game-docker/clear-logs.sh` | -``` - ---- - -### 场景九:从 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'"` | - -## 数据库远程管理(Navicat SSH 隧道) - -> RDS 白名单仅开放服务器 `47.98.203.17`,任何设备需通过 SSH 隧道访问数据库,无需开放公网 IP,安全可控。 - -### 原理 - -``` -本机 Navicat ──SSH加密隧道──▶ 47.98.203.17 ──内网──▶ RDS MySQL -``` - -### Navicat 连接配置(以 agent_db 为例) - -#### 第一步:SSH 标签页 - -| 字段 | 值 | -|------|----| -| 使用 SSH 通道 | ✅ 勾选 | -| 主机 | `47.98.203.17` | -| 端口 | `22` | -| 用户名 | `root` | -| 验证方法 | **公钥** | -| 私钥文件 | `C:\Users\{你的用户名}\.ssh\id_ed25519` | - -> **注意**:当前服务器已授权的密钥为 `id_ed25519`(标识 `youle-deploy`),选错密钥会导致认证失败。 - -#### 第二步:常规标签页 - -| 字段 | 值 | -|------|----| -| 主机名/IP | `rm-bp1btyuwq77591x0jpo.mysql.rds.aliyuncs.com` | -| 端口 | `3306` | -| 用户名 | `games` | -| 密码 | `Games0791!!` | -| 数据库 | `agent_db`(可留空后再选) | - -> ⚠️ **常见错误(2013 错误)**:常规标签的主机名填了 `127.0.0.1` 或 `localhost`,会连接到服务器本机而非 RDS,导致握手失败。必须填 RDS 完整域名。 - -#### 数据库与 RDS 实例对应关系 - -| 数据库 | RDS 主机 | -|--------|---------| -| `agent_db`、`agent_db_temp`、`game_field`、`youlehudong` | `rm-bp1btyuwq77591x0jpo.mysql.rds.aliyuncs.com` | -| `game_db`、`grade_db` | `rm-bp1749tfxu2rpq670lo.mysql.rds.aliyuncs.com` | - -### 新设备接入 - -在新设备上执行以下步骤: - -```powershell -# 1. 生成密钥对(如没有) -ssh-keygen -t ed25519 -C "设备标识备注" - -# 2. 查看公钥内容 -Get-Content "$env:USERPROFILE\.ssh\id_ed25519.pub" -``` - -将公钥内容追加到服务器: - -```bash -ssh root@47.98.203.17 "echo 'ssh-ed25519 AAAA...你的公钥内容...' >> ~/.ssh/authorized_keys" -``` - -之后 Navicat SSH 标签填写该设备的私钥路径即可。 - -### 命令行手动隧道(可选) - -如需在命令行工具(如 mysql CLI)中使用,可手动建立隧道: - -```bash -# 建立隧道(保持此终端运行,另开终端连接) -ssh -L 3307:rm-bp1btyuwq77591x0jpo.mysql.rds.aliyuncs.com:3306 root@47.98.203.17 -N - -# 另开终端,连接本地转发端口 -mysql -h 127.0.0.1 -P 3307 -u games -p agent_db -``` +> 详细步骤见 [快速部署](./docs/01-deployment.md)。 \ No newline at end of file diff --git a/codes/agent/game-docker/docs/01-deployment.md b/codes/agent/game-docker/docs/01-deployment.md new file mode 100644 index 0000000..b93a088 --- /dev/null +++ b/codes/agent/game-docker/docs/01-deployment.md @@ -0,0 +1,249 @@ +# 快速部署指南 + +> 首次将 YouleGames Docker 版部署到服务器的完整步骤。 + +--- + +## 前置要求 + +- 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:检查并修复行尾符(LF) + +> **为什么需要这步?** Windows 的 Git 默认 `core.autocrlf=true`,可能将脚本文件写成 CRLF。CRLF 格式的 shell 脚本在 Linux 容器中会报 `not found` / `syntax error` 错误,导致容器无法启动。 + +在上传前运行 `fix-lf.ps1`,自动扫描所有关键文件并修复: + +```powershell +.\fix-lf.ps1 +``` + +> **根本修复(一次性,之后无需再跑):** 执行以下命令让 `.gitattributes` 永久接管行尾符,此后任何机器 clone 均自动生效: +> ```powershell +> git config core.autocrlf false +> git add --renormalize . +> git commit -m "fix: normalize all line endings to LF" +> git push +> ``` + +--- + +## 步骤 2:上传项目到服务器 + +将 `game-docker` 目录上传到服务器 `/opt/youle/` 下: + +```powershell +# 推荐:使用 sync.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/ +``` + +--- + +## 步骤 3:准备环境变量 + +```bash +cd /opt/youle/game-docker +cp .env.example .env +vim .env +``` + +**必须修改的关键配置:** + +```bash +# 父域名(三个子域名自动推导,无需单独配置) +# 将自动生成: api. dlapi. +ROOT_DOMAIN=yourdomain.com + +# 数据库(各服务数据库连接) +API_DB_HOST=your-rds-host +API_DB_PASSWORD=your-password +DLWEB_DB_HOST=your-rds-host +DLWEB_DB_PASSWORD=your-password +# ... 其他数据库配置 + +# 微信配置 +WX_MINI_APPID=your-appid +WX_MINI_APPSECRET=your-secret +WX_PAY_MCHID=your-mchid +WX_PAY_KEY=your-key + +# SSL 邮箱 +SSL_EMAIL=your-email@example.com +``` + +> 完整变量说明见 [环境变量配置](./03-env-variables.md)。 + +--- + +## 步骤 4:首次申请 SSL 证书 + +```bash +chmod +x deploy.sh init-ssl.sh + +# 先测试(不真正申请,验证域名解析是否正确) +./deploy.sh ssl-init --dry-run + +# 正式申请 +./deploy.sh ssl-init +``` + +> SSL 证书详细管理见 [SSL 证书管理](./04-ssl.md)。 + +--- + +## 步骤 5:启动所有服务 + +```bash +./deploy.sh up +``` + +启动后验证: + +```bash +# 查看所有容器状态 +./deploy.sh status + +# 查看特定服务日志 +./deploy.sh logs api +./deploy.sh logs dlweb +./deploy.sh logs syncjob +./deploy.sh logs cronjob +``` + +--- + +## 步骤 6:部署命令速查 + +| 命令 | 说明 | +|------|------| +| `./deploy.sh up` | 构建并启动所有服务 | +| `./deploy.sh down` | 停止并移除所有容器 | +| `./deploy.sh restart` | 重启所有服务 | +| `./deploy.sh rebuild` | 无缓存重建所有镜像 | +| `./deploy.sh rebuild api` | 只重建指定服务 | +| `./deploy.sh logs [service]` | 查看日志(支持 `-f` 实时跟踪) | +| `./deploy.sh status` | 查看容器运行状态 | +| `./deploy.sh ssl-init` | 首次申请 SSL 证书 | +| `./deploy.sh ssl-init --staging` | 用 Let's Encrypt 测试环境申请 | +| `./deploy.sh ssl-renew` | 手动续签证书 | +| `./deploy.sh ssl-status` | 查看证书到期时间 | diff --git a/codes/agent/game-docker/docs/02-scheduled-tasks.md b/codes/agent/game-docker/docs/02-scheduled-tasks.md new file mode 100644 index 0000000..113462f --- /dev/null +++ b/codes/agent/game-docker/docs/02-scheduled-tasks.md @@ -0,0 +1,110 @@ +# 定时任务说明 + +Docker 部署包含两个定时任务容器,替代原 Windows 环境的 `HttpRequestService.exe` 和 `autorun.cmd`。 + +--- + +## syncjob — 实时同步任务 + +**替代:** Windows `HttpRequestService.exe`(通过 `HttpRequest.exe.json` 配置) + +**作用:** 每 30 秒 POST 请求 `dlweb/ext/Synchronize.php`,从游戏数据库 `ct_user_process_log` 表消费未处理日志,将玩家/代理数据同步到代理后台数据库。 + +**运行方式:** 通过 Docker 内网直连 `http://dlweb/ext/Synchronize.php`,不经过公网域名,零流量消耗。 + +### 可配置项(`.env`) + +```bash +# 轮询间隔(秒),默认 30 +SYNC_INTERVAL=30 + +# 每次处理的日志条数,默认 200 +SYNC_PROCESSCOUNT=200 +``` + +### 查看同步日志 + +```bash +./deploy.sh logs syncjob +# 或实时查看 +docker logs -f youle-syncjob +``` + +### 调整同步频率 + +```bash +# 修改 .env +SYNC_INTERVAL=15 # 15 秒一次 +SYNC_PROCESSCOUNT=500 # 每次处理 500 条 + +# 重启 syncjob +docker compose restart syncjob +``` + +--- + +## cronjob — 每日定时任务 + +**替代:** Windows 计划任务调用的 `tools-docker/autorun.cmd` + +**作用:** 每日凌晨 4:00 执行以下流程(与原 `autorun.cmd` 完全一致): + +| 步骤 | 原 autorun.cmd | Docker cronjob | +|------|---------------|----------------| +| 1. 停止同步服务 | `net stop HttpRequestService` | 创建 `/shared/syncjob.pause` 信号文件 | +| 2. 等待当前请求完成 | (Windows 服务立即停止) | `sleep 5` | +| 3. 同步报表数据 | `HttpRequest.exe POST SynchronizeReportData.php` | `curl POST http://dlweb/ext/SynchronizeReportData.php` | +| 4. 恢复同步服务 | `net start HttpRequestService` | 删除 `/shared/syncjob.pause` 信号文件 | + +> **暂停机制:** `syncjob` 和 `cronjob` 通过共享 Docker volume(`shared-signal`)通信。`cronjob` 创建 `/shared/syncjob.pause` 文件时,`syncjob` 会自动跳过轮询,报表同步完成后删除该文件恢复。 + +### 可配置项(`.env`) + +```bash +# cron 表达式,默认凌晨 4:00 +CRON_SCHEDULE=0 4 * * * +``` + +**修改执行时间示例:** + +```bash +# 凌晨 3:30 执行 +CRON_SCHEDULE=30 3 * * * + +# 每天凌晨 2:00 和 14:00 各执行一次 +CRON_SCHEDULE=0 2,14 * * * +``` + +### 查看执行日志 + +```bash +./deploy.sh logs cronjob +# 或实时查看 +docker logs -f youle-cronjob +``` + +### 手动触发(测试用) + +```bash +docker exec youle-cronjob /bin/sh /app/daily-task.sh +``` + +### 调整每日任务执行时间 + +```bash +# 修改 .env +CRON_SCHEDULE=30 3 * * * # 改为凌晨 3:30 + +# 重启 cronjob +docker compose restart cronjob +``` + +--- + +## 临时停止定时任务(维护数据库时) + +```bash +docker compose stop syncjob cronjob +# 维护完成后恢复 +docker compose up -d syncjob cronjob +``` diff --git a/codes/agent/game-docker/docs/03-env-variables.md b/codes/agent/game-docker/docs/03-env-variables.md new file mode 100644 index 0000000..0dae450 --- /dev/null +++ b/codes/agent/game-docker/docs/03-env-variables.md @@ -0,0 +1,141 @@ +# 环境变量配置 + +所有硬编码的域名、数据库地址、密钥都已外部化为环境变量。**修改配置不再需要改代码,只需改 `.env` 文件。** + +--- + +## 变量分组总览 + +| 变量分组 | 说明 | +|---------|------| +| `API_DB_*` | 游戏核心 API 数据库 | +| `DLWEB_DB_*` | 代理后台主库 | +| `DLWEB_SLAVE_DB_*` | 代理后台从库 | +| `EXT_GAME_DB_*` | 外部游戏数据库(Synchronize / SynchronizeReportData) | +| `EXT_GRADE_DB_*` | 战绩数据库(game.php) | +| `EXT_DEV_DB_*` | 开发数据库(DEBUG 模式) | +| `REDIS_*` | Redis 配置 | +| `WX_MINI_*` | 微信小程序 AppID / Secret | +| `WX_OA_*` | 微信公众号 AppID / Secret | +| `WX_PAY_*` | 微信支付商户配置 | +| `REMOTE_CONFIG_*` | 远程配置(Gitee) | +| `ROOT_DOMAIN` | 父域名(自动推导 3 个子域名 + 所有派生 URL) | +| `SITE_*` | PHP 后端各站点域名 | +| `DLWEB_*_URL` | 前端 JS/HTML 硬编码域名替换 | +| `SYNC_INTERVAL` / `SYNC_PROCESSCOUNT` | syncjob 同步参数 | +| `CRON_SCHEDULE` | cronjob 执行时间 | +| `GAME_SERVER_QUERY_URL` | 游戏服务器查询地址 | +| `INTERNAL_WHITELIST` | IP 白名单(逗号分隔) | + +--- + +## 域名配置关系 + +``` +.env 配置 │ 自动推导结果 +─────────────────────┼────────────────────────────────────────────────────── +ROOT_DOMAIN │ API_DOMAIN = api. → Nginx 网站1(含 wxserver /wx/ 路由) +(唯一必填) │ DLWEB_DOMAIN = dlapi. → Nginx 网站2 + │ SITE_API_URL = https://api. + │ SITE_PAY_NOTIFY_URL = https://api. + │ SITE_OPEN_URL = http://open. + │ DLWEB_DL_API_V3_URL = https://dlapi. +``` + +> 推导由 `docker-compose.yml` 的 `environment:` 块完成,容器内所有派生变量均无需手动配置。如子域名不符合 `<前缀>.` 规律,可在 `.env` 中单独覆盖对应变量。 + +--- + +## 环境变量加载机制 + +### PHP 服务(env_config.php) + +所有 PHP 文件通过 `env($key, $default)` 函数读取配置: + +```php +// 优先读 OS 环境变量(Docker 场景),回退读 .env 文件 +$host = env('API_DB_HOST', 'localhost'); +``` + +加载优先级:Docker 容器环境变量(`docker-compose env_file`)> `.env` 文件 > 代码默认值。 + +### Node.js 服务(wxserver_daoqi) + +直接使用 `process.env.VARIABLE_NAME`,由 `docker-compose env_file` 注入。 + +### 前端 JS / HTML + +前端静态文件无法读取环境变量,通过 Docker entrypoint 脚本在容器启动时用 `sed` 替换硬编码域名: + +- `docker/api/docker-entrypoint.sh` — 替换 API 服务中的 JS 文件 +- `docker/dlweb/docker-entrypoint.sh` — 替换 DLWEB 服务中的 30+ 个 JS/HTML 文件 + +### Nginx 域名注入 + +`default.conf.template` 使用 `${API_DOMAIN}` / `${DLWEB_DOMAIN}` 占位符,Nginx 容器启动时通过 `envsubst` 自动替换。wxserver 不独立占用域名,通过 `api.xxx/wx/*` 路由接入。 + +--- + +## 文件修改与生效方式 + +不同文件在镜像中的处理方式不同,决定了改完代码后需要执行哪种操作。 + +### 文件 → 操作对照表 + +| 文件路径 | 所属容器 | 载入方式 | 修改后需要执行的操作 | +|---------|---------|---------|-------------------| +| `api/**` | `youle-api` | `COPY` 进镜像 | `./deploy.sh rebuild api` 重建镜像 | +| `dlweb/**` | `youle-dlweb` | `COPY` 进镜像 | `./deploy.sh rebuild dlweb` 重建镜像 | +| `wxserver_daoqi/**` | `youle-wxserver` | `COPY` 进镜像 | `./deploy.sh rebuild wxserver` 重建镜像 | +| `env_config.php` | `youle-api` / `youle-dlweb` | `COPY` 进镜像 | `./deploy.sh rebuild api dlweb` 重建两个镜像 | +| `docker/api/Dockerfile` | `youle-api` | 构建定义 | `./deploy.sh rebuild api` | +| `docker/api/docker-entrypoint.sh` | `youle-api` | `COPY` 进镜像 | `./deploy.sh rebuild api` | +| `docker/dlweb/Dockerfile` | `youle-dlweb` | 构建定义 | `./deploy.sh rebuild dlweb` | +| `docker/dlweb/docker-entrypoint.sh` | `youle-dlweb` | `COPY` 进镜像 | `./deploy.sh rebuild dlweb` | +| `docker/wxserver/Dockerfile` | `youle-wxserver` | 构建定义 | `./deploy.sh rebuild wxserver` | +| `docker/nginx/default.conf.template` | `youle-nginx` | volume 挂载(`:ro`) | `scp` 上传 → `docker restart youle-nginx` | +| `docker/nginx/ssl-params.conf` | `youle-nginx` | volume 挂载(`:ro`) | `scp` 上传 → `docker restart youle-nginx` | +| `docker/syncjob/sync.sh` | `youle-syncjob` | volume 挂载(`:ro`) | `scp` 上传 → `docker restart youle-syncjob` | +| `docker/cronjob/entrypoint.sh` | `youle-cronjob` | volume 挂载(`:ro`) | `scp` 上传 → `docker restart youle-cronjob` | +| `docker/cronjob/daily-task.sh` | `youle-cronjob` | volume 挂载(`:ro`) | `scp` 上传 → `docker restart youle-cronjob` | +| `docker-compose.yml` | 所有容器 | compose 编排 | `docker compose up -d`(有变动的容器自动重建) | +| `.env` | 所有容器 | compose `env_file` | `docker compose up -d`(重新注入环境变量) | + +> **COPY vs 挂载的区别:** +> - **`COPY` 进镜像** — 文件被打进 Docker 镜像层,修改后必须重新 build 才能生效 +> - **volume 挂载** — 只需 `scp` 传到服务器后重启容器即可,**无需重建镜像** + +### 操作命令速查 + +```bash +# ── 需要重建镜像的操作(修改源码/Dockerfile/entrypoint 等 COPY 文件)── + +./deploy.sh rebuild api # 只重建 API +./deploy.sh rebuild dlweb # 只重建 DLWEB +./deploy.sh rebuild wxserver # 只重建 wxserver +./deploy.sh rebuild api dlweb # 同时重建多个 +./deploy.sh rebuild # 重建所有服务 + + +# ── 只需 scp + 重启的操作(修改 volume 挂载文件,秒级生效)── + +# Nginx 配置 +scp docker/nginx/ssl-params.conf root@47.98.203.17:/opt/youle/game-docker/docker/nginx/ssl-params.conf +scp docker/nginx/default.conf.template root@47.98.203.17:/opt/youle/game-docker/docker/nginx/default.conf.template +ssh root@47.98.203.17 "docker restart youle-nginx" + +# syncjob 脚本 +scp docker/syncjob/sync.sh root@47.98.203.17:/opt/youle/game-docker/docker/syncjob/sync.sh +ssh root@47.98.203.17 "docker restart youle-syncjob" + +# cronjob 脚本 +scp docker/cronjob/entrypoint.sh root@47.98.203.17:/opt/youle/game-docker/docker/cronjob/entrypoint.sh +scp docker/cronjob/daily-task.sh root@47.98.203.17:/opt/youle/game-docker/docker/cronjob/daily-task.sh +ssh root@47.98.203.17 "docker restart youle-cronjob" + + +# ── .env / docker-compose.yml 变更 ── + +ssh root@47.98.203.17 "cd /opt/youle/game-docker && docker compose up -d" +# compose 会对比配置差异,只重启有变更的容器 +``` diff --git a/codes/agent/game-docker/docs/04-ssl.md b/codes/agent/game-docker/docs/04-ssl.md new file mode 100644 index 0000000..ec25387 --- /dev/null +++ b/codes/agent/game-docker/docs/04-ssl.md @@ -0,0 +1,68 @@ +# SSL 证书管理 + +使用 Let's Encrypt 免费证书,由 `certbot` 容器自动管理。 + +--- + +## 常用命令 + +```bash +# 首次申请(必须先确保域名已解析) +./deploy.sh ssl-init + +# 用测试环境验证(不消耗申请限额) +./deploy.sh ssl-init --staging + +# 手动续签 +./deploy.sh ssl-renew + +# 查看证书状态 +./deploy.sh ssl-status +``` + +`certbot` 容器每 12 小时自动检查续签,证书到期前 30 天自动更新,无需人工干预。 + +--- + +## 更换域名后重新申请 + +更换 `ROOT_DOMAIN` 后需要重新申请证书: + +```bash +# 1. 测试验证(不消耗申请限额) +./deploy.sh ssl-init --staging + +# 2. 正式申请 +./deploy.sh ssl-init + +# 3. 重启所有服务 +./deploy.sh restart +``` + +> Let's Encrypt 有频率限制:每 7 天同一域名最多申请 5 次。调试阶段务必用 `--staging` 参数。 + +--- + +## 验证文件放置 + +微信后台添加授权域名时,要求在域名根目录放置 `.txt` 验证文件: + +1. 将微信提供的验证文件(如 `MP_verify_xxx.txt`)放入 `api/` 根目录 +2. 重建 api 镜像使其生效: + +```bash +./deploy.sh rebuild api +``` + +--- + +## 数据持久化 + +SSL 相关的 Docker Volume: + +| Volume | 挂载点 | 说明 | +|--------|--------|------| +| `certbot-webroot` | /var/www/certbot | ACME 域名验证文件 | +| `certbot-certs` | /etc/letsencrypt | SSL 证书文件 | + +> 卸载时若删除 `certbot-certs` volume,证书将丢失,需重新申请。详见 [卸载和清理](./07-uninstall.md)。 diff --git a/codes/agent/game-docker/docs/05-operations.md b/codes/agent/game-docker/docs/05-operations.md new file mode 100644 index 0000000..caa412e --- /dev/null +++ b/codes/agent/game-docker/docs/05-operations.md @@ -0,0 +1,319 @@ +# 常见运维操作 + +--- + +## 场景一:更换域名 + +当需要将服务迁移到新域名时(例如 `daoqijuyou.cn` → `newdomain.com`),只需改一个变量。 + +### 1. 修改 `.env` 中的 `ROOT_DOMAIN` + +```bash +vim .env +``` + +```bash +# 改成新父域名,三个子域名自动跟随 +ROOT_DOMAIN=newdomain.com +``` + +`docker-compose.yml` 将自动推导: + +| 推导变量 | 结果 | +|---------|------| +| `API_DOMAIN` | `api.newdomain.com` | +| `DLWEB_DOMAIN` | `dlapi.newdomain.com` | +| `SITE_API_URL` | `https://api.newdomain.com` | +| `SITE_PAY_NOTIFY_URL` | `https://api.newdomain.com` | +| `SITE_OPEN_URL` | `http://open.newdomain.com` | +| `DLWEB_DL_API_V3_URL` | `https://dlapi.newdomain.com` | + +> **子域名不符合标准规律时**,在 `.env` 中单独覆盖对应变量即可: +> ```bash +> DLWEB_DOMAIN=dl-manage.newdomain.com +> ``` + +> **其他独立 URL 变量**(`DLWEB_SETTLE_URL`、`DLWEB_PROXY_URL`、`QQ_CALLBACK_URL` 等)仍需在 `.env` 中手动配置,详见 `.env.example` 中的注释。 + +### 2. DNS 解析 + +```bash +# 验证 DNS 解析 +nslookup api.newdomain.com +nslookup dlapi.newdomain.com +``` + +### 3. 重新申请 SSL 证书 + +```bash +./deploy.sh ssl-init --staging # 测试验证 +./deploy.sh ssl-init # 正式申请 +``` + +### 4. 重启所有服务 + +```bash +./deploy.sh restart +``` + +重启时自动完成: +- Nginx 使用新域名的 `server_name` 和 SSL 证书 +- `docker-entrypoint.sh` 用新域名替换 JS/HTML 中的硬编码 URL +- PHP `env()` 读取新的环境变量值 + +### 5. 更新微信后台配置 + +> **关键路由说明:** Nginx 在 `api.newdomain.com` 上配置了 `/wx/` 前缀路由——以 `/wx/` 开头的请求被反向代理到 wxserver(Node.js),其余请求仍由 PHP API 处理。 + +#### 5.1 微信小程序后台 + +> **入口:** [mp.weixin.qq.com](https://mp.weixin.qq.com) → 开发 → 开发管理 → 开发设置 → 服务器域名 + +| 配置项 | 新值 | 不更新时的现象 | +|--------|------|--------------| +| **request 合法域名** | `https://api.newdomain.com` | `wx.request` 报 `invalid url`,所有网络请求失败 | +| **业务域名** | `api.newdomain.com` | web-view 提示"不在业务域名列表中" | + +> 小程序域名配置每月只能修改 5 次,且每项域名必须已备案并启用 HTTPS。 + +#### 5.2 微信公众号后台 + +> **入口:** [mp.weixin.qq.com](https://mp.weixin.qq.com) → 设置与开发 → 公众号设置 → 功能设置 + +| 配置项 | 填写值 | 不更新时的现象 | +|--------|--------|--------------| +| 业务域名 | `api.newdomain.com` | 微信内置浏览器提示"域名不合法" | +| 网页授权域名 | `api.newdomain.com` | 授权跳转被微信拦截,永久头像功能不可用 | +| JS 接口安全域名 | `api.newdomain.com` | `wx.config()` 签名验证失败,微信支付按钮无法唤起 | + +> **⚠️ 远程配置也需同步修改:** `WX_OA_REDIRECT_DOMAIN` 未配置时,wxserver 从远程配置文件读取 `minipro_api_url`。建议同步更新 Gitee Raw 配置 `minipro_api_url` 为 `api.newdomain.com/wx`。 + +#### 5.3 微信支付商户后台 + +> **入口:** [pay.weixin.qq.com](https://pay.weixin.qq.com) → 账户中心 → 商户信息 → 支付配置 → JSAPI 支付授权目录 + +| 配置值 | 用途 | +|--------|------| +| `https://api.newdomain.com/` | JSAPI 支付页面所在目录(必须包含末尾斜杠) | + +不更新的后果:下单时提示"当前 URL 未注册",JSAPI 支付彻底无法使用。 + +#### 配置清单汇总 + +| 平台 | 配置项 | 填写值 | +|------|--------|--------| +| 微信小程序后台 | request 合法域名 | `https://api.newdomain.com` | +| 微信小程序后台 | 业务域名 | `api.newdomain.com` | +| 微信公众号后台 | 业务域名 | `api.newdomain.com` | +| 微信公众号后台 | 网页授权域名 | `api.newdomain.com` | +| 微信公众号后台 | JS 接口安全域名 | `api.newdomain.com` | +| 微信支付商户后台 | JSAPI 支付授权目录 | `https://api.newdomain.com/` | + +--- + +## 场景二:更换数据库地址 + +当数据库实例迁移(例如 RDS 升级、切换区域)时: + +### 1. 修改 `.env` 中对应的数据库变量 + +| 数据库 | 需修改的变量 | 使用者 | +|--------|-------------|--------| +| API 主库 | `API_DB_HOST`, `API_DB_PORT`, `API_DB_USER`, `API_DB_PASSWORD` | api 服务 | +| 代理后台主库 | `DLWEB_DB_HOST`, `DLWEB_DB_PORT`, `DLWEB_DB_USER`, `DLWEB_DB_PASSWORD` | dlweb 服务 | +| 代理后台从库 | `DLWEB_SLAVE_DB_HOST`, `DLWEB_SLAVE_DB_PORT`, `DLWEB_SLAVE_DB_USER`, `DLWEB_SLAVE_DB_PASSWORD` | dlweb 读操作 | +| 外部游戏库 | `EXT_GAME_DB_HOST`, `EXT_GAME_DB_PORT`, `EXT_GAME_DB_USER`, `EXT_GAME_DB_PASSWORD` | Synchronize.php | +| 战绩库 | `EXT_GRADE_DB_HOST`, `EXT_GRADE_DB_PORT`, `EXT_GRADE_DB_USER`, `EXT_GRADE_DB_PASSWORD` | game.php | +| 开发库 | `EXT_DEV_DB_HOST`, `EXT_DEV_DB_PORT`, `EXT_DEV_DB_USER`, `EXT_DEV_DB_PASSWORD` | DEBUG 模式 | + +### 2. 重启受影响的服务 + +```bash +docker compose restart api # 只改了 API 数据库 +docker compose restart dlweb # 只改了 DLWEB 数据库 +docker compose restart dlweb syncjob cronjob # 改了外部游戏库 +./deploy.sh restart # 改了多个,全部重启 +``` + +### 3. 验证连接 + +```bash +docker logs --tail 20 youle-api +docker logs --tail 20 youle-dlweb +docker logs --tail 10 youle-syncjob +``` + +> 如果新数据库有 IP 白名单限制,需要将 Docker 宿主机的公网 IP 加入 RDS 白名单。 + +--- + +## 场景三:更换服务器(整体迁移) + +### 1. 打包项目文件(旧服务器) + +```bash +cd /path/to/game-docker +tar czf game-docker.tar.gz --exclude='.env' --exclude='game/' . +``` + +### 2. 传输到新服务器 + +```bash +scp game-docker.tar.gz newserver:/opt/ +``` + +### 3. 在新服务器上部署 + +```bash +cd /opt +tar xzf game-docker.tar.gz -C game-docker +cd game-docker +cp .env.example .env +vim .env +``` + +### 4. 确认修改项 + +| 检查项 | 是否需要改 | 说明 | +|--------|-----------|------| +| 域名(`*_DOMAIN`) | 域名不变则不改 | DNS 需指向新服务器 IP | +| 数据库地址(`*_DB_HOST`) | 通常不改 | RDS 地址不变,但需将新服务器 IP 加入白名单 | +| Redis 地址 | 不改 | Docker 内置 Redis,随容器迁移 | +| 微信/支付配置 | 不改 | AppID/Secret 与服务器无关 | +| 游戏服务器查询地址 | 看情况 | 游戏服务器也迁移了则需改 | +| IP 白名单 | 可能需改 | `INTERNAL_WHITELIST` 加入新 IP | + +### 5. 启动服务 + +```bash +chmod +x deploy.sh init-ssl.sh +./deploy.sh ssl-init # 新服务器需重新申请证书 +./deploy.sh up +``` + +### 6. 验证所有服务 + +```bash +./deploy.sh status +curl -k https://api.yourdomain.com/ +curl -k https://dlapi.yourdomain.com/ +curl -k https://api.yourdomain.com/wx/api/login +docker logs --tail 5 youle-syncjob +docker logs --tail 5 youle-cronjob +``` + +--- + +## 场景四:更改 Redis 配置 + +```bash +vim .env +# 修改以下变量: +# REDIS_HOST=new-redis-host +# REDIS_PORT=6379 +# REDIS_PASSWORD=new-password + +docker compose restart dlweb redis +``` + +> 使用 Docker 内置 Redis(默认),`REDIS_HOST` 应设为 `redis`(Docker 服务名),不是 `localhost`。 + +--- + +## 场景五:单独开启 / 关闭特定服务 + +### 服务清单与依赖关系 + +| 服务名 | 容器名 | 说明 | 依赖 | +|--------|--------|------|------| +| `nginx` | `youle-nginx` | 反向代理 + SSL | api / dlweb / wxserver | +| `api` | `youle-api` | 游戏核心 API | — | +| `dlweb` | `youle-dlweb` | 代理管理后台 | redis | +| `wxserver` | `youle-wxserver` | 微信小程序后端 | — | +| `syncjob` | `youle-syncjob` | 每 30s 数据同步 | dlweb(内网) | +| `cronjob` | `youle-cronjob` | 每日凌晨报表任务 | dlweb(内网) | +| `redis` | `youle-redis` | 缓存 | — | +| `certbot` | `youle-certbot` | 证书自动续签 | — | + +### 开启单个服务 + +```bash +docker compose up -d api +docker compose up -d dlweb +docker compose up -d wxserver +docker compose up -d syncjob +docker compose up -d cronjob +``` + +### 关闭单个服务 + +```bash +docker compose stop api +docker compose stop syncjob + +# stop + 删除容器(下次 up 会重新创建) +docker compose rm -sf syncjob +``` + +> `stop` 只停止容器,不删除;`rm -sf` 停止并删除容器(均不会丢失数据 volume)。 + +### 常见场景 + +**只重建并重启某个业务服务(代码更新后):** +```bash +docker compose up -d --build api +docker compose up -d --build dlweb +docker compose up -d --build wxserver +``` + +**关闭 certbot 自动续签(调试期间避免请求频率限制):** +```bash +docker compose stop certbot +docker compose up -d certbot # 恢复 +``` + +**仅重启 nginx(修改配置后生效):** +```bash +docker compose restart nginx +# 或热重载(不中断连接) +docker exec youle-nginx nginx -s reload +``` + +**查看所有服务当前状态:** +```bash +docker compose ps +# 或 +./deploy.sh status +``` + +--- + +## 操作速查表 + +| 变更内容 | 修改 `.env` 中的变量 | 重启命令 | 额外操作 | +|---------|---------------------|---------|---------| +| 更换域名 | `ROOT_DOMAIN`(子域名不标准时单独覆盖) | `./deploy.sh ssl-init && ./deploy.sh restart` | DNS 解析 + 微信后台 | +| API 数据库 | `API_DB_*` | `docker compose restart api` | RDS 白名单 | +| DLWEB 数据库 | `DLWEB_DB_*` | `docker compose restart dlweb` | RDS 白名单 | +| 游戏数据库 | `EXT_GAME_DB_*` | `docker compose restart dlweb syncjob cronjob` | RDS 白名单 | +| 战绩数据库 | `EXT_GRADE_DB_*` | `docker compose restart dlweb` | RDS 白名单 | +| Redis | `REDIS_*` | `docker compose restart dlweb redis` | — | +| 微信密钥 | `WX_*` | `docker compose restart api dlweb wxserver` | 微信后台 | +| 整体迁移 | 视情况 | `./deploy.sh ssl-init && ./deploy.sh up` | DNS + RDS 白名单 | + +--- + +## 数据持久化 + +以下 Docker Volume 用于持久化存储: + +| Volume | 挂载点 | 说明 | +|--------|--------|------| +| `api-logs` | /var/www/html/logs | API 服务日志 | +| `api-source-logs` | /var/www/html/source/logs | API source 模块日志 | +| `dlweb-logs` | /var/www/html/api/logs | DLWEB 服务日志 | +| `dlweb-debug` | /var/www/html/api/ext/debug | DLWEB 同步/报表调试日志 | +| `redis-data` | /data | Redis 持久化数据 | +| `shared-signal` | /shared | syncjob ↔ cronjob 暂停信号文件 | +| `certbot-webroot` | /var/www/certbot | ACME 域名验证文件 | +| `certbot-certs` | /etc/letsencrypt | SSL 证书文件 | diff --git a/codes/agent/game-docker/docs/06-logging.md b/codes/agent/game-docker/docs/06-logging.md new file mode 100644 index 0000000..1e8b92b --- /dev/null +++ b/codes/agent/game-docker/docs/06-logging.md @@ -0,0 +1,310 @@ +# 日志管理 + +--- + +## 日志位置总览 + +| 日志类型 | 来源容器 | 查看方式 | 说明 | +|---------|---------|---------|------| +| Nginx 访问/错误日志 | `youle-nginx` | `docker logs` | HTTP 请求记录、SSL 错误 | +| API Apache 错误日志 | `youle-api` | `docker logs` | PHP Fatal Error、Apache 500 | +| API PHP 错误日志 | `youle-api` | `docker logs` | PHP Warning/Notice(写入 Apache 错误流)| +| API 业务日志 | `youle-api` | Volume 文件 | `/var/www/html/logs/YYYY-MM-DD.log` | +| API source 模块日志 | `youle-api` | Volume 文件 | `/var/www/html/source/logs/` | +| DLWEB Apache 错误日志 | `youle-dlweb` | `docker logs` | PHP Fatal Error、Apache 500 | +| DLWEB 业务日志 | `youle-dlweb` | Volume 文件 | `/var/www/html/api/logs/` | +| 同步任务调试日志 | `youle-dlweb` | Volume 文件 | `/var/www/html/api/ext/debug/synchronize/YYYY-MM-DD.log` | +| 报表同步调试日志 | `youle-dlweb` | Volume 文件 | `/var/www/html/api/ext/debug/SynchronizeReportData/YYYY-MM-DD.log` | +| 自动任务调试日志 | `youle-dlweb` | Volume 文件 | `/var/www/html/api/ext/debug/autotask/YYYY-MM-DD.log` | +| syncjob 运行日志 | `youle-syncjob` | `docker logs` | curl 请求结果,每 30s 一条 | +| cronjob 调度日志 | `youle-cronjob` | `docker logs` | cron 触发记录 | +| wxserver 运行日志 | `youle-wxserver` | `docker logs` | Node.js 标准输出 | + +--- + +## 一、查看容器标准输出日志(docker logs) + +```bash +# 查看最近 50 行(快速概览) +docker logs --tail 50 youle-nginx +docker logs --tail 50 youle-api +docker logs --tail 50 youle-dlweb +docker logs --tail 50 youle-syncjob +docker logs --tail 50 youle-cronjob +docker logs --tail 50 youle-wxserver + +# 实时跟踪日志(Ctrl+C 退出) +docker logs -f youle-api +docker logs -f youle-syncjob + +# 查看最近 100 行并实时跟踪 +docker logs --tail 100 -f youle-dlweb + +# 查看带时间戳的日志 +docker logs -t --tail 50 youle-nginx + +# 查看某时间段之后的日志 +docker logs --since 2026-04-13T10:00:00 youle-api +docker logs --since 1h youle-syncjob # 最近 1 小时 +``` + +### 使用 deploy.sh 快捷查看 + +```bash +./deploy.sh logs api +./deploy.sh logs dlweb +./deploy.sh logs syncjob +./deploy.sh logs cronjob +./deploy.sh logs nginx +./deploy.sh logs wxserver + +# 加 -f 实时跟踪 +./deploy.sh logs -f api +./deploy.sh logs -f syncjob +``` + +--- + +## 二、查看业务调试日志文件(Volume 文件) + +业务调试日志写入 Docker Volume,按日期分文件(`YYYY-MM-DD.log`)。 + +```bash +# --- API 业务日志 --- + +docker exec youle-api ls -lh /var/www/html/logs/ +docker exec youle-api tail -50 /var/www/html/logs/$(date +%Y-%m-%d).log +docker exec youle-api tail -f /var/www/html/logs/$(date +%Y-%m-%d).log +docker exec youle-api cat /var/www/html/logs/$(date +%Y-%m-%d).log + +# --- API source 模块日志 --- +docker exec youle-api ls -lhR /var/www/html/source/logs/ +docker exec youle-api tail -50 /var/www/html/source/logs/$(date +%Y-%m-%d).log + +# --- DLWEB 业务日志 --- +docker exec youle-dlweb ls -lh /var/www/html/api/logs/ +docker exec youle-dlweb tail -50 /var/www/html/api/logs/$(date +%Y-%m-%d).log + +# --- 同步任务调试日志(Synchronize.php)--- +docker exec youle-dlweb ls -lh /var/www/html/api/ext/debug/synchronize/ +docker exec youle-dlweb tail -50 /var/www/html/api/ext/debug/synchronize/$(date +%Y-%m-%d).log +docker exec youle-dlweb tail -f /var/www/html/api/ext/debug/synchronize/$(date +%Y-%m-%d).log + +# --- 报表同步调试日志(SynchronizeReportData.php)--- +docker exec youle-dlweb ls -lh /var/www/html/api/ext/debug/SynchronizeReportData/ +docker exec youle-dlweb tail -50 /var/www/html/api/ext/debug/SynchronizeReportData/$(date +%Y-%m-%d).log + +# --- 自动任务调试日志(autotask)--- +docker exec youle-dlweb ls -lh /var/www/html/api/ext/debug/autotask/ +docker exec youle-dlweb tail -50 /var/www/html/api/ext/debug/autotask/$(date +%Y-%m-%d).log +``` + +### 一键健康检查(汇总命令) + +```bash +echo '=== syncjob 容器日志(最近20行)===' +docker logs --tail 20 youle-syncjob +echo +echo '=== 同步调试日志(最近20行)===' +docker exec youle-dlweb tail -20 /var/www/html/api/ext/debug/synchronize/$(date +%Y-%m-%d).log +echo +echo '=== API 业务日志(最近20行)===' +docker exec youle-api tail -20 /var/www/html/logs/$(date +%Y-%m-%d).log +``` + +### Nginx 访问日志过滤 + +```bash +# 过滤 HTTP 500 错误 +docker logs youle-nginx 2>&1 | grep ' 500 ' + +# 过滤特定 IP 的请求 +docker logs youle-nginx 2>&1 | grep '客户端IP地址' + +# 过滤 SSL/TLS 握手错误 +docker logs youle-nginx 2>&1 | grep 'SSL_do_handshake\|no required SSL' +``` + +--- + +## 三、清除日志 + +### 1. 清除 Docker 容器日志(stdout/stderr) + +```bash +# 清空单个容器的 docker logs(容器保持运行,不中断服务) +truncate -s 0 $(docker inspect --format='{{.LogPath}}' youle-syncjob) +truncate -s 0 $(docker inspect --format='{{.LogPath}}' youle-api) +truncate -s 0 $(docker inspect --format='{{.LogPath}}' youle-dlweb) +truncate -s 0 $(docker inspect --format='{{.LogPath}}' youle-nginx) + +# 一键清空所有 youle-* 容器的 docker logs +for name in youle-nginx youle-api youle-dlweb youle-wxserver youle-syncjob youle-cronjob youle-redis youle-certbot; do + logpath=$(docker inspect --format='{{.LogPath}}' $name 2>/dev/null) + [ -n "$logpath" ] && truncate -s 0 "$logpath" && echo "Cleared: $name" +done +``` + +### 2. 清除业务调试日志文件(Volume 内) + +```bash +# --- 清除 API 业务日志 --- +docker exec youle-api sh -c "find /var/www/html/logs/ -name '*.log' ! -name '$(date +%Y-%m-%d).log' -delete" +docker exec youle-api truncate -s 0 /var/www/html/logs/$(date +%Y-%m-%d).log +docker exec youle-api sh -c 'rm -f /var/www/html/logs/*.log' + +# --- 清除 DLWEB 业务日志 --- +docker exec youle-dlweb sh -c "find /var/www/html/api/logs/ -name '*.log' ! -name '$(date +%Y-%m-%d).log' -delete" +docker exec youle-dlweb sh -c 'rm -f /var/www/html/api/logs/*.log' + +# --- 清除同步任务调试日志 --- +docker exec youle-dlweb find /var/www/html/api/ext/debug/ -name '*.log' -mtime +30 -delete # 删 30 天前 +docker exec youle-dlweb sh -c "find /var/www/html/api/ext/debug/ -name '*.log' ! -name '$(date +%Y-%m-%d).log' -delete" +docker exec youle-dlweb sh -c ' + rm -f /var/www/html/api/ext/debug/synchronize/*.log + rm -f /var/www/html/api/ext/debug/SynchronizeReportData/*.log + rm -f /var/www/html/api/ext/debug/autotask/*.log +' +``` + +### 3. 一键清理脚本(所有日志) + +将以下内容保存为服务器上的 `/opt/youle/game-docker/clear-logs.sh`: + +```bash +#!/bin/bash +echo '=== 清空 Docker 容器日志 ===' +for name in youle-nginx youle-api youle-dlweb youle-wxserver youle-syncjob youle-cronjob youle-redis youle-certbot; do + logpath=$(docker inspect --format='{{.LogPath}}' $name 2>/dev/null) + if [ -n "$logpath" ] && [ -f "$logpath" ]; then + truncate -s 0 "$logpath" + echo " Cleared docker log: $name" + fi +done + +echo '=== 清空业务日志文件 ===' +docker exec youle-api sh -c 'rm -f /var/www/html/logs/*.log /var/www/html/source/logs/*.log 2>/dev/null; echo " Cleared api logs"' +docker exec youle-dlweb sh -c ' + rm -f /var/www/html/api/logs/*.log 2>/dev/null + rm -f /var/www/html/api/ext/debug/synchronize/*.log 2>/dev/null + rm -f /var/www/html/api/ext/debug/SynchronizeReportData/*.log 2>/dev/null + rm -f /var/www/html/api/ext/debug/autotask/*.log 2>/dev/null + echo " Cleared dlweb logs" +' +echo '=== 完成 ===' +``` + +```bash +chmod +x /opt/youle/game-docker/clear-logs.sh +/opt/youle/game-docker/clear-logs.sh +``` + +--- + +## 四、Windows PowerShell 远程操作 + +> 以下命令在 **Windows PowerShell** 中执行,通过 SSH 直接读取服务器上的业务日志。 + +### 查看日志 + +```powershell +$today = (Get-Date -Format "yyyy-MM-dd") + +# api/logs +ssh root@47.98.203.17 "docker exec youle-api ls -lh /var/www/html/logs/" +ssh root@47.98.203.17 "docker exec youle-api tail -50 /var/www/html/logs/$today.log" +ssh root@47.98.203.17 "docker exec youle-api cat /var/www/html/logs/$today.log" +ssh root@47.98.203.17 "docker exec youle-api tail -f /var/www/html/logs/$today.log" # 实时 + +# synchronize +ssh root@47.98.203.17 "docker exec youle-dlweb ls -lh /var/www/html/api/ext/debug/synchronize/" +ssh root@47.98.203.17 "docker exec youle-dlweb tail -50 /var/www/html/api/ext/debug/synchronize/$today.log" +ssh root@47.98.203.17 "docker exec youle-dlweb tail -f /var/www/html/api/ext/debug/synchronize/$today.log" # 实时 + +# SynchronizeReportData +ssh root@47.98.203.17 "docker exec youle-dlweb ls -lh /var/www/html/api/ext/debug/SynchronizeReportData/" +ssh root@47.98.203.17 "docker exec youle-dlweb tail -50 /var/www/html/api/ext/debug/SynchronizeReportData/$today.log" + +# autotask +ssh root@47.98.203.17 "docker exec youle-dlweb ls -lh /var/www/html/api/ext/debug/autotask/" +ssh root@47.98.203.17 "docker exec youle-dlweb tail -50 /var/www/html/api/ext/debug/autotask/$today.log" + +# 一键汇总(同时查看三个目录今天的日志末尾) +$today = (Get-Date -Format "yyyy-MM-dd") +ssh root@47.98.203.17 @" +echo '=== api/logs/$today.log ===' +docker exec youle-api tail -30 /var/www/html/logs/$today.log +echo +echo '=== synchronize/$today.log ===' +docker exec youle-dlweb tail -30 /var/www/html/api/ext/debug/synchronize/$today.log +echo +echo '=== SynchronizeReportData/$today.log ===' +docker exec youle-dlweb tail -30 /var/www/html/api/ext/debug/SynchronizeReportData/$today.log +"@ +``` + +### 删除日志 + +```powershell +$today = (Get-Date -Format "yyyy-MM-dd") + +# 清空今天的 API 业务日志(保留文件) +ssh root@47.98.203.17 "docker exec youle-api truncate -s 0 /var/www/html/logs/$today.log" + +# 删除全部 API 业务日志 +ssh root@47.98.203.17 "docker exec youle-api sh -c 'rm -f /var/www/html/logs/*.log'" + +# 清空今天的同步调试日志 +ssh root@47.98.203.17 "docker exec youle-dlweb truncate -s 0 /var/www/html/api/ext/debug/synchronize/$today.log" + +# 删除 30 天前的旧调试日志 +ssh root@47.98.203.17 "docker exec youle-dlweb find /var/www/html/api/ext/debug/ -name '*.log' -mtime +30 -delete" + +# 一键清理:api/logs + dlweb/api/ext/debug 全部日志 +ssh root@47.98.203.17 @" +docker exec youle-api sh -c 'rm -f /var/www/html/logs/*.log' +docker exec youle-dlweb sh -c ' + rm -f /var/www/html/api/ext/debug/synchronize/*.log + rm -f /var/www/html/api/ext/debug/SynchronizeReportData/*.log + rm -f /var/www/html/api/ext/debug/autotask/*.log +' +echo "Done" +"@ +``` + +--- + +## 快捷速查表 + +> 以下命令在 SSH 登录服务器后直接执行。 + +### 查看日志 + +| 目标 | 命令 | +|------|------| +| nginx 访问日志(末尾50行) | `docker logs --tail 50 youle-nginx` | +| nginx 访问日志(实时跟踪) | `docker logs -f youle-nginx` | +| wxserver 日志(末尾50行) | `docker logs --tail 50 youle-wxserver` | +| API PHP 错误日志(末尾50行) | `docker exec youle-api tail -50 /var/log/apache2/php_errors.log` | +| API 业务日志_今天(末尾50行) | `docker exec youle-api tail -50 /var/www/html/logs/$(date +%Y-%m-%d).log` | +| API 业务日志_今天(实时跟踪) | `docker exec youle-api tail -f /var/www/html/logs/$(date +%Y-%m-%d).log` | +| 列出 API 业务日志文件 | `docker exec youle-api ls -lh /var/www/html/logs/` | +| 同步调试日志_今天(末尾50行) | `docker exec youle-dlweb tail -50 /var/www/html/api/ext/debug/synchronize/$(date +%Y-%m-%d).log` | +| 同步调试日志_今天(实时跟踪) | `docker exec youle-dlweb tail -f /var/www/html/api/ext/debug/synchronize/$(date +%Y-%m-%d).log` | +| syncjob 任务日志(末尾50行) | `docker logs --tail 50 youle-syncjob` | +| cronjob 任务日志(末尾50行) | `docker logs --tail 50 youle-cronjob` | + +### 清理日志 + +| 目标 | 命令 | +|------|------| +| 清空 nginx docker logs | `truncate -s 0 $(docker inspect --format='{{.LogPath}}' youle-nginx)` | +| 清空 API docker logs | `truncate -s 0 $(docker inspect --format='{{.LogPath}}' youle-api)` | +| 清空 dlweb docker logs | `truncate -s 0 $(docker inspect --format='{{.LogPath}}' youle-dlweb)` | +| 清空所有容器 docker logs | `for n in youle-nginx youle-api youle-dlweb youle-wxserver youle-syncjob youle-cronjob youle-redis youle-certbot; do truncate -s 0 $(docker inspect --format='{{.LogPath}}' $n 2>/dev/null) 2>/dev/null; done` | +| 清空今天 API 业务日志 | `docker exec youle-api truncate -s 0 /var/www/html/logs/$(date +%Y-%m-%d).log` | +| 清空今天同步调试日志 | `docker exec youle-dlweb truncate -s 0 /var/www/html/api/ext/debug/synchronize/$(date +%Y-%m-%d).log` | +| 删除 API 全部历史日志 | `docker exec youle-api sh -c 'rm -f /var/www/html/logs/*.log'` | +| 删除调试日志 30 天前旧文件 | `docker exec youle-dlweb find /var/www/html/api/ext/debug/ -name '*.log' -mtime +30 -delete` | +| 删除调试日志全部文件 | `docker exec youle-dlweb sh -c 'rm -f /var/www/html/api/ext/debug/synchronize/*.log /var/www/html/api/ext/debug/SynchronizeReportData/*.log /var/www/html/api/ext/debug/autotask/*.log'` | +| 一键清理全部日志 | `/opt/youle/game-docker/clear-logs.sh` | diff --git a/codes/agent/game-docker/docs/07-uninstall.md b/codes/agent/game-docker/docs/07-uninstall.md new file mode 100644 index 0000000..4a30ff7 --- /dev/null +++ b/codes/agent/game-docker/docs/07-uninstall.md @@ -0,0 +1,144 @@ +# 卸载和清理 + +根据需求选择卸载范围。以下操作不可逆,请提前备份重要数据。 + +--- + +## 卸载前:备份关键数据 + +```bash +cd /opt/youle/game-docker + +# 1. 备份 .env(包含所有密钥,不在版本库中) +cp .env ~/youle-env-backup.env + +# 2. 备份 Redis 数据(如有业务数据存储在 Redis 中) +docker exec youle-redis redis-cli -a "${REDIS_PASSWORD}" BGSAVE +# 或直接备份 volume +docker run --rm -v game-docker_redis-data:/data -v ~/:/backup alpine \ + tar czf /backup/redis-data-backup.tar.gz /data + +# 3. 备份日志(按需) +docker cp youle-api:/var/www/html/logs ~/api-logs-backup +docker cp youle-dlweb:/var/www/html/api/logs ~/dlweb-logs-backup +``` + +--- + +## 仅停止所有容器(保留镜像和数据,可随时恢复) + +```bash +cd /opt/youle/game-docker +docker compose stop + +# 验证 +docker compose ps +``` + +恢复运行: + +```bash +docker compose start +``` + +--- + +## 停止并删除容器(保留镜像、volumes 和项目文件) + +```bash +cd /opt/youle/game-docker +docker compose down + +# 验证容器已删除 +docker ps -a | grep youle +``` + +> 此操作不会删除数据 volume 和已构建的镜像,再次 `docker compose up -d` 可快速恢复,无需重新构建。 + +--- + +## 完全卸载(删除容器 + volumes + 镜像) + +> **警告:** 以下操作将删除 Redis 缓存和所有日志数据,不可恢复。 + +```bash +cd /opt/youle/game-docker + +# 停止并删除容器 + 所有相关 volumes +docker compose down -v + +# 删除本项目构建的镜像 +docker rmi game-docker-api game-docker-dlweb game-docker-wxserver 2>/dev/null || true + +# 验证 +docker volume ls | grep game-docker +docker images | grep game-docker +``` + +--- + +## 彻底清理(删除容器 + volumes + 镜像 + 项目目录 + SSL 证书) + +> **警告:** SSL 证书删除后需重新申请(Let's Encrypt 有频率限制,每 7 天最多 5 次)。 + +```bash +cd /opt/youle/game-docker + +# 1. 停止并删除容器 + volumes +docker compose down -v + +# 2. 删除构建镜像 +docker rmi game-docker-api game-docker-dlweb game-docker-wxserver 2>/dev/null || true + +# 3. 清理 Docker 悬空资源(可选) +docker system prune -f + +# 4. 删除 SSL 证书 +docker volume rm game-docker_certbot-certs game-docker_certbot-webroot 2>/dev/null || true + +# 5. 删除项目目录 +rm -rf /opt/youle/game-docker +``` + +--- + +## 删除单个服务的容器和镜像 + +```bash +cd /opt/youle/game-docker + +# 以 dlweb 为例 +docker compose stop dlweb +docker compose rm -sf dlweb +docker rmi game-docker-dlweb + +# 下次启动时会重新构建 +docker compose up -d --build dlweb +``` + +--- + +## 清理定时任务残留 + +```bash +docker compose stop syncjob cronjob +docker compose rm -sf syncjob cronjob + +# 清理共享信号 volume(如有残留暂停文件) +docker run --rm -v game-docker_shared-signal:/shared alpine rm -f /shared/syncjob.pause + +# 如需完全删除共享 volume +docker volume rm game-docker_shared-signal +``` + +--- + +## 卸载操作速查 + +| 目标 | 命令 | 保留内容 | +|------|------|----------| +| 临时停止(可恢复) | `docker compose stop` | 容器 / 镜像 / volumes / 文件 | +| 删除容器 | `docker compose down` | 镜像 / volumes / 文件 | +| 删除容器 + volumes | `docker compose down -v` | 镜像 / 文件 | +| 删除容器 + volumes + 镜像 | `docker compose down -v` + `docker rmi ...` | 文件 | +| 完全清理 | 上述全部 + `rm -rf /opt/youle/game-docker` | 无 | diff --git a/codes/agent/game-docker/docs/08-database-remote.md b/codes/agent/game-docker/docs/08-database-remote.md new file mode 100644 index 0000000..8e85a21 --- /dev/null +++ b/codes/agent/game-docker/docs/08-database-remote.md @@ -0,0 +1,85 @@ +# 数据库远程管理(Navicat SSH 隧道) + +> RDS 白名单仅开放服务器 `47.98.203.17`,任何设备需通过 SSH 隧道访问数据库,无需开放公网 IP,安全可控。 + +--- + +## 原理 + +``` +本机 Navicat ──SSH加密隧道──▶ 47.98.203.17 ──内网──▶ RDS MySQL +``` + +--- + +## 数据库与 RDS 实例对应关系 + +| 数据库 | RDS 主机 | +|--------|---------| +| `agent_db`、`agent_db_temp`、`game_field`、`youlehudong` | `rm-bp1btyuwq77591x0jpo.mysql.rds.aliyuncs.com` | +| `game_db`、`grade_db` | `rm-bp1749tfxu2rpq670lo.mysql.rds.aliyuncs.com` | + +--- + +## Navicat 连接配置(以 agent_db 为例) + +### 第一步:SSH 标签页 + +| 字段 | 值 | +|------|----| +| 使用 SSH 通道 | ✅ 勾选 | +| 主机 | `47.98.203.17` | +| 端口 | `22` | +| 用户名 | `root` | +| 验证方法 | **公钥** | +| 私钥文件 | `C:\Users\{你的用户名}\.ssh\id_ed25519` | + +> **注意**:当前服务器已授权的密钥为 `id_ed25519`(标识 `youle-deploy`),选错密钥会导致认证失败。 + +### 第二步:常规标签页 + +| 字段 | 值 | +|------|----| +| 主机名/IP | `rm-bp1btyuwq77591x0jpo.mysql.rds.aliyuncs.com` | +| 端口 | `3306` | +| 用户名 | `games` | +| 密码 | `Games0791!!` | +| 数据库 | `agent_db`(可留空后再选) | + +> ⚠️ **常见错误(2013 错误)**:常规标签的主机名填了 `127.0.0.1` 或 `localhost`,会连接到服务器本机而非 RDS,导致握手失败。必须填 RDS 完整域名。 + +--- + +## 新设备接入 + +在新设备上执行以下步骤: + +```powershell +# 1. 生成密钥对(如没有) +ssh-keygen -t ed25519 -C "设备标识备注" + +# 2. 查看公钥内容 +Get-Content "$env:USERPROFILE\.ssh\id_ed25519.pub" +``` + +将公钥内容追加到服务器: + +```bash +ssh root@47.98.203.17 "echo 'ssh-ed25519 AAAA...你的公钥内容...' >> ~/.ssh/authorized_keys" +``` + +之后 Navicat SSH 标签填写该设备的私钥路径即可。 + +--- + +## 命令行手动隧道(可选) + +如需在命令行工具(如 mysql CLI)中使用,可手动建立隧道: + +```bash +# 建立隧道(保持此终端运行,另开终端连接) +ssh -L 3307:rm-bp1btyuwq77591x0jpo.mysql.rds.aliyuncs.com:3306 root@47.98.203.17 -N + +# 另开终端,连接本地转发端口 +mysql -h 127.0.0.1 -P 3307 -u games -p agent_db +```