最近我用 1Panel + MCSManager + Docker 搭建了一个 Minecraft Paper 服务器。服务端本身能够正常启动,但是客户端一直无法正常联机。整个问题排查下来,发现并不是 Minecraft 服务端没有启动,而是 Docker 端口映射、MCSManager 容器化配置以及离线版登录验证几个问题叠加导致的。
这篇文章记录一下完整排查过程,方便以后自己复盘,也希望能帮到遇到类似问题的人。
一、问题现象
服务器环境大致如下:
系统:Debian
面板:1Panel
管理器:MCSManager
服务端:Paper 1.21.11
Java:21
默认端口:25565
部署方式:Docker
最开始在 MCSManager 里启动 Minecraft 实例时,日志显示服务端已经启动成功:
Starting Minecraft server on *:25565
Done (...)! For help, type "help"
这说明 Paper 服务端本身没有崩溃,监听端口也是正常的 25565。
但是客户端连接服务器时一直失败。最开始我以为是 1Panel 防火墙、云服务器安全组或者服务器端口没有放行。后来逐项检查后发现:
1Panel 防火墙:已放行 TCP 25565
云服务器安全组:已放行 TCP 25565
Paper 服务端:已监听 25565
按理说已经满足外网联机条件,但还是连接不上。
二、第一次排查:Docker 容器端口没有映射
后来通过 SSH 执行:
docker ps
发现 mcsmanager-daemon 容器只映射了管理端口:
0.0.0.0:40057->24444/tcp
但是没有看到 Minecraft 需要的:
0.0.0.0:25565->25565/tcp
这就说明问题很可能出在 Docker 端口映射上。
虽然 Minecraft 服务端在容器内部监听了 25565,但是宿主机没有把这个端口暴露出来,外网自然访问不到。
一开始我尝试去修改:
/opt/1panel/apps/mcsmanager-daemon/mcsmanager-daemon/docker-compose.yml
在 ports 下添加:
- "25565:25565/tcp"
但实际效果并不理想,docker ps 里仍然没有出现 25565->25565/tcp。后来发现,1Panel 应用商店安装的应用,直接手动改 compose 文件并不是最推荐的方式,后续重建、更新或者面板管理时也可能不稳定。
于是换了一个更合适的办法:让 Minecraft 实例本身容器化运行,并由实例容器开放 25565。
三、正确方向:开启 MCSManager 实例容器化
进入 MCSManager 后,打开 Minecraft 实例的:
应用实例设置 → 容器化
然后开启:
启用 Docker 容器
我这里服务端是 Paper 1.21.11,需要 Java 21,所以 Docker 镜像填写:
eclipse-temurin:21-jre
容器内工作目录填写:
/workspace
并且打开“更改容器默认工作目录”。
端口映射这里是最关键的,添加:
外部访问端口:25565
容器内端口:25565
协议:TCP
也就是等价于:
25565:25565/tcp
网络模式保持:
bridge
容器名可以自定义,例如:
mc-paper
这样做的思路是:
不再强行让 mcsmanager-daemon 占用 Minecraft 的游戏端口,而是让 Minecraft 实例自己的容器开放 25565。
四、遇到的新错误:mount path must be absolute
开启实例容器化后,第一次启动又出现了新的错误:
invalid mount config for type "bind":
invalid mount path: 'data/daemon/data/InstanceData/...' mount path must be absolute
这个错误的意思是:MCSManager 在创建实例容器时,要把实例目录挂载进 Docker 容器,但是它传给 Docker 的宿主机路径是相对路径。
错误路径类似:
data/daemon/data/InstanceData/...
而 Docker 要求宿主机挂载路径必须是绝对路径,比如:
/opt/1panel/apps/mcsmanager-daemon/mcsmanager-daemon/data/daemon/data/InstanceData
解决方法是修改 mcsmanager-daemon 的 compose 配置。
打开:
/opt/1panel/apps/mcsmanager-daemon/mcsmanager-daemon/docker-compose.yml
找到环境变量:
MCSM_DOCKER_WORKSPACE_PATH
把它改成绝对路径:
- MCSM_DOCKER_WORKSPACE_PATH=/opt/1panel/apps/mcsmanager-daemon/mcsmanager-daemon/data/daemon/data/InstanceData
同时注意:如果之前在 daemon 的 ports 里手动添加过 25565:25565/tcp,这时要删掉,避免 daemon 先占用 25565,导致 Minecraft 实例容器无法使用这个端口。
也就是说 daemon 的端口只保留管理端口即可:
ports:
- ${HOST_IP}:${PANEL_APP_PORT_HTTP}:24444
然后在 SSH 中执行:
cd /opt/1panel/apps/mcsmanager-daemon/mcsmanager-daemon
docker compose down
docker compose up -d
重建完成后,再回到 MCSManager 启动 Minecraft 实例。
五、服务端成功启动
重新启动后,日志终于正常了:
已挂载工作目录:/opt/1panel/apps/mcsmanager-daemon/... --> /workspace
已为实例开放以下端口:
外部访问端口:25565 -> 容器内端口:25565 / 协议:tcp
Starting Minecraft server on *:25565
Done (...)! For help, type "help"
这说明几个关键点都成功了:
1. Minecraft 实例容器创建成功
2. 服务端目录挂载成功
3. 25565 端口映射成功
4. Paper 服务端正常启动
到这里,服务器已经不是“外网连不到”的状态了,而是客户端确实能够访问到服务端。
六、客户端报错:Connection throttled
第一次客户端连接时,出现了:
Connection throttled! Please wait before reconnecting.
这个不是版本问题,而是连接太频繁,被 Bukkit/Paper 的连接节流限制拦了一下。
可以先等十几秒再重新连接。如果一直出现,可以修改:
bukkit.yml
找到:
connection-throttle: 4000
改成:
connection-throttle: -1
保存后重启服务器。
七、离线版客户端报错:无效会话
后来客户端又出现:
登录失败:无效会话(请尝试重启游戏及启动器)
这个就和离线版启动器有关了。
Minecraft 服务端默认开启正版验证:
online-mode=true
如果客户端是离线版、非正版启动器,就可能无法通过 Mojang 正版会话验证。
解决方法是编辑:
server.properties
把:
online-mode=true
改成:
online-mode=false
保存后重启服务器。
需要注意的是,关闭正版验证后,服务器安全性会降低,因为玩家可以使用任意名字进入服务器。建议同时开启白名单:
whitelist on
whitelist add 玩家名
这样可以减少陌生人乱进服务器的风险。
八、最终总结
这次问题不是单一原因,而是几个点叠加造成的:
1. Paper 服务端本身其实已经正常启动
2. 1Panel 防火墙和云服务器安全组都没问题
3. 真正卡住的是 Docker 端口映射
4. 不建议直接让 mcsmanager-daemon 占用 25565
5. 更合适的方式是开启 MCSManager 实例容器化
6. 容器化时要设置 25565:25565/tcp
7. MCSM_DOCKER_WORKSPACE_PATH 必须使用绝对路径
8. 离线版客户端需要关闭 online-mode
9. Connection throttled 是连接过快导致的限流
最终可用配置大致如下。
MCSManager 实例容器化配置
启用 Docker 容器:开启
Docker 镜像:eclipse-temurin:21-jre
容器内工作目录:/workspace
开放端口:25565 -> 25565 / TCP
网络模式:bridge
容器名:mc-paper
mcsmanager-daemon 配置重点
environment:
- MCSM_DOCKER_WORKSPACE_PATH=/opt/1panel/apps/mcsmanager-daemon/mcsmanager-daemon/data/daemon/data/InstanceData
server.properties
online-mode=false
bukkit.yml
connection-throttle: -1
九、排障经验
这次最大的经验是:
看到 Minecraft 服务端日志里出现 Done,并不代表外网一定能连上。对于 Docker 部署的服务来说,还要检查宿主机端口是否真的映射出来。
排查顺序建议是:
1. 看服务端是否 Done
2. 看服务端是否监听 25565
3. 看 docker ps 是否有 25565->25565/tcp
4. 看 1Panel 防火墙是否放行
5. 看云服务器安全组是否放行
6. 看客户端版本是否一致
7. 看是否需要关闭 online-mode
如果 docker ps 里没有看到:
0.0.0.0:25565->25565/tcp
那基本就可以判断:服务端可能在容器里跑着,但外网还没有真正访问到它。
这次折腾下来,最终解决方案就是:
使用 MCSManager 的实例容器化功能,让 Minecraft 实例自己的 Docker 容器开放 25565,而不是把游戏端口硬塞给 mcsmanager-daemon。