在WSL2上用Docker部署MC服务器并映射到公网IP
最近和同学想玩 mc 了,我有一个有公网 ip 的阿里云的服务器,但是这个 2c2g 的服务器太垃了,一部署上 mc 服务端就直接卡死了,所以干脆在自己电脑的 wsl 上部署了一个 linux 端的 MC 服务器,然后用 ssh 隧道把 mc 服务映射到了阿里云服务器的公网 ip 上。现在想想还不如直接在 windows 上部署一个 mc 服务端呢,不过用 wsl 的话资源占用应该要比 windows 要少一点。下面开始教程。
要求:
- ① 一个公网 ip 的服务器
- ② 一台装了 wsl2 和 docker desktop 的电脑,无公网 IP
第一次安装的话先安装 wsl2 再安装 docker desktop,因为 windows 端的 docker desktop 是基于 wsl 运行的,并且运行的话需要先在 windows 上的 docker desktop 中登录才能在 wsl 中运行,不过这个应该是比较基础的。另外不同的 windows 版本支持的 wsl2 版本不一样,可能有不同的特性,博主这里使用的是 win11 23h2。
首先在 wsl 中用 docker compose 部署 mc 服务端,在 wsl 中找一个存放数据的文件夹,建立一个 docker-compose.yaml 文件并键入以下内容:
services:
mc:
image: itzg/minecraft-server
tty: true
stdin_open: true
ports:
- "25565:25565"
environment:
TYPE: PAPER
Version: 1.21.8
EULA: "TRUE"
MEMORY: 3G
volumes:
# attach the relative directory 'data' to the container's /data path
- ./data:/data
说明一下,本教程基于 https://github.com/itzg/docker-minecraft-server 项目进行部署,链接中有项目的具体实施文档,以上的代码采用的是 papermc 的服务端,版本是 1.21.8,并给与服务端 3G 的最大运存。
在存放 docker-compose.yaml 目录下的终端键入以下代码,开始进行部署,这段代码会自动拉取相关的镜像,注意如果网络报错的话可以在 windows 宿主机上开启梯子。
docker compose up -d
# 不是 root 用户的话可能需要 sudo docker compose up -d
进度条跑完后终端输入 ls 和 docker ps -a 分别可以看到该目录下生成了一个 data 文件夹,以及容器的运行状态。

以上 wsl 对外暴露的端口是 25565。所以对本端口开放防火墙,代码如下:
sudo ufw allow 25565/tcp
以上 MC 服务端搭建完成,可分别使用以下命令管理本容器:
docker restart <容器id>
docker stop <容器id>
docker start <容器id>
docker compose down # 移除容器
因为目前运行的服务绑定的是 wsl 的私网 ip,有两种方式将本地服务映射到公网。
第一种 ssh 隧道
通过 ssh 反向隧道将本地服务映射到公网服务器。不过首先需要了解,因为 wsl 默认使用的是 nat 网络,windows 宿主机无法直接访问 wsl2 服务,包括外部网络更无法连接,所以要在 windows 上设置端口转发。建立一个 execute.bat 文件把以下代码放进去之后再右键管理员方式启动就行。
博主使用的 wsl 版本为 win11 23h2 版本的 wsl2,该版本的 wsl ip 地址不会每次重启都发生变更所以 bat 文件只用运行一次就行。如果每次重启 wsl 用 ifconfig 看 ip 都会变更的话,则每次重启后都要运行一遍以上 bat 文件。
# 获取 WSL2 的 IP
$wsl_ip = (wsl hostname -I).Trim()
# 将 Windows 的 25565 转发到 WSL2
netsh interface portproxy add v4tov4 listenport=25565 listenaddress=0.0.0.0 connectport=25565 connectaddress=$wsl_ip
# 放行防火墙
New-NetFirewallRule -DisplayName "Minecraft" -Direction Inbound -Protocol TCP -LocalPort 25565 -Action Allow
然后设置 ssh 反向隧道映射到公网服务器,首先在公网 ip 的服务器和 wsl 都要安装好 ssh 服务,具体可以在网上搜一下。这里说一下重点,安装好后在公网 IP 服务器的 /etc/ssh/sshd_config 中添加:
GatewayPorts yes
AllowTcpForwarding yes
然后重启 ssh 服务:
systemctl restart sshd
在 wsl 上建立反向隧道,终端输入以下代码,这里公网设置的监听端口是 25566。【注意每次容器重启后都需要重新建立一次隧道,也可以设置成自动运行】
ssh -fNTR *:25566:localhost:25565 <用户名>@<公网ip>
# 例 ssh -fNTR *:25566:localhost:25565 [email protected]
然后在公网 IP 服务器上对 25566 端口放行防火墙:
sudo ufw allow 25566/tcp
最后在阿里云服务器官网开放服务器安全组 25566 端口。

以上步骤完成可以就可以在 mc 中输入公网 ip + 端口号进入服务器中了,比如 34.34.34.34:25566。
第二种 frp 内网穿透
内网穿透比 ssh 隧道更加稳定,并且不需要 windows 进行端口转发。 首先分别在 wsl 和公网服务器中下载并解压 frp 的开源版本:
wget https://github.com/fatedier/frp/releases/download/v0.52.3/frp_0.52.3_linux_amd64.tar.gz
tar -zxvf frp_0.52.3_linux_amd64.tar.gz
cd frp_0.52.3_linux_amd64
公网服务器作为 frp 服务端,修改 frps.toml 文件中的以下内容:
[common]
bind_port = 7000 # FRP 服务端端口
token = "123456" # 认证密钥(客户端需一致)
wsl 端作为 frp 服务器的客户端,修改 frpc.toml 文件中的以下内容:
[common]
server_addr = xx.xx.xx.xx # 公网服务器 IP
server_port = 7000 # 与服务端一致
token = "123456" # 与服务端一致
[minecraft] # 映射 MC 服务器
type = tcp
local_ip = xx.xx.xx.xx # WSL2 本地 IP
local_port = 25565 # MC 服务器端口
remote_port = 25566 # 公网访问端口(可自定义)
启动 frp 服务,在服务端和客户端的 frp 文件夹下各自输入以下内容:
nohup ./frps -c ./frps.toml > frps.log 2>&1 & # 服务端
nohup ./frpc -c ./frpc.toml > frpc.log 2>&1 & # 客户端
启动后就可以啦,嫌麻烦的话也可以用 systemctl 设置开机自启动。
以下代码为测试代码:
netstat -tuln | grep 25566
# 查看端口属性
telnet 127.0.0.1 25566
# 在公网服务器上本地测试访问 25566 端口
telnet <公网ip> 25566
# 在 wsl 上测试 25566 端口
