当前位置: 首页 > news >正文

从零搭建DNF私服:基于Docker容器化的一键部署实战指南

从零搭建DNF私服:基于Docker容器化的一键部署实战指南

【免费下载链接】dnf项目地址: https://gitcode.com/gh_mirrors/dnf/dnf

如果你曾经尝试过搭建地下城与勇士(DNF)的私服,大概率体会过那种"装到一半就想放弃"的滋味:要先准备一台干净的Linux服务器,手动编译各种依赖,拷贝几十个配置文件,还得处理版本不对导致的诡异报错。gh_mirrors/dnf/dnf 项目把这些繁琐的步骤全部打包进了一个 Docker 镜像,通过环境变量和初始化脚本即可完成服务端的快速部署,让"今天clone、今天开服测试"成为可能。本文将以实战视角,带你走完从服务器初始化、容器启动、到客户端成功登录的完整链路。

一、先搞清楚:这个项目到底替你解决了什么

传统方式搭建 DNF 服务端,你需要自己解决三件麻烦事:

  1. 环境依赖:游戏服务端依赖特定版本的 CentOS 和系统库,一旦系统环境有差异,各种莫名其妙的崩溃随之而来。
  2. 服务编排:DNF 服务端并非单一进程,而是由游戏服、频道、中继、穿透等多个进程协同工作,手动启动和监控非常痛苦。
  3. 初始化数据:数据库建库、账号创建、PVF 资源部署,每一步都需要人工干预,错一步就得重来。

gh_mirrors/dnf/dnf 项目以官方 CentOS-5/6/7 为基础镜像,将上述所有内容固化到镜像内部,对外只暴露一组环境变量。你只需要回答几个问题——公网 IP 是多少、GM 账号密码用什么、开哪几个频道——剩下的交给初始化脚本。项目还内置了 Supervisor 进程管理器,所有服务进程的状态、日志、重启操作都能在一个 Web 页面上完成,这也是它适合新手入门的关键原因。

二、一张图看懂服务端架构:那些进程都是干什么的

在动手部署之前,建议先花两分钟理解服务端的组成,否则后面排查问题会像无头苍蝇。项目文档 doc/ArchitectureDiagram.md 中给出了完整的流程图:

整个服务端可以归纳为四个层次:

接入与转发层

  • Relay(中继):当客户端之间无法建立 P2P 直连时负责数据中转,需要暴露公网端口(希洛克大区为 7300)。
  • Stun(穿透):负责 NAT 穿透(UDP Hole Punching),是组队功能的关键服务,占用 2311-2313 端口。
  • Channel(频道):向客户端下发分流(频道)信息,端口 7001。

核心业务层

  • Game(游戏服):处理登录登出、地下城逻辑、角色创建、现金购买,即你在日志中看到的df_game_r进程。
  • Bridge:负责分流信息档案的收集与传送,同时统计在线人数等数据。
  • Community / Monitor / Guild / Auction等辅助服务:分别处理决斗场、跨服消息、公会、拍卖行等功能。

数据层

  • DBMW:数据库中间件,分为 guild、mnt、stat 三种,是游戏逻辑与 MySQL 之间的桥梁。

监控层

  • Supervisor:统一管理所有进程,访问http://IP:2000即可打开管理页面。

对于普通使用者,你不需要逐一理解每个进程的细节,但记住一句话就够了:凡是架构图上标注了端口号的组件,都需要在防火墙和云厂商安全组中放行。这也是绝大多数"灰频道""连不上网关"问题的根源。

三、部署第一步:初始化一台"合格"的Linux服务器

项目文档 doc/PrepareLinux.md 列出了三项必须完成的准备工作,建议按顺序执行:

1. 安装 Docker

yum update -y curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh systemctl enable docker systemctl restart docker

2. 关闭防火墙(重点)

游戏服务端使用大量 TCP/UDP 端口,如果防火墙未关闭,即便容器端口映射正确也无法访问:

systemctl disable firewalld systemctl stop firewalld

3. 配置 Swap 交换空间(内存不足 8GB 时必须做)

服务端启动时对内存的需求远超你的想象,尤其是Init DataManager阶段,内存不够会直接卡死。创建一个 8GB 的 swap 文件:

/usr/bin/fallocate --length 8GiB /var/swap.1 mkswap /var/swap.1 swapon /var/swap.1 sed -i '$a /var/swap.1 swap swap default 0 0' /etc/fstab

随后确认sysctl vm.swappiness输出不为 0;如果为 0,需要在/etc/sysctl.conf追加vm.swappiness = 100并执行sysctl -p生效。

拉取镜像:国内用户推荐从阿里云镜像源拉取,速度更快:

docker pull registry.cn-hangzhou.aliyuncs.com/1995chen/dnf:centos7-2.1.9.fix1 docker tag registry.cn-hangzhou.aliyuncs.com/1995chen/dnf:centos7-2.1.9.fix1 1995chen/dnf:centos7-2.1.9.fix1

四、最快跑起来:一条 docker run 命令完成部署

准备工作就绪后,先创建三个数据挂载目录,用于持久化日志、数据库和资源文件:

mkdir -p /data/log /data/mysql /data/data

然后执行以下命令启动服务(将x.x.x.x替换为你的公网 IP,局域网测试则填写局域网 IP):

docker run -d \ -e PUBLIC_IP=x.x.x.x \ -e WEB_USER=root -e WEB_PASS=123456 \ -e DNF_DB_ROOT_PASSWORD=88888888 \ -e GM_ACCOUNT=gmuser -e GM_PASSWORD=gmpass \ -e CLIENT_POOL_SIZE=10 \ -v /data/log:/home/neople/game/log:Z \ -v /data/mysql:/var/lib/mysql:Z \ -v /data/data:/data:Z \ -p 2000:180 -p 3000:3306/tcp -p 7600:7600/tcp \ -p 881:881/tcp -p 7001:7001/tcp -p 7001:7001/udp \ -p 30011:30011/tcp -p 31011:31011/udp \ -p 30052:30052/tcp -p 31052:31052/udp \ -p 7300:7300/tcp -p 7300:7300/udp \ -p 2311-2313:2311-2313/udp \ --cap-add=NET_ADMIN --hostname=dnf \ --cpus=1 --memory=1g --memory-swap=-1 --shm-size=8g \ --name=dnf 1995chen/dnf:centos5-2.1.9.fix1

四个必须注意的参数

  • --shm-size=8g不可删除。Docker 默认共享内存只有 64M,过小会导致服务启动失败。
  • PUBLIC_IP:必须填写客户端能访问到的 IP,填错会直接表现为"灰频道"。
  • CLIENT_POOL_SIZE:客户端缓冲池大小,单人测试可设为 3,多人按需增加,上限 1000。
  • DNF_DB_ROOT_PASSWORD:容器启动时会自动把 MySQL root 密码修改为该值。

五、如何确认服务端真的启动成功了

这一步很多人会忽略,导致后续排查浪费时间。项目给出了三层验证方法:

第一层:看"五国"日志

进入日志目录,查看当天的初始化日志:

tail -f /data/log/siroco11/Log$(date +%Y%m%d).init

当看到类似下面的输出时,说明基础服务已经就绪(初始化大约需要 1 分钟,请耐心等待):

[09:40:23] GeoIP Allow Country Code : CN [09:40:23] GeoIP Allow Country Code : HK [09:40:32] [!] Connect To Guild Server ... [09:40:32] [!] Connect To Monitor Server ...

第二层:确认游戏进程存活

ps -ef | grep df_game

如果输出中存在./df_game_r siroco11 start这样的进程,代表游戏服正常运行。

第三层:访问 Supervisor 管理页面

浏览器打开http://IP:2000(默认账号 root / 123456),可以看到所有进程的运行状态,并支持在线查看日志、重启进程。后续服务被系统杀掉时,也可以在这里手动拉起。

六、客户端接入:网关、补丁与登录器三步走

服务端就绪后,客户端还需要做三件事。相关工具都收录在 other/登录器 目录中,客户端补丁则位于 other/等级补丁。

  1. 安装 DOF 补丁:解压DOF补丁大合集V7.6.7z,编辑其中的DNF.toml,将服务器地址改为你的PUBLIC_IP,然后把DNF.tomlDNF.exe等文件复制到游戏客户端根目录。
  2. 配置统一网关:打开统一网关在线管理工具v6.4.exe,在"网关设置"页填写:网关地址为PUBLIC_IP、网关端口 881、登录账号 gmuser、登录密码 gmpass、通信密钥763WXRBW3PFTC3IXPFWH、登录器端口 7600。保存后在"登录器设置"页生成登录器。
  3. 放置登录器:将生成的登录器及Config.ini复制到游戏根目录,双击运行即可。

项目默认的网关参数汇总如下,如果你修改了环境变量,请以实际配置为准:

配置项默认值说明
网关端口881统一网关 TCP 端口
登录器端口7600统一登录器端口
通信密钥763WXRBW3PFTC3IXPFWH网关与登录器之间的密钥
GM 账号 / 密码gmuser / gmpass不能包含特殊字符

七、进阶玩法:从单机到多频道、多大区的扩展路径

当你跑通单机后,自然会想扩大规模。项目在 deploy/dnf/docker-compose 目录下提供了四套现成的编排方案,覆盖了从入门到生产的各种场景:

  • basic:基础部署,一个容器跑完整服务,适合个人测试。
  • multi_channel:多频道部署,通过OPEN_CHANNEL变量指定开放哪些频道,每个频道需要映射对应的 TCP/UDP 端口。
  • standalone_mysql:站库分离,将 MySQL 独立成容器,适合后续迁移。
  • multi_server_group:多大区部署,支持在一台或多台服务器上同时运行卡恩(cain)、狄瑞吉(diregie)、希洛克(siroco)三个大区。

以 basic 方案为例,核心配置如下(deploy/dnf/docker-compose/basic/docker-compose.yaml):

version: "2.3" services: dnf-1: image: 1995chen/dnf:centos5-2.1.9.fix1 environment: - TZ=Asia/Shanghai - SERVER_GROUP=3 - DNF_DB_ROOT_PASSWORD=88888888 - GM_ACCOUNT=gmuser - GM_PASSWORD=gmpass - GM_CONNECT_KEY=763WXRBW3PFTC3IXPFWH - GM_LANDER_VERSION=20180307 - PUBLIC_IP=127.0.0.1 - OPEN_CHANNEL='11,52' shm_size: 8g mem_limit: 1g cpu_count: 1 restart: always ports: - 2000:180/tcp - 3000:3306/tcp - 7600:7600/tcp - 881:881/tcp - 7001:7001/tcp - 7001:7001/udp - 7300:7300/tcp - 7300:7300/udp - 30011:30011/tcp - 31011:31011/udp - 30052:30052/tcp - 31052:31052/udp - 2311-2313:2311-2313/udp volumes: - ./data:/data:Z - ./mysql:/var/lib/mysql:Z - ./log:/home/neople/game/log:Z

关于大区,有两个容易踩坑的知识点:

  • 大区编号映射:1=卡恩(cain)、2=狄瑞吉(diregie)、3=希洛克(siroco)。默认SERVER_GROUP=3
  • 数据库兼容:市面上的主流 PVF 和 GM 工具大多连接 cain 数据库,如果遇到 GM 工具无法使用,可额外设置环境变量SERVER_GROUP_DB=cain显式指定。

如果需要更大规模的部署(如 K8s),项目在 deploy/dnf/k8s-deploy 目录提供了完整的 StatefulSet、Service 与存储配置,建议先阅读00-1开始一定要看前期准备.md00-2开始一定要看注意事项.md两份文档。

八、性能与成本:一个人玩和一百个人玩,配置差多少

服务端的内存占用主要受两个因素影响:频道数量和CLIENT_POOL_SIZE。其中df_bridge_rdf_channel_r两个进程各占约 1.3GB 内存,这是固定开销;CLIENT_POOL_SIZE则决定缓冲池大小,直接关系并发能力。参考配置如下:

场景内存CLIENT_POOL_SIZE建议 shm-size
单人测试1G32G~8G
小型亲友服2G~4G10~308G
大规模开服8G+按需调大16G

两个高性价比的优化手段

  1. 调整 swap 优先级:文档建议将vm.swappiness设为 100(优先使用虚拟内存),对个位数玩家的场景,几乎无感知差异,却能大幅降低物理内存门槛。
  2. 升级后清理旧脚本:如果你从旧版本升级,CLIENT_POOL_SIZE不生效时,删除挂载目录下的/data/run/start_bridge.sh/data/run/start_channel.sh后重启即可(只需删一次)。

另外,如果你没有固定公网 IP,可以设置AUTO_PUBLIC_IP=true让容器启动时自动获取公网 IP;项目还支持 Netbird 和 Tailscale 虚拟组网,适合朋友间通过虚拟内网联机。

九、踩坑实录:五个高频问题的排查手册

结合项目 README 与社区反馈,这里整理五个最高频的问题,全部采用"现象→原因→解法"的格式,建议收藏备用。

问题 1:服务端一直卡在 Init DataManager 日志循环

  • 原因:物理内存或 swap 不足,进程无法完成数据加载。
  • 解法:将 swap 扩容到 10G 或更大,同时把--shm-size调整为 10g;若 swap 占用始终为 0,执行sysctl -p后重启服务器。

问题 2:出现"灰频道"或点击频道无法进入

  • 原因:端口不通或 IP 配置错误,客户端拿不到游戏服的真实地址。
  • 解法:依次检查 Linux 防火墙是否关闭、云厂商安全组端口是否放行、PUBLIC_IP是否填错、客户端 hosts 是否配置了start.dnf.tw(5.x 登录器需要)、公钥私钥文件是否匹配。

问题 3:点击网关登录没反应,不出游戏

  • 原因:多半是客户端环境问题,而非服务端问题。
  • 解法:Win7 用管理员权限运行网关、Win10 反之;不要通过虚拟机 Console/VNC 访问 Windows;用dxdiag确认 DirectX 功能全部开启;确认客户端补丁已正确覆盖。

问题 4:登录器提示"版本过期"

  • 原因:登录器版本与网关配置不一致。
  • 解法:在网关"登录器设置"页将登录器版本设为20180307(与GM_LANDER_VERSION一致),重新生成登录器。

问题 5:GEO 拦截导致连接频道时网络中断

  • 原因:服务端内置了 GeoIP 地区限制,你的 IP 不在允许列表。
  • 解法:从频道日志中找到Fail Account...IP:xxx的拦截记录,执行 SQL 添加白名单(以 IP 192.168.48.1 为例):
insert into d_taiwan.geo_allow values ('192.168.48.1', "*", "2016-04-09 23:53:04");

执行后重启服务端生效。更完整的排查清单可参考项目 README 的"常见问题"部分。

十、写在最后:能力越大,责任越大

至此,你已经走完了从服务器初始化、容器部署、日志验证到客户端接入的完整流程。这个项目最大的价值,是把一个原本需要数天甚至数周的专业运维工作,压缩成了几分钟的容器操作——这正是容器化技术的魅力所在。更进一步,你还可以通过 plugin 目录挂载 dnf-console(Web 控制台)、DP 数据包处理等插件,或参考 doc/OtherDeploy.md 探索 K8s 生产级部署。

最后必须提醒:该项目仅用于学习与研究目的。虽然服务端支持外网访问,但请勿用于商业开服运营,以免侵犯游戏公司的知识产权并触犯相关法律法规。在动手之前,建议先阅读项目的 LICENSE 文件,明确使用边界。祝你在技术探索的道路上玩得开心,也欢迎加入社区 QQ 群(933010289 / 971177373)与其他爱好者交流,共同完善这个项目。

【免费下载链接】dnf项目地址: https://gitcode.com/gh_mirrors/dnf/dnf

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

http://www.cnnetsun.cn/news/4138869.html

相关文章:

  • 视频生成模型太大跑不动?LTX-2.3 10Eros v1.2 MLX-q8 让 16GB 内存 Mac 也能本地出片
  • 轻松打破语言壁垒:RPCS3模拟器中文汉化完整指南
  • 9款AI写论文哪个好?2026实测:只有它敢给你真文献+真图表
  • 10分钟给平衡车换上FOC固件:从主板解锁到参数调优的完整保姆级指南
  • 4 步搭好 PotPlayer 字幕翻译插件,外挂字幕实时双语同屏
  • rust-ctrlc 完全教程:如何用 10 行代码处理 Ctrl-C 信号
  • AI 视频放大入门指南:用 Video2X 免费把老片修成 4K 高清
  • 5 分钟快速上手 ppo-Huggy-NPU:昇腾 910B 跑通 Huggy 策略推理的极简教程
  • 不用花 30 美元订阅:Wand-Enhancer 免费解锁游戏修改器专业版功能,手机还能远程遥控
  • 爱享素材下载器完整上手指南:免费跨平台抓取视频号、抖音、快手等网络资源
  • 毕业救命神器|PaperXie一站式学术工具,从选题到答辩全程躺平✅
  • mybatis-generator-gui-extension vs 原生 MyBatis Generator:图形化界面到底解决了哪些痛点?
  • test-ttm-v1-npu推理实战教程:从模型加载到预测结果验证的完整分步流程
  • ScreenCloud插件系统原理剖析:PluginManager加载与安装机制解密
  • 4 种场景,重新认识这款免费开源字体
  • Hap QuickTime 编解码器快速上手指南:免费开源方案,让 GPU 接管视频解码
  • 机器学习在母婴健康数据分析中的应用:从监督学习到随机森林实践
  • 微信聊天记录导出完整指南:用WeChatMsg把每一段对话永久留存
  • 拼多多推广效果怎么看?2026年分析ROI的5个工具方案推荐榜
  • 微信防撤回工具 RevokeMsgPatcher 亲测:3分钟装好,撤回的消息一个都跑不掉
  • TGRS 2025 即插即用 | 特征融合篇 | HMoE:新型异构专家融合模块,特征融合+MoE泛化,性能和效率均提升!
  • 5分钟上手rembg:图片背景去除如何零代码跨平台?
  • 微信聊天记录如何永久保存?试试WeChatMsg
  • MockGPS 安装与配置完整指南:零门槛跑通 GPS 模拟
  • 网页时光机完整上手指南:3 个日常场景,轻松找回消失的网页历史
  • 【单片机课程设计/毕业设计】基于 STM32 的 RTC 时钟多功能称重报警采集系统设计 基于 STM32 单片机的人机交互称重监测终端设计与实现(013704)
  • AI Agent核心技术解析与面试实战指南
  • 3步免费升级老Mac:用OpenCore Legacy Patcher跑通最新macOS
  • 计算机单片机毕设实战-基于 STM32 的多体征实时采集与声光预警装置设计 基于 STM32 的人体健康指标监测与阈值报警系统设计(013204)
  • 5 分钟快速上手 pretty_backtrace:美化 Ruby 异常堆栈的完整入门指南