奇迹MU OpenMU 部署在绿联 NAS:Docker、端口与局域网联机完整记录

阅读 -- 次

# 奇迹MU OpenMU 部署在绿联 NAS:Docker、端口与局域网联机完整记录

本文记录个人家庭局域网中的 OpenMU 技术实践,只用于学习、测试和自建环境排错。文章不提供游戏客户端、CD KEY、破解文件、游戏数据或第三方整合包,也不提供对外公开运营方案。OpenMU 服务端项目的许可证不覆盖游戏客户端、美术资源、音乐、地图和商标;相关文件应由使用者按自己合法持有的版本和授权范围准备。

先看结果

OpenMU 管理后台登录后的首页
OpenMU 管理后台登录后的首页

这次在绿联 DXP6800 Pro 上,用 Docker Compose 跑起了三部分:

浏览器
  ↓ 18443
Nginx
  ↓ 8080
OpenMU 管理后台、Connect Server、Game Server
  ↓
PostgreSQL

局域网游戏链路是:

MU 客户端
  ↓ 18405
Connect Server
  ↓ 18451
Game Server

最终使用的主要端口如下:

端口 用途
18443OpenMU 管理后台,仅建议局域网访问
18405原版客户端 Connect Server
18406开源客户端 Connect Server
18451第一个 Game Server
18480聊天服务器
OpenMU Server 0 与两个 Connect Server 的运行状态,已移除账号栏
OpenMU Server 0 与两个 Connect Server 的运行状态,已移除账号栏

本文不是一条命令就结束的“一键包”。本次真正耗时的部分,是让 Docker 端口映射、OpenMU 数据库里的监听端口、IP 解析器和 Nginx 跳转地址保持一致。

一、准备范围

测试环境是一台 x86_64 架构的绿联 DXP6800 Pro,Docker 中已有其他项目运行。本文新建独立目录和独立数据卷,不修改现有容器。

准备:

  1. NAS 上的 Docker 和 Docker Compose。
  2. /volume1/docker/qijiMU 独立目录。
  3. 一个合法的 Season 6 Episode 3 游戏客户端目录。本文不提供客户端文件。
  4. Windows 游戏电脑和官方 OpenMU Client Launcher。
  5. 三个不冲突的 TCP 端口、一个 Web 端口和一个聊天端口。

目录结构:

qijiMU/
├── docker-compose.yml
├── env.example
├── README.md
├── check.sh
└── nginx/
    └── nginx.dev.conf

二、服务端项目和授权边界

OpenMU 是一个独立实现的 MU Online 服务端项目,当前使用的版本是 0.9.12,代码采用 MIT 许可证。但这不意味着项目附带游戏客户端,也不代表原游戏的美术、音乐、地图、名称和商标可以被自由分发。

这篇文章只讨论:

  • Docker、PostgreSQL、Nginx 和端口配置;
  • OpenMU 管理后台初始化;
  • 个人家庭局域网内的技术测试;
  • 日志分析和排错。

不会提供:

  • 游戏客户端或补丁下载;
  • CD KEY、账号或授权文件;
  • 破解程序、外挂或绕过验证的方法;
  • 未获授权的游戏数据、地图、音乐和资源包;
  • 面向公众的收费运行方案。

三、Compose 设计

这里把数据库、OpenMU 和 Nginx 分成三个服务。数据库不发布到宿主机,只允许同一 Compose 网络中的 OpenMU 访问。

核心配置如下:

name: qijimu

services:
  web:
    image: nginx:alpine
    restart: unless-stopped
    ports:
      - "0.0.0.0:18443:80"
    volumes:
      - ./nginx/nginx.dev.conf:/etc/nginx/nginx.conf:ro

  openmu:
    image: munique/openmu:0.9.12
    restart: unless-stopped
    init: true
    environment:
      ASPNETCORE_ENVIRONMENT: Production
      ASPNETCORE_URLS: http://+:8080
      TZ: Asia/Shanghai
      DB_HOST: database
      DB_ADMIN_USER: postgres
      DB_ADMIN_PW: ${DB_ADMIN_PW}
      OPENMU_ADMIN_USER: ${OPENMU_ADMIN_USER}
      OPENMU_ADMIN_PASSWORD: ${OPENMU_ADMIN_PASSWORD}
    ports:
      - "18405:18405"
      - "18406:18406"
      - "18451:18451"
      - "18480:18480"
    volumes:
      - qijimu-keys:/app/data-protection-keys
    depends_on:
      database:
        condition: service_healthy

  database:
    image: postgres:17-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: openmu
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: ${DB_ADMIN_PW}
      TZ: Asia/Shanghai
    volumes:
      - qijimu-db:/var/lib/postgresql/data

volumes:
  qijimu-db:
    name: qijimu-db
  qijimu-keys:
    name: qijimu-keys

实际文件还为数据库、OpenMU 和 Nginx 增加了健康检查,让 Nginx 等 OpenMU 健康后再启动。

这里特意避免使用 80、443、3306 和常用的数据库端口。18405 到 18451 都低于 49152,避开了 Windows 常见的临时端口范围。

四、环境变量与密码

创建配置文件:

cd /volume1/docker/qijiMU
cp env.example .env
chmod 600 .env

密码使用随机值:

openssl rand -hex 24

至少执行两次,分别填写:

DB_ADMIN_PW=<数据库随机密码>
OPENMU_ADMIN_USER=<后台登录名>
OPENMU_ADMIN_PASSWORD=<后台随机密码>

不要把 .env、管理员密码、Cookie、API Key 或数据库导出文件提交到 Git,也不要发到公开聊天和网盘。

启动前先检查:

cd /volume1/docker/qijiMU
bash check.sh
docker compose config --quiet
docker compose pull
docker compose up -d
docker compose ps

三个容器都应处于 Up,数据库和 OpenMU 应为 healthy。

五、第一次进入管理后台

局域网管理地址:

http://NAS_LAN_IP:18443/

首次进入后,确认数据库状态并初始化 Season 6 Episode 3。

不要在生产环境勾选公开测试账号。本次数据库自动生成了若干测试账号,登录后台后应立即检查账户列表;确认测试结束后,删除、禁用或修改这些账号。

同时创建自己的正式管理员用户,设置独立密码和双重验证。.env 里的引导管理员只用于初始化或恢复,不应长期作为日常账号。

六、IP 解析器:Game Server 启动失败的根因

第一次启动 Game Server 时,服务进程出现后又立刻停止。日志里反复出现:

Could not start the server listeners:
Connection refused (api.ipify.org:443)

端口并没有冲突。真正的原因是 IP 解析器选择了 Public,启动监听器前会访问 api.ipify.org 获取公网地址;NAS 环境无法访问该地址,于是游戏服务器在开始监听前抛出异常。

进入:

游戏配置 → 系统 → IP 地址解析方式

可选值对应关系:

页面选项 含义
自动Auto
公网Public
局域网Local
本机回环Loopback
自定义Custom
OpenMU IP 地址解析方式配置页
OpenMU IP 地址解析方式配置页

家庭局域网测试建议选“自定义”,并填写 NAS 的真实局域网 IP。只选“局域网”也通常可以让进程启动,但在容器环境中可能返回容器内部地址,客户端选服后仍可能断开。

保存后,重新加载服务器配置,再启动 Game Server。

七、Docker 端口不等于 OpenMU 监听端口

这是部署时最容易踩的坑:

Docker 把宿主机 18451 映射到容器 18451

并不代表 OpenMU 自动在容器里监听 18451。

数据库里仍然保存着原始端口:

Connect Server:44405、44406
Game Server:45901、45903、45905

因此还需要在管理后台逐项修改:

对象 建议端口
原版客户端 Connect Server18405
开源客户端 Connect Server18406
第一个 Game Server18451
Chat Server18480
Server 0 的 Game Server 端点已改为 18451
Server 0 的 Game Server 端点已改为 18451

只保留一个 Game Server,避免客户端列表里出现已经停止或没有端口映射的服务器。

八、修改 Connect Server 后必须重启监听器

端口在数据库里保存后,正在运行的 Connect Server 不会自动换端口。第一次修改后,页面显示“运行中”,但实际仍监听旧的 44405/44406,外部访问 18405 依然会被拒绝。

正确顺序:

  1. 停止两个 Connect Server。
  2. 修改监听端口。
  3. 保存配置。
  4. 重新启动两个 Connect Server。
  5. 用日志确认。
docker logs --tail 300 qijimu-game 2>&1 \
  | grep "Client Listener started" | tail -10

应看到:

Client Listener started, Port 18405
Client Listener started, Port 18406
Connect Server 的监听端口已改为 18405
Connect Server 的监听端口已改为 18405

如果仍显示 44405/44406,说明旧监听器没有真正重启,或者配置没有保存。

九、非 80 端口下的后台登录跳转

管理后台从 18443 访问时,根路径返回了:

302 Found
Location: http://NAS_LAN_IP/login?ReturnUrl=/

跳转地址缺少 18443,浏览器于是回到 80 端口,页面自然打不开。

Nginx 转发 OpenMU 时,需要保留客户端原始 Host,并关闭默认的代理地址重写:

location / {
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Host $http_host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_redirect off;
    proxy_pass http://openmu:8080;
}

修改后重启 Nginx:

docker compose restart web
curl -sS -D - -o /dev/null http://NAS_LAN_IP:18443/ \
  | grep -i '^location:'

正确结果应保留端口:

Location: http://NAS_LAN_IP:18443/login?ReturnUrl=%2F

十、局域网连通性验证

先看宿主机是否在监听:

ss -lntp | grep -E ':18443|:18405|:18406|:18451|:18480'

宿主机上的 docker-proxy 应监听这些端口。

再从另一台局域网电脑验证:

nc -vz NAS_LAN_IP 18443
nc -vz NAS_LAN_IP 18405
nc -vz NAS_LAN_IP 18451

管理后台使用 GET 请求测试:

curl -sS -o /dev/null -w '%{http_code}\n' \
  http://NAS_LAN_IP:18443/

返回 302 是正常的登录跳转。不要使用 curl -I 判断全部服务,因为 OpenMU 的管理页面可能不支持 HEAD 请求,从而返回 405 Method Not Allowed。

十一、客户端启动器连接

OpenMU 不附带游戏客户端。客户端目录应由使用者按自己合法持有的版本准备。

官方启动器可以在 Windows 上把客户端连接到指定地址和端口。启动后选择客户端目录里的 main.exe,新增一个连接配置:

Description: NAS Local Server
Server-Address: NAS_LAN_IP
Server Port: 18405

保存后,在 Server 下拉框中选择该配置,再点 Launch Client。

建议在后台新建自己的测试游戏账号,不要长期依赖公开默认账号。首次登录后再创建角色。

如果能看到服务器列表,但选择 Server 后断开,依次检查:

  1. IP 解析器填写的地址是否正确;
  2. 18451 是否在宿主机监听;
  3. Game Server 是否处于运行中;
  4. Docker 映射端口和后台配置是否完全一致。

十二、安全收尾

完成首次测试后,做这几件事:

  1. 删除、禁用或修改自动生成的测试账号。
  2. 创建正式后台管理员并开启双重验证。
  3. 管理后台保持局域网访问,不直接开放到互联网。
  4. 不公开 .env、管理员密码、API Key 和数据库备份。
  5. 如需远程访问,优先使用 Tailscale,或使用经过配置的 HTTPS 反向代理。

本文不讨论公网收费运行。远程访问本身也要先确认网络、安全、客户端授权和当地规则。

十三、备份

先停止应用,再导出数据库:

cd /volume1/docker/qijiMU
mkdir -p backups
docker compose stop openmu web

docker compose exec -T database sh -c \
  'pg_dump -U "$POSTGRES_USER" -d "$POSTGRES_DB" -Fc' \
  > "backups/qijimu-$(date +%Y%m%d-%H%M).dump"

docker run --rm \
  -v qijimu-keys:/src:ro \
  -v "$PWD/backups:/backup" \
  alpine sh -c 'tar czf /backup/qijimu-keys.tgz -C /src .'

docker compose start openmu web

数据库结构和配置更新前都先备份。docker compose down -v 会删除数据库卷,不要在未确认备份时执行。

十四、常见故障

现象 优先检查
管理后台跳转到没有端口的地址Nginx Host 头和 proxy_redirect
Game Server 一启动就停止IP 解析器、api.ipify.org、日志中的首个异常
18405 在外网电脑上被拒绝Connect Server 是否真正重启,防火墙是否放行
能看到服务器列表,选服后断开IP 解析器返回地址和 18451 映射
Docker 显示端口已发布,但连接被拒绝容器内服务是否真的监听同一端口
修改端口后马上测试失败保存后是否停止并重启对应监听器

最后

这类部署最麻烦的地方,不是把三个容器拉起来,而是让四层配置互相一致:

数据库中的监听端口
OpenMU 进程实际绑定的端口
Docker 宿主机映射端口
客户端实际连接地址和端口

IP 解析器决定客户端选服后去找哪个地址;端口决定它能不能真正进入 Game Server。把这两件事分开检查,比反复删除容器和重装数据库有效得多。

参考资料

【后续更新与提问】

问题答疑和后续更新会在 idindoo.com 站点持续维护;免费注册账号后可以提交部署问题,方便答疑。

需要交流时,可加入 idindoo QQ 交流群 1131068116。提问请注明 NAS 型号、Wine 版本、容器状态、数据库报错和实际端口。

消息盒子

# 暂无消息 #

只显示最新10条未读和已读信息

版权与侵权投诉