文章目录
打包Linux服务器以及windows客户端
点我进链接
下载双击,然后next
选一个盘然后安装
安装完后就可以关闭了,然后重启电脑
打包Linux服务器
打包window客户端
通过 WSL 安装 Docker 和 Docker Compose
打开powershell
,输入
wsl -l -o
安装下面红色圈住的
输入下面安装,安装后重启一下电脑
wsl --install -d Ubuntu
也可以输入下面这个看看你是否安装过
wsl --list --verbose
首次安装的话需要输入下列,然后输入用户名密码等
ubuntu
不是首次的话就找不到了,直接启动好了
输入一个wsl
就能进去了
输入下列可以美化终端
使用 Shell 命令:
curl -sS https://starship.rs/install.sh | sh
然后输入y,再输入密码
这里也看到我密码忘记了输错了几次,这也是小问题,开一个新的终端。
只需要输入
wsl -u root
然后输入
passwd huanyu(输入用户名,我的叫huanyu所有输入这个)
然后就重复输入两次新的密码就好了
安装后输入
vi .bashrc
到最下面按两下z
,按下Insert
,把下面这个复制下去
eval "$(starship init bash)"
按esc
返回正常模式然后输入:x
然后回车保存,注意
:必须切到 英文输入法
,然后按 Shift +
; 才能输入冒号 :
。
然后运行下面的命令:
source .bashrc
它的作用是 重新加载 Bash 配置文件
由于主播成为了失败的man,然后狠狠的拷打了AI
下面是我从AI中获得的成功的一种方法:请看下面
拷打AI获取的安装美化的方法
你在 WSL Ubuntu 里执行 curl 下载 Starship GNU 版本时,出现:
curl: (35) Recv failure: Connection reset by peer
这是因为 WSL 里的网络无法直接访问 GitHub,常见原因:
- WSL 使用 NAT 模式,localhost 代理没有正确配置
- 企业或家庭网络阻止了 HTTPS 连接
- GitHub 连接被重置或速度极慢
最稳妥的解决方案:先在 Windows 下载,再在 WSL 使用
在 Windows 浏览器下载 Starship GNU 版本:
保存到:
C:\Users\幻雨\Downloads
- 在 WSL 里确认文件存在:
ls "/mnt/c/Users/幻雨/Downloads"
你应该看到:
starship-x86_64-unknown-linux-gnu.tar.gz
- 解压并安装:
下面这一坨直接复制进去回车就行了,反正我是这么干的
mkdir -p ~/.local/bin
tar -xzf "/mnt/c/Users/幻雨/Downloads/starship-x86_64-unknown-linux-gnu.tar.gz" -C ~/.local/bin
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(starship init bash)"' >> ~/.bashrc
source ~/.bashrc
starship --version
- 如果显示版本号,说明 Starship 已经在 WSL 生效
- 打开新的 WSL 终端,你会看到 Starship 提示符。
然后输入下面的更新软件包
sudo apt update
安装Docker
sudo apt install docker.io
验证安装
查看版本
docker --version
非 root 用户使用 Docker
默认需要 sudo
才能执行 Docker,用普通用户运行:
sudo usermod -aG docker $USER
然后退出并重新登录 WSL 或终端,普通用户就能直接运行 docker
命令。
输入下列可以看docker当前的进程
docker ps
可以查看 Docker 服务的详细状态信息
sudo systemctl status docker
输入下列添加环境变量
echo 'export DOCKER_CONFIG="$HOME/.docker"' >> ~/.bashrc
source ~/.bashrc
输入下列就可以看见用户下的声明的.docker
echo $DOCKER_CONFIG
安装Docker Compose
创建一个文件夹
mkdir cli-plugins
github中找到Linux-x86_64,右键复制链接
然后输入,这个是复制的链接https://github.com/docker/compose/releases/download/v2.39.2/docker-compose-linux-x86_64,你点一下进去就会下载东西了
curl -SL https://github.com/docker/compose/releases/download/v2.39.2/docker-compose-linux-x86_64 -o docker-compose
唉失败
在 WSL 里下载 Docker Compose CLI 插件时出现:
curl: (35) Recv failure: Connection reset by peer
原因
- WSL 检测到 localhost 代理,但是 NAT 模式下无法使用
- 导致 curl 无法从 GitHub 下载文件
- 并不是命令本身错,而是 网络连接被重置
解决方法
从 Windows 下载再复制到 WSL
- 在 Windows 浏览器打开:
https://github.com/docker/compose/releases/download/v2.39.2/docker-compose-linux-x86_64
- 下载到 Windows 目录,例如:
C:\Users\幻雨\Downloads\docker-compose
- 在 WSL 里复制到 Docker CLI 插件目录:
cp /mnt/c/Users/幻雨/Downloads/docker-compose/docker-compose-linux-x86_64 ~/.docker/cli-plugins/docker-compose
chmod +x docker-compose
- 验证安装:
docker compose version
输入就会出现一堆能用的命令
docker compose
到项目中创建一个文件夹
把两个python文件复制过来
添加一个Dockerfile
文件
# 使用官方提供的轻量级 Python 3.9 镜像作为基础镜像(因为3.9比较稳定)
FROM python:3.9-slim
# 更新 apt 包索引
RUN apt-get update
# 安装 curl 工具,用于后续下载脚本
RUN apt-get install -y curl
# 使用官方 Docker 安装脚本在容器里安装 Docker (dind 场景下可能用)
RUN curl -fsSL https://get.docker.com | sh
# 将当前目录下的所有文件复制到容器的根目录 /
COPY . /
# 设置容器的工作目录为 /coordinator
WORKDIR /coordinator
# 安装 Flask Web 框架 (用于运行 Python Web 服务)
RUN pip3 install flask
# 设置容器启动命令,运行 coordinator.py
ENTRYPOINT [ "python", "coordinator.py"]
🔹手动下载 Docker Buildx
- 打开 Windows 的浏览器,进入 buildx 发布页面:
👉 https://github.com/docker/buildx/releases - 找到最新版本(比如 v0.19.2),然后下载这个文件:
(注意:一定要下载 linux-amd64,因为 WSL 是 Linux 环境。)buildx-v0.19.2.linux-amd64
- 下载后,你会得到一个文件,比如:
C:\Users\幻雨\Downloads\buildx-v0.19.2.linux-amd64
🔹拷贝到 WSL
在 PowerShell/命令行里执行:
mkdir -p ~/.docker/cli-plugins
cp /mnt/c/Users/幻雨/Downloads/buildx-v0.19.2.linux-amd64 ~/.docker/cli-plugins/docker-buildx
chmod +x ~/.docker/cli-plugins/docker-buildx
🔹验证安装
执行:
docker buildx version
如果成功,会输出类似:
github.com/docker/buildx v0.19.2 ...
这样你就手动完成了 buildx 的安装 🎉。
重回上文输入
docker build -t coordinator .
产生多次失败呜呜呜
1.** 配置国内镜像源**
在 WSL 内执行:
sudo mkdir -p /etc/docker
cat <<EOF | sudo tee /etc/docker/daemon.json
{
"registry-mirrors": [
"https://docker.m.daocloud.io",
"https://hub-mirror.c.163.com",
"https://mirror.baidubce.com",
"https://ccr.ccs.tencentyun.com"
]
}
EOF
然后重启 Docker
sudo service docker restart
如果在此失败了
改代码吧
换成阿里的
# 使用官方提供的轻量级 Python 3.9 镜像作为基础镜像(因为3.9比较稳定)
FROM python:3.9-slim
# 更新 apt 包索引
RUN apt-get update
# 安装 curl 工具,用于后续下载脚本
RUN apt-get install -y curl
# 使用官方 Docker 安装脚本在容器里安装 Docker (dind 场景下可能用)
# RUN curl -fsSL https://get.docker.com | sh
RUN curl -fsSL https://get.docker.com | sh -s docker --mirror Aliyun
# 将当前目录下的所有文件复制到容器的根目录 /
COPY . /
# 设置容器的工作目录为 /coordinator
WORKDIR /coordinator
# 安装 Flask Web 框架 (用于运行 Python Web 服务)
RUN pip3 install flask
# 设置容器启动命令,运行 coordinator.py
ENTRYPOINT [ "python", "coordinator.py"]
这里没有看见python(应该没啥问题吧,感觉有点问题)
补充操作一个python3.9。https://docker.aityp.com/image/docker.io/python:3.9-slim
docker pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/python:3.9-slim
docker tag swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/python:3.9-slim docker.io/python:3.9-slim
就有了python
输入下列可以看见自己的ip
ip addr show eth0
复制一下ip
运行
docker run --rm -p 80:80 coordinator
然后到你打包的客户端游戏文件中打开
powershell
.\Crunch.exe -COORDINATOR_URL="你的IP" -TESTING_URL="你的IP:7777" -log
创建大厅后会接收到,UE在windows里这个docker没有这个游戏服务器,所有进不去房间
在游戏项目的ServerDeploy
文件下,创建如图文件,并把Linux服务器复制进去
到.gitignore
文件中添加下列
# 忽略服务器部署文件
ServerDeploy/server/server/*
添加新的文件
# 使用一个小巧的 Linux 镜像,不用 root 用户
FROM gcr.io/distroless/cc-debian10:nonroot
# 把本地 server 文件夹复制到镜像里
COPY --chown=nonroot:nonroot ./server /home/nonroot/server
# 容器启动时运行 CrunchServer 程序
ENTRYPOINT [ "/home/nonroot/server/Crunch/Binaries/Linux/CrunchServer", "Crunch"]
构建
docker build -t crunchserver .
显然我成为了失败的man
法一(建议直接法二,法一在后面会成为失败的man):
找了一个国内的镜像网站https://docker.aityp.com/image/gcr.io/distroless/cc-debian12:nonroot
把下面的复制去运行
docker pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/gcr.io/distroless/cc-debian12:nonroot
docker tag swr.cn-north-4.myhuaweicloud.com/ddn-k8s/gcr.io/distroless/cc-debian12:nonroot gcr.io/distroless/cc-debian12:nonroot
然后从10改成12(我没找到10 的)
# 使用一个小巧的 Linux 镜像,不用 root 用户
FROM gcr.io/distroless/cc-debian12:nonroot
# 把本地 server 文件夹复制到镜像里
COPY --chown=nonroot:nonroot ./server /home/nonroot/server
# 容器启动时运行 CrunchServer 程序
ENTRYPOINT [ "/home/nonroot/server/Crunch/Binaries/Linux/CrunchServer", "Crunch"]
再执行
docker build -t crunchserver .
看着应该是成功了
法2
直接改了这个吧
# 使用一个小巧的 Linux 镜像,不用 root 用户
# FROM gcr.io/distroless/cc-debian10:nonroot
# FROM gcr.io/distroless/cc-debian12:nonroot
FROM swr.cn-north-4.myhuaweicloud.com/ddn-k8s/gcr.io/distroless/cc-debian12:nonroot
# 把本地 server 文件夹复制到镜像里
COPY --chown=nonroot:nonroot ./server /home/nonroot/server
# 容器启动时运行 CrunchServer 程序
ENTRYPOINT [ "/home/nonroot/server/Crunch/Binaries/Linux/CrunchServer", "Crunch"]
移除的容器的方法(这里我们并不需要这么操作,我只是给我的学习存一个档)
运行启动测试
docker run --rm -p 7778:7778/udp -p 7778:7778/tcp crunchserver -server -log -epicapp="ServerClient" -SESSION_NAME="QWQ" -SESSION_SEARCH_ID="123456789" -PORT=7778
直接点击游戏运行
下面输入你的ip
可以直接加入房间
安装python虚拟环境
sudo apt install python3.12-venv
然后在ServerDeploy/coordinator/coordinator目录下输入下列
python3 -m venv .venv
输入下列可以看到.venv/
ll
输入下列激活
source .venv/bin/activate
安装flask框架
pip3 install flask
修改python文件
# 导入 Flask 框架中的 Flask 类、request(处理请求)、jsonify(返回 JSON 响应)
from flask import Flask, request, jsonify
import subprocess
from consts import SESSION_NAME_KEY, SESSION_SEARCH_ID_KEY, PORT_KEY
import re
# 创建 Flask 应用
app = Flask(__name__)
# 获取当前正在使用的Docker容器端口
def GetUsedPort():
# 运行docker命令,列出所有容器的端口信息
result = subprocess.run(['docker', 'ps', '--format', '"{{.Ports}}"'], capture_output=True, text=True)
output = result.stdout # 获取命令输出
usedPorts = set()
# 遍历输出中的每一行
for line in output.strip().split("\n"):
# 匹配 0.0.0.0:port-> 格式的端口映射(如 0.0.0.0:8080->80/tcp)
matches = re.findall(r'0\.0\.0\.0:(\d+)->', line)
# 将找到的端口号添加到集合中(自动去重)
usedPorts.update(map(int, matches))
return usedPorts # 返回已使用的端口集合
# 查找下一个可用的端口号
def FindNextAvailablePort(start = 7777 ,end = 8000):
usedPort = GetUsedPort() # 获取当前已使用的端口
# 在指定范围内查找可用端口
for port in range(start, end+1):
if port not in usedPort: # 如果端口未被占用
return port # 返回可用端口
return 0 # 无可用端口返回0
# 创建服务器的实现函数(使用Docker)
def CreateServerImpl(sessionName, sessionSearchId):
port = FindNextAvailablePort() # 查找可用端口
# 打印启动信息
print(f"启动服务器: {sessionName}, ID: {sessionSearchId}, 端口: {port}")
# 使用subprocess.Popen启动Docker容器
# 这会创建一个新的进程运行服务器,不会阻塞当前程序
subprocess.Popen([
"docker", # Docker命令
"run", # 运行容器
"--rm", # 容器退出后自动删除
"-p", f"{port}:{port}/tcp", # 映射TCP端口
"-p", f"{port}:{port}/udp", # 映射UDP端口
"crunchserver", # 使用的Docker镜像名称
"-server", # 服务器模式参数
"-log", # 启用日志参数
'-epicapp="ServerClient"', # 应用标识参数
f'-SESSION_NAME="{sessionName}"', # 会话名称参数
f'-SESSION_SEARCH_ID="{sessionSearchId}"', # 会话ID参数
f'-PORT={port}' # 端口参数
])
return port # 返回分配的端口号
# 定义路由,当客户端以 POST 请求访问 /Sessions 时触发该函数
@app.route('/Sessions', methods=['POST'])
def CreateServer():
# 打印请求头信息(调试用,可以看到客户端传过来的数据)
print(dict(request.headers))
# 获取请求体中的会话名称和搜索 ID
sessionName = request.get_json().get(SESSION_NAME_KEY)
sessionSearchId = request.get_json().get(SESSION_SEARCH_ID_KEY)
# 创建服务器并获取分配的端口号
# port = CreateServerLocalTest(sessionName, sessionSearchId) # 测试用
port = CreateServerImpl(sessionName, sessionSearchId) # Docker用
# 返回 JSON 响应,其中包含状态(success)和分配的端口号
# 状态码 200 表示请求成功
return jsonify({"status": "success", PORT_KEY: port}), 200
# 启动 Flask Web 服务
# host="0.0.0.0" 表示允许外部访问
# port=80 表示监听 80 端口(标准 HTTP 端口)
if __name__ == "__main__":
app.run(host="0.0.0.0", port=80)
# CreateServerImpl("", "")
清理协调器
重新生成
docker build -t coordinator .
运行
docker run --rm -p 80:80 -v /var/run/docker.sock:/var/run/docker.sock coordinator
D:\_My_Game\PUBLSH\GameBuild_02\Windows\Crunch.exe -COORDINATOR_URL="你的IP" -TESTING_URL="你的IP:7777" -log
命令行中输入下列获取IP
ip addr show eth0
唉我失败了不管了(最后还是解决了唉太难了孩子,直接到最后面,主要python脚本那里缺了东西)
清理docker images
docker rmi -f $(docker images -q)
创建一个docker-compose.yaml
文件
# 定义服务配置
services:
# 主服务容器
server:
# 使用当前目录下的Dockerfile构建镜像
build: ./server
# 镜像名称
image: server
# 协调服务容器
coordinator:
# 使用coordinator子目录的Dockerfile构建
build: ./coordinator
# 镜像名称
image: coordinator
# 自定义容器名称
container_name: servercoordinator
# 挂载Docker套接字实现容器管理
volumes:
- /var/run/docker.sock:/var/run/docker.sock
# 映射80端口供外部访问
ports:
- '80:80'
移除
最终版的Dockerfile
coordinator文件下的Dockerfile
# 使用官方提供的轻量级 Python 3.9 镜像作为基础镜像(因为3.9比较稳定)
# FROM python:3.9-slim
FROM swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/python:3.9-slim
# 更新 apt 包索引
RUN apt-get update
# 安装 curl 工具,用于后续下载脚本
RUN apt-get install -y curl
# 使用官方 Docker 安装脚本在容器里安装 Docker (dind 场景下可能用)
# RUN curl -fsSL https://get.docker.com | sh
RUN curl -fsSL https://get.docker.com | sh -s docker --mirror Aliyun
# 将当前目录下的所有文件复制到容器的根目录 /
COPY . /
# 设置容器的工作目录为 /coordinator
WORKDIR /coordinator
# 安装 Flask Web 框架 (用于运行 Python Web 服务)
RUN pip3 install flask
# 设置容器启动命令,运行 coordinator.py
ENTRYPOINT [ "python", "coordinator.py"]
server文件下的Dockerfile
# 使用一个小巧的 Linux 镜像,不用 root 用户
# FROM gcr.io/distroless/cc-debian10:nonroot
# FROM gcr.io/distroless/cc-debian12:nonroot
FROM swr.cn-north-4.myhuaweicloud.com/ddn-k8s/gcr.io/distroless/cc-debian12:nonroot
# 把本地 server 文件夹复制到镜像里
COPY --chown=nonroot:nonroot ./server /home/nonroot/server
# 容器启动时运行 CrunchServer 程序
ENTRYPOINT [ "/home/nonroot/server/Crunch/Binaries/Linux/CrunchServer", "Crunch"]
顺便修改coordinator.py
# 导入 Flask 框架中的 Flask 类、request(处理请求)、jsonify(返回 JSON 响应)
from flask import Flask, request, jsonify
import subprocess
from consts import SESSION_NAME_KEY, SESSION_SEARCH_ID_KEY, PORT_KEY
import re
# 创建 Flask 应用
app = Flask(__name__)
# 获取当前正在使用的Docker容器端口
def GetUsedPort():
# 运行docker命令,列出所有容器的端口信息
result = subprocess.run(['docker', 'ps', '--format', '"{{.Ports}}"'], capture_output=True, text=True)
output = result.stdout # 获取命令输出
usedPorts = set()
# 遍历输出中的每一行
for line in output.strip().split("\n"):
# 匹配 0.0.0.0:port-> 格式的端口映射(如 0.0.0.0:8080->80/tcp)
matches = re.findall(r'0\.0\.0\.0:(\d+)->', line)
# 将找到的端口号添加到集合中(自动去重)
usedPorts.update(map(int, matches))
return usedPorts # 返回已使用的端口集合
# 查找下一个可用的端口号
def FindNextAvailablePort(start = 7777 ,end = 8000):
usedPort = GetUsedPort() # 获取当前已使用的端口
# 在指定范围内查找可用端口
for port in range(start, end+1):
if port not in usedPort: # 如果端口未被占用
return port # 返回可用端口
return 0 # 无可用端口返回0
# 创建服务器的实现函数(使用Docker)
def CreateServerImpl(sessionName, sessionSearchId):
port = FindNextAvailablePort() # 查找可用端口
# 打印启动信息
print(f"启动服务器: {sessionName}, ID: {sessionSearchId}, 端口: {port}")
# 使用subprocess.Popen启动Docker容器
# 这会创建一个新的进程运行服务器,不会阻塞当前程序
subprocess.Popen([
"docker", # Docker命令
"run", # 运行容器
"--rm", # 容器退出后自动删除
"-p", f"{port}:{port}/tcp", # 映射TCP端口
"-p", f"{port}:{port}/udp", # 映射UDP端口
"server", # 使用的Docker镜像名称
"-server", # 服务器模式参数
"-log", # 启用日志参数
'-epicapp="ServerClient"', # 应用标识参数
f'-SESSION_NAME="{sessionName}"', # 会话名称参数
f'-SESSION_SEARCH_ID="{sessionSearchId}"', # 会话ID参数
f'-PORT={port}' # 端口参数
])
return port # 返回分配的端口号
# TODO: 将来使用 Docker 时移除该变量
# 当前用作测试的可用端口(后续可以根据需求动态分配)
nextAvailablePort = 7777
# 用于本地测试时创建服务器进程
# 参数:
# sessionName: 会话名称
# sessionSearchId: 会话搜索ID
def CreateServerLocalTest(sessionName, sessionSearchId):
# 使用全局变量 nextAvailablePort
global nextAvailablePort
# 启动一个新的进程
subprocess.Popen([
# UnrealEditor.exe 的路径(指定引擎可执行文件)
"D:/UnrealSource/UnrealEngine/Engine/Binaries/Win64/UnrealEditor.exe",
# 工程文件路径(告诉引擎要启动哪个项目)
"D:/ue_texiao/Crunch/Crunch.uproject" ,
# 以服务器模式运行(而不是客户端/编辑器模式)
"-server",
# 打开日志输出
"-log",
# 指定 Epic 应用 ID(可用于标识不同的运行实例)
'-epicapp="ServerClient"',
# 传递会话名称参数(作为命令行参数给引擎使用)
f'-SESSION_NAME="{sessionName}"',
# 传递会话搜索 ID 参数
f'-SESSION_SEARCH_ID="{sessionSearchId}"',
# 指定使用的端口号
f'-PORT={nextAvailablePort}'
])
# 记录当前使用的端口号
usedPort = nextAvailablePort
nextAvailablePort += 1
# 返回当前使用的端口号
return usedPort
# 定义路由,当客户端以 POST 请求访问 /Sessions 时触发该函数
@app.route('/Sessions', methods=['POST'])
def CreateServer():
# 打印请求头信息(调试用,可以看到客户端传过来的数据)
print(dict(request.headers))
# 获取请求体中的会话名称和搜索 ID
sessionName = request.get_json().get(SESSION_NAME_KEY)
sessionSearchId = request.get_json().get(SESSION_SEARCH_ID_KEY)
# 创建服务器并获取分配的端口号
# port = CreateServerLocalTest(sessionName, sessionSearchId) # 测试用
port = CreateServerImpl(sessionName, sessionSearchId) # Docker用
# 返回 JSON 响应,其中包含状态(success)和分配的端口号
# 状态码 200 表示请求成功
return jsonify({"status": "success", PORT_KEY: port}), 200
# 启动 Flask Web 服务
# host="0.0.0.0" 表示允许外部访问
# port=80 表示监听 80 端口(标准 HTTP 端口)
if __name__ == "__main__":
app.run(host="0.0.0.0", port=80)
# CreateServerImpl("", "")
执行
docker compose build
启动 coordinator 容器
docker compose up coordinator
以上是正常操作的全部
解决总是出现500返回的错误问题,错误的没有保留截图
直接从新加载一遍
# 停止服务
docker compose down
# 清理 Docker 缓存和镜像
docker system prune -f
# 强制完全重新构建(不使用任何缓存)
docker compose build --no-cache --force-rm coordinator
# 重新启动
docker compose up coordinator
废了我九牛二虎之力终于成功了
全部人退出游戏后
这波写的最为之乱emmm,被制裁了