资讯动态

Docker 部署 WOW 服务端:AzerothCore 与 TrinityCore 容器化实战

发布时间:2026/10/2 22:55:48 来源:尧图企业网站定制
1. 为什么用 Docker 跑 WOW 服务端是当前最省心的方案把 WOW 服务端塞进 Docker 这件事最早是私服圈子里几个运维老哥为了省事折腾出来的。传统装法是什么流程先装一台 Ubuntu 或者 Debian然后手动编译 AzerothCore 或者 TrinityCore中间 CMake 报错、Boost 版本对不上、MySQL 密码策略冲突、OpenSSL 版本不兼容随便一个环节就能卡你一整天。更别提换机器的时候整套环境要重新来一遍配置文件散落在/etc、/opt、/var/lib各个角落迁移一次掉半条命。Docker 方案的核心价值就三点环境隔离、一键复现、数据可迁移。服务端本体、数据库、认证服务全部跑在独立容器里宿主机只需要装好 Docker 引擎剩下的依赖问题全部由镜像解决。你在一台机器上跑通了把docker-compose.yml和挂载目录打包拷到另一台机器docker compose up -d就能起来配置文件、角色数据、账号信息原封不动。这套方案适合谁我总结下来是三类人一是想自己搭个服跟朋友玩的玩家不想花三天时间研究编译二是需要频繁重置环境做测试的开发者比如调插件、改掉落、测副本机制三是手上有多台机器比如家里一台 N100 小主机、公司一台旧笔记本想随时切换部署的折腾党。如果你只是想体验一下服务端长什么样Docker 方案能让你在半小时内看到登录界面而不是在编译错误里挣扎。需要提前说清楚的是本文讨论的是本地局域网或单机自娱自乐的部署场景重点放在 Docker 环境搭建、镜像选型、数据持久化和常见故障排查上。涉及服务端核心配置、数据库结构、网络端口映射这些实操细节我会结合自己踩过的坑逐一展开。2. 镜像选型AzerothCore 与 TrinityCore 的容器化差异2.1 两个主流服务端在 Docker 生态里的成熟度对比WOW 服务端开源实现里目前社区活跃度最高的是AzerothCore基于 MaNGOS 演进和TrinityCore暴雪模拟器老牌分支。这两个项目在 Docker 支持上的成熟度差距挺明显直接决定了你部署时的痛苦指数。AzerothCore 官方仓库里就带了docker-compose.yml维护者把数据库初始化脚本、认证服务、世界服务全部编排好了镜像发布在 Docker Hub 上拉下来就能用。TrinityCore 虽然也有社区维护的 Dockerfile但官方并不直接提供 compose 编排数据库初始化需要你自己导入 SQL 文件步骤多出不少。我个人的建议是新手直接上 AzerothCore它的 Docker 化程度最高文档也相对完整。TrinityCore 更适合对服务端结构已经熟悉、需要深度定制的老手。对比维度AzerothCoreTrinityCore官方 Docker 支持官方仓库自带 compose社区维护需自行编排镜像来源Docker Hub 官方发布多为自行构建数据库初始化容器启动自动执行手动导入 SQL配置复杂度低环境变量覆盖中高需改 conf 文件社区活跃度高更新频繁中版本迭代较慢适合人群新手、快速部署老手、深度定制2.2 镜像标签怎么选latest 还是固定版本拉镜像的时候你会看到latest、master、3.3.5这类标签。我的经验是永远不要用 latest。原因很简单服务端镜像更新频繁某次更新可能改了数据库结构你直接拉 latest 覆盖旧容器数据库版本对不上服务端起不来角色数据还可能损坏。正确做法是锁定一个具体版本标签比如azerothcore/azerothcore:master-2024-xx-xx这种带日期的构建。部署前先去 Docker Hub 页面看一眼最近几个标签的更新说明挑一个稳定的。升级的时候也不要直接换标签重启而是先备份数据库再拉新镜像按官方升级文档走迁移流程。提示如果你在 Docker Hub 上看到镜像标签只有latest和master说明这个镜像的版本管理不规范建议换一个维护更勤快的镜像源。2.3 数据库镜像的选择MySQL 5.7 还是 8.0服务端依赖 MySQL 存储账号、角色、世界数据。AzerothCore 官方推荐MySQL 8.0但实际部署中我发现 5.7 的兼容性反而更好尤其是老版本的 SQL 脚本里有些语法在 8.0 下会报错。如果你用官方 compose 文件它默认会拉mysql:8.0这个没问题因为官方已经把 SQL 脚本适配过了。但如果你是自己写 compose从旧版本迁移数据建议先用mysql:5.7跑通确认数据没问题再考虑升级。这里有个坑要提前说MySQL 8.0 默认的认证插件是caching_sha2_password而某些老版本的服务端连接库不支持这个插件会导致认证服务连不上数据库。解决办法是在 compose 里加一行环境变量command: --default-authentication-pluginmysql_native_password强制用旧版认证方式。services: db: image: mysql:8.0 command: --default-authentication-pluginmysql_native_password environment: MYSQL_ROOT_PASSWORD: yourpassword MYSQL_DATABASE: acore_world volumes: - ./data/mysql:/var/lib/mysql3. 从零到登录界面compose 编排的完整落地过程3.1 目录结构规划数据卷挂载是重中之重Docker 部署服务端最核心的原则是容器无状态数据全挂载。容器本身随时可以删掉重建但数据库文件、配置文件、日志必须落在宿主机上。我习惯的目录结构是这样的wow-server/ ├── docker-compose.yml ├── data/ │ ├── mysql/ # 数据库文件 │ ├── world/ # 世界服务数据 │ └── logs/ # 服务端日志 ├── config/ │ ├── worldserver.conf │ └── authserver.conf └── sql/ └── init/ # 自定义 SQL 脚本这个结构的好处是备份的时候直接打包整个wow-server目录迁移的时候拷过去就行。data/mysql目录尤其重要里面存着所有账号和角色数据丢了就全没了。注意MySQL 容器对挂载目录的权限有要求如果宿主机目录属主不是999MySQL 容器内用户 UID启动会报权限错误。解决办法是chown -R 999:999 ./data/mysql或者直接在 compose 里指定user: 999:999。3.2 compose 文件逐段拆解每个参数都有讲究下面这份 compose 是我在实际部署中反复调整后的版本去掉了官方模板里一些用不上的服务保留了核心三件套数据库、认证服务、世界服务。services: ac-database: image: mysql:8.0 container_name: ac-database restart: unless-stopped command: --default-authentication-pluginmysql_native_password environment: MYSQL_ROOT_PASSWORD: acore_root_pass MYSQL_USER: acore MYSQL_PASSWORD: acore_pass volumes: - ./data/mysql:/var/lib/mysql ports: - 3306:3306 networks: - ac-network ac-authserver: image: azerothcore/azerothcore:master container_name: ac-authserver restart: unless-stopped depends_on: - ac-database volumes: - ./config/authserver.conf:/azerothcore/env/dist/etc/authserver.conf - ./data/logs:/azerothcore/env/dist/bin/logs ports: - 3724:3724 networks: - ac-network ac-worldserver: image: azerothcore/azerothcore:master container_name: ac-worldserver restart: unless-stopped depends_on: - ac-database - ac-authserver volumes: - ./config/worldserver.conf:/azerothcore/env/dist/etc/worldserver.conf - ./data/world:/azerothcore/env/dist/bin/data - ./data/logs:/azerothcore/env/dist/bin/logs ports: - 8085:8085 networks: - ac-network networks: ac-network: driver: bridge几个关键点解释一下。restart: unless-stopped保证容器异常退出后自动重启服务端跑久了偶尔会崩这个参数能省不少事。depends_on只控制启动顺序不保证数据库完全就绪所以世界服务启动时可能会因为连不上数据库而重试几次这是正常现象等一两分钟就好。端口映射方面3724是认证服务端口客户端登录走这个8085是世界服务端口进游戏后走这个。如果你只在局域网玩映射到宿主机就行如果要让外网朋友连进来需要在路由器上做端口转发同时把配置文件里的BindIP改成0.0.0.0。3.3 配置文件的关键改动别让默认值坑了你官方镜像里的配置文件模板有一堆默认值直接跑起来大概率连不上。必须改的几个地方数据库连接信息。worldserver.conf和authserver.conf里都有LoginDatabaseInfo、WorldDatabaseInfo、CharacterDatabaseInfo三行格式是主机;端口;用户;密码;数据库名。因为容器在同一个 bridge 网络里主机名直接写服务名ac-database端口3306用户密码跟 compose 里环境变量保持一致。LoginDatabaseInfo ac-database;3306;acore;acore_pass;acore_auth WorldDatabaseInfo ac-database;3306;acore;acore_pass;acore_world CharacterDatabaseInfo ac-database;3306;acore;acore_pass;acore_characters数据目录路径。DataDir这一行指向客户端提取出来的地图数据dbc、maps、vmaps、mmaps默认路径是./data容器内对应/azerothcore/env/dist/bin/data。这个数据必须从客户端提取没有它世界服务起不来。提取工具在服务端源码的contrib目录里或者用社区打包好的版本。绑定地址。BindIP默认是127.0.0.1只允许本机连接。局域网玩改成0.0.0.0或者填宿主机的局域网 IP。提示配置文件改完后docker compose restart让容器重新读取。如果改了数据库连接信息建议先docker compose down再up -d避免旧连接缓存导致的问题。3.4 首次启动的完整流程与验证方法第一次启动按这个顺序来能少走很多弯路准备数据目录mkdir -p data/mysql data/world data/logs config然后chown -R 999:999 data/mysql。放置配置文件从镜像里拷出默认配置docker run --rm azerothcore/azerothcore:master cat /azerothcore/env/dist/etc/worldserver.conf config/worldserver.conf然后按上面说的改。启动数据库docker compose up -d ac-database等 30 秒左右用docker logs ac-database看是否出现ready for connections。导入基础数据AzerothCore 镜像首次启动会自动执行数据库初始化但如果你用的是自定义 SQL需要手动导入。docker exec -i ac-database mysql -uacore -pacore_pass acore_world your.sql。启动认证和世界服务docker compose up -d然后docker logs -f ac-worldserver观察启动日志。验证看到World initialized和Worldserver started就说明起来了。用客户端连127.0.0.1:3724能进登录界面、能创建角色、能进游戏三步都通过才算真正跑通。4. 跑起来之后才会遇到的坑网络、权限与性能4.1 容器网络不通的三种典型表现Docker 网络问题是最让人头疼的因为报错信息往往很模糊。我遇到过三种情况排查思路各不相同。第一种认证服务连不上数据库。日志里反复出现Cant connect to MySQL server。先docker exec -it ac-authserver ping ac-database如果 ping 不通说明两个容器不在同一个网络里。检查 compose 里每个服务是否都声明了networks: - ac-network少写一个就会掉到默认网络里。第二种客户端能登录但进不了游戏。登录界面正常选角色后卡在读取界面。这通常是世界服务端口没映射对或者worldserver.conf里的WorldServerPort跟 compose 映射的端口不一致。默认是8085如果你改了配置文件compose 里的ports也要同步改。第三种局域网其他机器连不上。宿主机自己能玩朋友连不上。检查宿主机防火墙是否放行了3724和8085以及BindIP是否改成了0.0.0.0。Windows 上还要注意 Docker Desktop 的网络模式默认的 NAT 模式对外网访问有限制必要时切换到host网络模式仅限 Linux 宿主机。4.2 权限错误的排查链路从报错到修复权限问题在 Docker 部署里出现频率极高尤其是数据库目录和日志目录。我记录一次完整的排查过程你可以照着复现。现象docker compose up -d后ac-database容器反复重启docker logs显示mysqld: Cant create/write to file /var/lib/mysql/... (Errcode: 13 - Permission denied)。第一步确认宿主机目录属主。ls -ln data/mysql如果显示的用户 UID 不是999就是权限问题。第二步改属主。sudo chown -R 999:999 data/mysql。如果宿主机是 Windows 或 macOSDocker Desktop 的文件共享机制会自动处理权限这个问题一般不会出现。第三步如果改完还报错检查 SELinux。CentOS 或 RHEL 系宿主机上SELinux 会阻止容器访问挂载目录。临时方案是setenforce 0永久方案是给目录打标签chcon -Rt svirt_sandbox_file_t data/mysql。第四步验证。docker compose down docker compose up -d观察日志是否还有权限报错。注意不要图省事用privileged: true绕过权限问题这会让容器获得宿主机 root 权限安全风险很大。正确做法是调整目录属主和 SELinux 策略。4.3 资源占用与性能调优N100 能不能跑得动很多人关心小主机能不能跑服务端。我实测过 N1004 核 4 线程16G 内存跑 AzerothCore结论是能跑但要看怎么配。默认配置下世界服务启动后会预加载大量地图数据内存占用能到 4-6G。N100 的 16G 内存跑一个服务端加数据库没问题但同时跑多个容器比如再加个 GitLab、Redis就会吃紧。CPU 方面N100 单核性能一般玩家数量少10 人以内体验还行人多了会卡。调优方向有几个一是限制 MySQL 的innodb_buffer_pool_size默认可能占太多内存改成512M到1G之间二是世界服务的MapUpdate.Threads调低N100 上设成2就够了三是关掉不必要的日志输出Logger.Level设成2Error而不是3Info能减少磁盘 IO。# worldserver.conf 性能相关 MapUpdate.Threads 2 Logger.Level 2如果宿主机内存实在紧张可以把数据库单独放到另一台机器上世界服务通过局域网连过去。compose 里把ac-database服务删掉配置文件里的数据库主机改成那台机器的 IP 就行。5. 数据备份、迁移与版本升级的实操经验5.1 备份策略别等数据丢了才后悔服务端跑起来之后最值钱的就是数据库里的角色数据。我见过太多人折腾半天结果一次误操作把data/mysql删了所有账号角色归零。备份分两个层次。数据库逻辑备份用mysqldump每天定时跑一次docker exec ac-database mysqldump -uacore -pacore_pass --all-databases backup/wow_$(date %Y%m%d).sql这个备份文件小恢复方便适合日常。物理备份直接打包data/mysql目录适合大版本升级前做全量快照。物理备份必须在数据库停止状态下做否则文件可能不一致docker compose stop ac-database tar czf backup/mysql_physical_$(date %Y%m%d).tar.gz data/mysql docker compose start ac-database配置文件也别忘了一起备份config/目录打包进去恢复的时候省得重新改。5.2 迁移到另一台机器的完整步骤迁移的核心是数据目录 compose 文件 配置文件三件套。步骤在源机器上docker compose down确保所有容器停止。打包整个wow-server目录tar czf wow-server-backup.tar.gz wow-server/。拷到目标机器解压。目标机器上装好 Docker 和 Docker Compose。检查目录权限chown -R 999:999 data/mysql。docker compose up -d观察日志。如果目标机器的 Docker 版本跟源机器差异较大可能会遇到镜像不兼容的问题。解决办法是重新拉一次镜像docker compose pull然后up -d。提示迁移后如果客户端连不上先检查目标机器的 IP 是否变了配置文件里的BindIP和客户端的realmlist都要同步更新。5.3 版本升级什么时候该升怎么升才安全服务端镜像更新频繁但不是每次更新都值得跟。我的原则是没有明确需要的功能或修复不升级。升级意味着数据库结构可能变化角色数据有损坏风险。如果确实要升按这个流程走先看官方更新说明确认是否有数据库迁移脚本。全量备份数据库和配置文件。拉新镜像docker compose pull。停止服务docker compose down。启动数据库执行迁移脚本如果有。启动认证和世界服务观察日志是否有报错。用测试账号登录验证角色数据是否正常。如果升级后服务起不来回滚方案是换回旧镜像标签恢复备份的数据库。所以备份是升级的前提没有备份就不要升级。6. 几个容易被忽略的细节与个人体会6.1 客户端版本与服务端版本的匹配问题服务端跑起来了客户端连不上很多时候是版本不匹配。AzerothCore 主要支持3.3.5aWotLK版本客户端必须是这个版本的完整客户端不能是其他资料片的。客户端的realmlist.wtf文件里要改成服务端 IP格式是set realmlist 127.0.0.1。另外客户端的数据提取dbc、maps、vmaps、mmaps必须用跟服务端版本匹配的工具版本不对会导致世界服务启动时报Map file not found或者进游戏后地图错乱。6.2 日志是排查问题的第一手资料Docker 部署最大的好处之一就是日志集中。docker logs -f ac-worldserver能实时看到服务端输出出问题先看日志比瞎猜快得多。常见的日志关键词Cant connect是网络或数据库问题Permission denied是权限问题Map file not found是数据目录问题Table doesnt exist是数据库初始化没完成。我习惯在 compose 里把日志目录挂载出来./data/logs:/azerothcore/env/dist/bin/logs这样日志文件持久化容器删了日志还在方便事后分析。6.3 关于 Docker Desktop 在 Windows 上的那些事Windows 上用 Docker Desktop 跑服务端有几个坑要提前知道。一是WSL2 后端比 Hyper-V 后端性能好建议在设置里切换。二是文件挂载性能Windows 目录挂载到容器里 IO 很慢数据库文件放在 WSL2 的 Linux 文件系统里会快很多。三是虚拟化支持如果启动 Docker Desktop 报virtualisation support wasnt detected需要进 BIOS 开启 VT-x 或 AMD-V然后在 Windows 功能里启用 WSL2 和虚拟机平台。如果实在搞不定 Docker Desktop可以考虑在 Windows 上装个 WSL2 的 Ubuntu然后在 Ubuntu 里装 Docker Engine这样跟 Linux 原生环境基本一致少很多兼容性问题。6.4 我个人的一些使用习惯跑了几年 Docker 服务端有几个习惯我觉得挺有用。一是给每个容器起明确的名字ac-database、ac-worldserver比随机生成的容器名好管理。二是用.env文件管理密码不要把密码硬编码在 compose 里.env文件加到.gitignore避免泄露。三是定期清理无用镜像docker system prune -a能释放不少空间但执行前确认没有正在用的镜像。最后说一个心态上的体会Docker 部署服务端前期配置确实比一键包麻烦但一旦跑通后续的维护、迁移、升级都比传统方式省心太多。遇到问题不要急着删容器重来先看日志、查网络、验权限大部分问题都能定位到具体原因。这套流程走顺了你会发现 Docker 不只是个部署工具更是一种让服务端变得可管理、可复现的思维方式。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑