5步搭建DNF私服完整指南:Docker容器化部署地下城与勇士服务器实战
5步搭建DNF私服完整指南:Docker容器化部署地下城与勇士服务器实战
【免费下载链接】dnf项目地址: https://gitcode.com/gh_mirrors/dnf/dnf
如果你一直想拥有一台属于自己的《地下城与勇士》私服,但又苦于传统端游服务端繁琐的编译、依赖、进程配置,那么gh_mirrors/dnf/dnf这个开源项目就是为你准备的答案。它把整套 DNF 服务端打包进 Docker 镜像,通过环境变量和初始化脚本即可快速拉起完整的游戏服务器,让 DNF 私服搭建从"折腾一整天"变成"一条命令跑通",特别适合学习游戏服务器架构、研究经典端游逻辑的开发者。
一、为什么选择容器化方案:先想清楚三个问题
在动手之前,先回答三个新手最常问的问题,帮你判断这条路线是否适合你:
- 环境兼容性:DNF 服务端原本依赖 CentOS 5/6/7 这类老系统,直接装很容易被依赖库折腾到崩溃。容器化之后,官方以 CentOS 为基础镜像构建,理论上可以在任何未修改过的 Linux 上运行(ARM 架构除外),彻底绕开系统环境地狱。
- 可移植性:镜像、数据、日志全部通过挂载目录管理,换机器只需要把
/data、/var/lib/mysql等目录带走,配合docker-compose文件即可秒级恢复。 - 资源可控:通过
--memory、--cpus、--shm-size等参数可以精确限制服务端资源占用,测试机 1G 内存也能跑,生产环境按需放大。
一句话总结:容器化把"部署 DNF 私服"从一项运维杂活,变成了一次可重复、可回滚、可版本化的标准操作。
二、先看懂台服架构:服务端到底由哪些"零件"组成
动手部署前,花三分钟看懂架构图会让你后续排错事半功倍。DNF 台服服务端并非单个进程,而是一组通过 TCP/UDP 端口协作的分布式组件:
核心组件与职责速览:
- Game Server(
df_game_r):游戏逻辑核心,处理登录登出、地下城副本逻辑、现金购买、创角与等级处理,每个频道独占一组 TCP/UDP 端口。 - Channel(
df_channel_r,端口 7001):从分流中继服务器确认分流情报,并把分流信息下发给客户端,是玩家进入频道的"门卫"。 - Bridge(
df_bridge_r,端口 7000):收集各频道分流信息(开/关、在线人数)、外挂玩家物品概率、死亡之塔排名等,形成分流档案。 - Relay Server(大区 3 对应 7300):客户端之间无法 P2P 直连时的中继转发,必须暴露外网。
- Stun Server(2311-2313/udp):P2P 组队的关键服务,通过 UDP Hole Punching 实现 NAT 穿透。
- Community(31100):决斗场相关服务,记录决斗场登录注销历史。
- Monitor / Manager:监控与消息广播,负责服务器认证、踢人下线、活动(burning time)套用等。
- DBMW(guild/mnt/stat,20203-20403):三种数据库中间件,把游戏组件与 MySQL 解耦。
- Guild(30403)、Auction(30803)、Point(30603):分别处理公会、拍卖行、点券交易。
更详细的端口与连接关系可以参考项目内的 doc/ArchitectureDiagram.md。看完你会发现:所谓"部署 DNF 私服",本质就是把这些进程全部正确拉起,并让它们彼此连通。而容器镜像已经帮你把这件事自动化了。
三、第一步:准备 Linux 环境与基础目录
前置条件:一台 Linux 服务器(云服务器或虚拟机均可),已安装 Docker,建议内存不低于 2G,磁盘预留 20G 以上。
项目在 doc/PrepareLinux.md 中提供了完整的服务器初始化指南,包括配置 swap 交换空间(若内存不足 8G)、安装依赖等,建议先按文档走一遍。核心步骤是创建三个挂载目录,分别存放游戏数据、数据库和日志:
mkdir -p /data/log /data/mysql /data/data✅ 说明:2.1.0 及之后版本在首次启动时会自动初始化 MySQL 数据,无需手动导入数据库文件。
四、第二步:一条 docker run 命令拉起服务端
这是整篇文章最核心的一步。镜像选择1995chen/dnf:centos5-2.1.9.fix1(当前稳定版),启动命令如下:
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逐项解读这些关键参数:
| 参数/变量 | 含义 | 建议 |
|---|---|---|
PUBLIC_IP | 对外 IP,公网部署填公网 IP,局域网填内网 IP | 必须正确,客户端要能访问到它 |
GM_ACCOUNT/GM_PASSWORD | 网关管理员账号密码 | 建议修改,不能含特殊字符 |
DNF_DB_ROOT_PASSWORD | MySQL root 密码,启动时自动修改 | 外网访问数据库用它 |
WEB_USER/WEB_PASS | Supervisor 管理页账号密码 | 默认 root/123456,建议修改 |
CLIENT_POOL_SIZE | 客户端缓冲池大小(3-1000) | 单机测试可设 3,人多按需加大 |
--shm-size=8g | 共享内存大小 | 不可删除,Docker 默认 64M 太小会导致启动失败 |
--memory=1g --cpus=1 | 资源限制 | 部分阉割系统不支持,报错时可去掉 |
端口映射速查(为什么是这些端口):
2000:180Supervisor 进程监控页面3000:3306MySQL(对外暴露为 3000,不是 3306)7600统一登录器端口881统一网关端口7001Channel 频道服务(TCP+UDP)7300Relay 中继服务(TCP+UDP,希洛克大区)30011/31011频道 11 的 TCP/UDP 端口30052/31052频道 52 的 TCP/UDP 端口2311-2313/udpStun 穿透服务
如果你不想手敲这么长的命令,也可以直接用项目自带的 compose 文件:deploy/dnf/docker-compose/basic/docker-compose.yaml就是最精简的配置模板,把PUBLIC_IP改成你的地址,docker-compose up -d即可。群晖 NAS 用户尤其推荐这种方式。
五、第三步:三招确认服务端真的跑起来了
镜像启动后不能急着连客户端,先做三项检查:
① 看"五国"初始化日志:进入/data/log/siroco11目录,执行:
tail -f Log$(date +%Y%m%d).init当看到GeoIP Allow Country Code : CN/HK/KR/MO/TW(CN)以及Connect To Guild Server、Connect To Monitor Server等输出时,说明初始化成功。四国/五国初始化大约需要 1 分钟左右,请耐心等待。
② 看游戏进程:
ps -ef | grep df_game如果看到./df_game_r siroco11 start、./df_game_r siroco52 start这样的进程,说明频道服务已拉起。
③ 看 Supervisor 管理页:浏览器访问http://PUBLIC_IP:2000,用WEB_USER/WEB_PASS登录,可以实时查看每个进程状态、在线 Tail 日志、手动重启,相当于给服务端装了一个可视化控制台。
⚠️ 进程被系统杀掉很常见:该服务内存占用较大,极可能被 OOM 干掉。恢复命令很简单:
docker restart dnf。
六、第四步:客户端配置——网关、补丁与登录器
服务端就绪后,剩下的是客户端侧的三件套:客户端本体、DOF 补丁、统一网关。项目在other/登录器/目录下提供了配套资源,流程如下:
- 安装 DOF 补丁:解压"DOF补丁大合集V7.6"后,编辑其中的
DNF.toml,把服务器地址改为你填写的PUBLIC_IP,保存后把DNF.toml、DNF.exe、说明文件一起复制到游戏客户端根目录。 - 配置统一网关:打开"统一网关在线管理工具 v6.4",在网关设置页填写——网关地址(PUBLIC_IP)、网关端口
881、登录账号gmuser、登录密码gmpass、通信密钥763WXRBW3PFTC3IXPFWH、登录器端口7600,点击"参数设置内容立刻生效"。 - 生成登录器:切到"登录器设置"页,服务器名称随意,登录器版本填
20180307,游戏地址填 PUBLIC_IP,通信密钥同上,点击"增加"后再点"生成登录器"。 - 启动游戏:把生成的登录器与
Config.ini复制到客户端根目录,运行即可,首次登录记得先注册账号。
默认网关信息汇总(部署时若未修改则如下):
网关端口: 881 通讯密钥: 763WXRBW3PFTC3IXPFWH 登录器版本: 20180307 登录器端口: 7600 GM账户: gmuser GM密码: gmpass💡 经验之谈:Windows7 下请用管理员权限运行网关,Windows10 则相反不要用管理员权限;统一登录器 5.x 版本需要在客户端 hosts 中添加
start.dnf.tw,否则进不了频道。
七、第五步:按需定制——多频道、站库分离与多大区
基础版默认只开 11、52 两个频道。当你需要承载更多玩家或做更复杂的拓扑时,项目提供了由浅入深的部署矩阵:
多频道扩容:通过OPEN_CHANNEL环境变量指定频道列表(如'1,6,7'),并在ports中为每个频道补充对应的 TCP/UDP 端口。参考deploy/dnf/docker-compose/multi_channel/docker-compose.yaml。频道端口遵循固定规律:大区 N 的频道 ch,TCP 端口为N00ch,UDP 端口为N10ch(例如希洛克频道 6 对应 30006/31006)。
站库分离:数据库单独跑一个容器,游戏容器通过MYSQL_HOST、MYSQL_PORT、DNF_DB_ROOT_PASSWORD指向远程库。配置模板在deploy/dnf/docker-compose/standalone_mysql/docker-compose.yaml,适合把 MySQL 独立出来统一管理的场景。
多大区部署:项目内置 6 个大区代号——1 卡恩(cain)、2 狄瑞吉(diregie)、3 希洛克(siroco)、4 普雷(prey)、5 卡西利亚斯(casillas)、6 赫尔德(hilder)。通过SERVER_GROUP指定大区编号(默认 3),通过SERVER_GROUP_DB=cain让 GM 工具兼容卡恩数据库。既可以用deploy/dnf/docker-compose/multi_server_group/下的cain.yaml、diregie.yaml、siroco.yaml在多台服务器分别跑各大区,也可以用combine_server_group.yaml在单台机器上同时开三个大区。
Kubernetes 生产级部署:deploy/dnf/k8s-deploy/目录提供了从 namespace、MySQL StatefulSet、存储卷到 Service 的完整 YAML 清单,其中05-dnf-server-new.yaml定义了 Deployment,通过 emptyDir(medium: Memory,8Gi)解决共享内存问题。K8s 路线适合需要滚动更新、持久化存储和服务发现的生产环境,配套说明见 doc/Kubernetes.md 与目录内的"开始一定要看"文档。
⚠️ 升级提醒:2.1.7 版本引入多大区功能后调整了端口——10011→30011、11011→31011、10052→30052、11052→31052、7200→7300。旧版本升级需新增
SERVER_GROUP_DB=cain,并删除 data 目录下的旧运行数据(PVF、登记补丁、密钥等除外)。
八、性能调优与资源控制要点
内存是 DNF 私服的生命线。以下几个参数直接影响稳定性:
CLIENT_POOL_SIZE:客户端缓冲池大小,直接影响df_bridge_r和df_channel_r两个进程的内存占用。默认 10,单机测试可调到 3,上限 1000。旧版本升级后若发现这两个进程仍占 1.3G,删除挂载目录中的/data/run/start_bridge.sh和/data/run/start_channel.sh再重启即可生效(只需删一次)。--shm-size:内存不足 2G 时可尝试降到 2g 或 1g,但不要低于极限。- 服务器一直卡在
Init DataManager日志循环,几乎都是 swap 不足——建议把 swap 设到 10G 以上,并同步调整--shm-size=10g。
没有固定公网 IP 怎么办?项目提供了三级备选方案:AUTO_PUBLIC_IP=true自动获取公网 IP(云服务器可用,重启需自己写检测脚本);或开启 DDNS(DDNS_ENABLE=true+DDNS_DOMAIN);还可以接入 Netbird/Tailscale 虚拟内网(所有客户端需加入同一虚拟网络)。等级补丁方面,other/等级补丁/目录内置了 50 到 99 共 11 档补丁(每个目录含DNFHelper.dll与df_game_r),更换时务必保证 PVF 未加密且与服务端版本配套。
九、常见问题速查表
把社区里被问得最多的坑整理成一张速查表,遇到问题先对号入座:
| 症状 | 优先排查方向 |
|---|---|
| 服务端不出五国 | 内存/swap 是否足够、磁盘空间、PVF 是否加密、--shm-size是否过小 |
| 灰频道或点不进去 | Linux 防火墙、云厂商安全组端口、客户端 hosts、PUBLIC_IP 是否可达、公钥私钥是否匹配 |
| 登录器卡在连接网关 | 五国是否跑出、881 端口是否放通、通信密钥格式是否正确 |
| 无法连接数据库 | 外网请用 3000 端口(非 3306),game 用户默认禁止外网,请用 root 账号 |
| 被 GeoIP 拦截断线 | 从频道日志找到拦截 IP,执行insert into d_taiwan.geo_allow values ('IP', "*", "2016-04-09 23:53:04");添加白名单 |
| 新建角色键盘无法输入 | 客户端问题,Win10 用系统自带英文输入法,或换 Dof7.6 补丁 |
| 生成网关提示非法字符 | 默认账号gmuser/gmpass含下划线,与 6.x 网关不兼容,改用 5.x 网关或换账号密码 |
插件方面,项目在plugin/目录提供了dnf-console(Web 控制台)、by-gate(自定义网关)以及 70s2_dp、70s2_dp_enhance、dp2 等数据包处理插件,需镜像版本 ≥ 2.1.4.fix1,按各目录内 README 操作即可。注意服务端默认已内置 DP,无需额外挂载。
十、写在最后:从搭建到真正玩起来
到这里,你已经走完了从环境准备、镜像启动、五国验证、客户端接入到多频道/多大区扩展的完整链路。回顾整个流程,最关键的三个决策点分别是:PUBLIC_IP 填对(客户端能否连上)、端口全部放通(防火墙 + 云安全组)、shm-size 给足(服务端能否稳定启动)。把这三件事做对,你的 DNF 私服就已经成功了一大半。
接下来可以按这个路线继续进阶:先单机跑通基础版 → 用 compose 固化配置 → 尝试多频道和站库分离 → 最后挑战多大区或 K8s 部署。项目后续还计划支持假人系统与更多登录器插件,值得持续关注。需要说明的是,该项目虽支持外网部署,但请仅用于学习与研究目的,切勿用于商业开服。祝你在 DNF 服务端的世界里玩得开心,八百勇士,冲!
【免费下载链接】dnf项目地址: https://gitcode.com/gh_mirrors/dnf/dnf
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
