想和朋友一起玩 Minecraft,结果发现有人用手机、有人用 Switch、有人用 Windows —— 这种组合下开 Java 版服务器是行不通的。基岩版客户端连不上 Java 服,反过来也一样。
站内那篇 Minecraft Java 服务器教程讲的是 Paper 服务端,适用于 PC 玩家。这篇讲的是基岩版(Bedrock Dedicated Server),专门解决手机、平板、主机、Windows 一起玩的问题。
两者的服务端软件、配置方式、端口协议完全不同,Java 那套配置基本不能照搬。
选错了方向,后面全是白费功夫。
| Java 版 | 基岩版 | |
|---|---|---|
| 服务端 | Paper / Purpur / Fabric | BDS(官方) |
| 能进的客户端 | 只有 PC | 手机、平板、Xbox、PS、Switch、Windows |
| 网络协议 | TCP 25565 | UDP 19132 |
| 插件生态 | 极强(Spigot 3 万+ 插件) | 几乎没有,只有行为包 |
| 模组 | Forge / Fabric 深度魔改 | 行为包 + 资源包,改不深 |
| 内存占用 | 每玩家约 100-150MB | 每玩家约 50-80MB |
| 启动时间 | 15-60 秒 | 5-15 秒 |
| 官方支持的系统 | 无限制 | Linux 只认 Ubuntu |
一句话判断:
- 玩家全在 PC,要插件要模组 → 开 Java 服
- 玩家有手机或主机 → 开基岩服
- 两边都有 → 别开基岩服,去开 Java 服 + Geyser
最后这条是最容易踩的坑。Geyser 是个 Java 服务端插件,装上之后基岩版客户端就能进 Java 服。很多人以为"要支持手机就开基岩服",结果丢了整个 Java 插件生态。 如果你的朋友里既有 PC 又有手机,正确路线是 Java 服 + Geyser,而不是基岩服。
只有"清一色移动端和主机、完全不需要插件"的情况,才该开纯基岩服。
官方文档写的最低要求是 4GB 内存,但那是给"独立服务器专机"的保守值,实际用不了那么多。
| 玩家数(原版) | 内存 | CPU |
|---|---|---|
| 2-4 人 | 2GB | 1 核够 |
| 5-10 人 | 2-4GB | 2 核 |
| 10-20 人 | 4-8GB | 2-4 核,单核主频要高 |
基岩版是 C++ 写的,没有 JVM 堆预分配那一套,同样人数下比 Java 版省一半左右的内存。1 核 1G 的小鸡开原版、把视距调低,带十来个人也不是不行,但别指望它能扛住大型红石机器或者几百只实体同时运算。
真正拖后腿的往往不是内存,是这两样:
单核主频。 服务器主线程的运算跑不快,TPS 就掉。买机器的时候看 CPU 型号,比看核心数有用。
硬盘。 世界文件随着探索不断膨胀,机械盘在区块加载时会明显拖慢。选 NVMe。
带宽反而不是问题。基岩版的流量不大,十来个玩家的常规游玩,2-3Mbps 足够了。但延迟很要命 —— 国内玩家连海外的机器,一两百毫秒的延迟会让挖方块手感发飘。玩家在国内的话,优先选线路好的亚洲节点。游戏服务器 VPS 推荐里有按场景分的选型建议。
官方确实提供 Linux 版 BDS,就是一个压缩包加一个 bedrock_server 可执行文件。但它有几个麻烦:升级要手动下载覆盖、只支持 Ubuntu、崩溃了没有自动重启。
社区镜像 itzg/minecraft-bedrock-server 把这些都包好了,支持指定版本、环境变量配置、自动重启。
docker-compose.yml:
services:
bedrock:
image: itzg/minecraft-bedrock-server
container_name: minecraft-bedrock
restart: unless-stopped
environment:
EULA: "TRUE"
SERVER_NAME: "周末生存服"
GAMEMODE: survival
DIFFICULTY: normal
MAX_PLAYERS: 10
ONLINE_MODE: "true"
ALLOW_LIST: "true"
VIEW_DISTANCE: 16
TICK_DISTANCE: 4
VERSION: LATEST
ports:
- "19132:19132/udp"
- "19133:19133/udp"
volumes:
- ./data:/data
tty: true
stdin_open: true
几个必须说清楚的点:
端口后面那个 /udp 不能漏。 基岩版用的是 RakNet 协议,跑在 UDP 上。写成 19132:19132 默认是 TCP,容器起来了、日志也正常,但所有客户端都连不上。这是排查列表上的第一条。
EULA: "TRUE" 是启动的前提。 不接受 EULA 容器会直接退出,日志里会写得很明白。
19133 是 IPv6 端口。 你的机器如果没有 IPv6,这一行可以删掉;有双栈的话留着,纯 IPv6 网络下的玩家(某些移动网络)要靠它连进来。
tty 和 stdin_open 别删。 后面要用它往服务器控制台发命令。
启动:
docker compose up -d
docker compose logs -f
日志里出现 Server started. 就说明世界生成完了,可以连了。
镜像支持用环境变量覆盖配置,但也可以直接改 ./data/server.properties。后者改完要重启容器才生效(容器启动时会读一次)。
常用的几项:
| 属性 | 默认 | 说明 |
|---|---|---|
server-name | Dedicated Server | 服务器列表里显示的名字 |
gamemode | survival | 新玩家模式:survival / creative / adventure |
difficulty | easy | peaceful / easy / normal / hard |
allow-cheats | false | 开不开作弊指令,开了之后玩家能 /gamemode |
max-players | 10 | 上限,调高会增加运算压力 |
online-mode | true | 是否要求 Xbox Live 正版认证 |
allow-list | false | 只允许白名单玩家进 |
view-distance | 32 | 视距(区块),这是最吃性能的一项 |
tick-distance | 4 | 保持模拟的区块半径(4-12) |
player-idle-timeout | 30 | 挂机多少分钟被踢,0 表示不踢 |
view-distance 从 32 降到 16,服务器负载能明显下降,代价是远处的地形看得没那么远。人少或者机器弱就往下调,这是性价比最高的一项优化。
online-mode 别关。 关掉之后任何人都能用任意 ID 进来(包括冒充你的 ID),只在自己完全可控的局域网里才考虑关闭。
tick-distance 别乱调高。 它决定哪些区块持续运算(刷怪、红石、农作物生长)。调到 12 会让 CPU 直接跪,除非你的机器是真·性能怪兽。
私人服一定要开白名单。ALLOW_LIST: "true" 打开后,只有 allowlist.json 里的玩家能进来。
别手动编辑 allowlist.json。 服务器在运行时会把它缓存到内存,你手改的文件会被覆盖,白名单还不生效。正确做法是通过控制台命令:
allowlist add 玩家名
allowlist remove 玩家名
allowlist reload
op 玩家名
deop 玩家名
发命令的方式是 attach 进容器:
docker attach minecraft-bedrock
然后直接敲命令回车。
退出的时候按 Ctrl+P 再按 Ctrl+Q,不是 Ctrl+C。Ctrl+C 会直接把服务器停掉,玩家全掉线 —— 这个坑几乎每个人都踩过一次。
名字里有空格的,用引号包起来:allowlist add "Some Player"。
权限分三级,写在 permissions.json 里,同样建议用命令管理:普通访客(visitor)、成员(member)、管理员(operator)。给人 op 之前想清楚,管理员能执行 stop、kill、改游戏规则。
服务器跑起来之后,进来的地址就是 你的公网IP:19132。
手机版在"游戏 → 服务器 → 添加服务器"里填,界面上有三个字段:服务器名称(随便起)、服务器地址、端口。地址填 IP 或域名,端口填 19132。Xbox 和 Switch 的操作类似,都不需要额外的客户端软件。
IP 有个问题:不好记,而且换机器就变了,所有人的服务器列表都得重新改一遍。绑个域名会舒服很多。 基岩版客户端支持域名,加一条 A 记录指向服务器 IP 就行 —— 注意这里不需要 Java 版那种 SRV 记录,基岩版只认 A 记录。域名怎么解析到 VPS里有具体步骤。
还有一点容易忽略:服务器上不需要开 HTTP 服务,也不用配 HTTPS。 基岩版走的是自己的 UDP 协议,跟网页那套无关。看到教程让你配 Nginx 反代的,那是给 Java 版配网页地图(Dynmap)用的,跟基岩服本身没关系。
存档在 ./data/worlds/ 下面。服务器运行中直接复制这个目录,有可能拿到写了一半的存档,恢复的时候世界会损坏。
安全做法是停服再打包:
cd ~/minecraft
docker compose stop bedrock
tar czf ~/mc-backup-$(date +%F).tar.gz data/worlds data/server.properties data/allowlist.json data/permissions.json
docker compose start bedrock
挂个定时任务每周跑一次,比什么都强。存档丢了重建的痛苦,玩过的人都知道。
如果不想停服,退而求其次的做法是先用 save hold 命令让服务器把存档落盘(基岩版有 save hold / save query / save resume 这套命令),在 hold 的窗口期内复制文件,然后 save resume。但这套命令依赖游戏内 op 权限执行,不如停服来得简单可靠。
世界文件也会一直涨大。一个玩了大半年的生存服,几十 MB 到几百 MB 都很正常,探索过的区块都会留在存档里。备份文件别只放在同一台机器上 —— 服务器一挂,存档和备份一起没,那才是真的白玩。
服务器端放两个目录:
./data/resource_packs/—— 资源包(材质、音效、UI)./data/behavior_packs/—— 行为包(实体逻辑、新物品)
放进去之后,还要在对应世界的 world_resource_packs.json / world_behavior_packs.json 里写 UUID 才能生效。这里有个细节:行为包和资源包的 UUID 必须不一样,随便拿个 UUID 生成器造就行。
服务器端的包会强制下发给进服的玩家。玩家不用自己装,但也意味着包不能太大 —— 每次进服都要下载,几十 MB 的包会让加入过程变得很难受。
基岩版游戏更新很频繁,而且客户端是强制更新的。你这边服务器不跟着升,玩家更新完游戏就进不来了,报的是"版本不匹配"。
用 VERSION: LATEST 的话,重启容器就会拉到最新版,日常维护基本不用管。但有个前提要说清楚:大版本更新(比如 1.21 → 1.22)有可能改动世界格式,升级前先备份存档。纯原版世界向前兼容通常没问题,装了行为包的世界在跨大版本时经常出幺蛾子。
想稳一点就把 VERSION 锁成具体版本号,等社区确认没问题了再改。代价是每次游戏更新后得手动跟一次。
升级镜像本身和服务端版本是两回事,但操作是同一套:
cd ~/minecraft
docker compose pull
docker compose up -d
pull 拉新镜像,up -d 用新镜像重建容器。数据挂在 ./data 上,容器重建不影响存档 —— 这也是为什么一定要把 data 目录挂出来,而不是让它待在容器内部。
客户端显示"无法连接":先确认端口是 UDP。再检查机器防火墙(sudo ufw allow 19132/udp)和云服务商的安全组,两边都要放行。站内这篇 UFW 防火墙配置有详细步骤。
"版本不匹配":基岩版每次游戏更新后,服务器也要跟着升。用 VERSION: LATEST 的话重启容器就会拉到最新版;如果想锁死某个版本(比如客户端还没更新),把它改成具体的版本号。
容器起来又立刻退出:看 docker compose logs。最常见是 EULA 没设成 TRUE,或者 data 目录权限不对。
服务器越来越卡:进服先看有多少实体和掉落物。基岩版的实体运算跑在主线程上,一片自动农场或者几百只动物就够呛。另外把 view-distance 降下来。
世界文件莫名其妙的损坏:大概率是没停服就复制存档,或者磁盘满了(尤其是世界文件所在分区)。加个磁盘监控。
手机端连不上但电脑能连:手机上如果用流量,走的是运营商网络,可能被分配了 IPv6 地址 —— 这种情况下要么服务器开 IPv6(19133 端口),要么确认运营商的 IPv4 出口正常。
基岩服的配置不复杂,Docker 那几十行加上几个参数就完事了。真正需要想清楚的是两个决策:
一是到底开 Java 服还是基岩服。朋友里有 PC 玩家,就该走 Java + Geyser 的路线,别为了一时方便丢了插件生态。
二是机器买多大。原版小服 2GB 起步足够,把钱花在单核主频和 SSD 上,比堆内存划算。
延伸阅读:
