ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Docker容器化部署WOW服务端:镜像选型、数据库初始化与配置挂载实战

Docker容器化部署WOW服务端:镜像选型、数据库初始化与配置挂载实战 1. 为什么要在 Docker 里跑 WOW 服务端把 WOW 服务端塞进 Docker这件事我前前后后折腾了差不多两年。最早是在一台闲置的旧笔记本上直接装服务端系统是 Ubuntu编译、装依赖、配数据库一套流程走下来重装一次系统就得从头再来一遍。后来换机器、换系统每次都要重新踩一遍坑实在受不了才开始认真考虑用容器把整套环境固化下来。WOW 服务端本质上是一个多进程协作的系统一个负责认证的进程、一个负责世界逻辑的进程、一个数据库、再加上若干辅助脚本。传统部署方式下这些东西散落在宿主机的各个目录里配置文件互相引用路径写死换台机器就报错。Docker 的价值在这里体现得非常直接——把认证服务、世界服务、数据库、配置文件和启动脚本全部打包进镜像用一份 compose 文件描述它们之间的关系换任何一台装了 Docker 的机器一条命令就能拉起来。这篇文章面向的是想自己搭一个 WOW 服务端、又不想被环境问题反复折磨的人。不管你是完全没接触过 Docker 的新手还是已经用过 Docker 但没试过跑游戏服务端的老手下面的内容都能直接照着做。我会把镜像怎么选、数据库怎么初始化、端口怎么映射、配置文件怎么挂载、启动顺序怎么控制这些关键环节全部拆开讲清楚并且把我在实际操作中踩过的坑和对应的解决办法一并写出来。需要提前说明的是WOW 服务端本身是开源社区维护的项目不同版本比如经典的 3.3.5 版本和后续版本对应的服务端实现不一样本文以社区里流传最广、资料最全的 3.3.5 版本为主线来展开其他版本思路一致只是镜像和配置细节有差异。2. 整体方案设计与镜像选型思路2.1 为什么用 Docker 而不是直接装先说清楚 Docker 方案到底解决了什么问题这样你在后面遇到选择时才知道该怎么权衡。直接装在宿主机上的服务端最大的问题是环境污染。服务端依赖特定版本的数据库、特定版本的运行库这些依赖一旦和宿主机上其他软件冲突排查起来非常痛苦。我遇到过最典型的一次是宿主机上已经装了一个数据库用于别的用途服务端要求的版本和它不一致结果两边都跑不起来最后只能把数据库卸了重装。Docker 把每个组件隔离在独立容器里数据库容器只服务这个服务端运行库版本固定在镜像里和宿主机完全解耦。带来的直接好处有三个第一可移植镜像推到仓库换机器直接拉第二可回滚镜像打标签出问题切回上一个版本第三可复制想开第二个服务端实例改一下端口和容器名就行互不干扰。代价也有主要是性能开销和网络配置复杂度。容器网络比宿主机直连多一层转发对延迟敏感的场景需要额外调优端口映射、容器间通信这些概念对新手有一定门槛。但对于个人搭建、朋友之间联机这种场景这点开销完全可以接受。2.2 镜像来源的三种选择社区里能拿到的 WOW 服务端镜像大致分三类各有取舍。第一类是官方或半官方维护的镜像特点是更新及时、文档相对完整但往往只提供最基础的服务端数据库和配置需要自己补。第二类是个人打包的整合镜像把服务端、数据库、配置全部塞进一个镜像开箱即用缺点是镜像体积大、更新依赖打包者、出问题不好定位。第三类是自己基于基础镜像构建用 Dockerfile 把服务端编译和配置过程固化下来灵活度最高但需要一定的构建知识。我的建议是第一次搭建用整合镜像快速跑通跑通之后再考虑自己构建。先用整合镜像把整个流程走一遍理解各个组件之间的关系等你知道每个配置文件是干什么的、数据库里有哪些表之后再自己构建就能做到心里有数。上来就自己构建很容易在编译阶段卡住连服务端长什么样都没见到就放弃了。2.3 组件拆分与容器编排一个完整的 WOW 服务端在 Docker 里通常拆成三个容器数据库容器、认证服务容器、世界服务容器。有些整合镜像会把认证和世界服务放在同一个容器里用启动脚本控制两个进程这样容器数量少但日志混在一起排查问题时不够清晰。我更推荐拆开理由后面讲排查技巧时会说到。三个容器之间用 Docker 的自定义网络连接容器之间通过服务名互相访问不需要暴露数据库端口到宿主机。只有认证服务和世界服务需要对外暴露端口供游戏客户端连接。这种拆分方式的好处是每个容器职责单一重启某一个不影响其他日志也各自独立。数据库用社区里最常用的那个开源关系型数据库即可服务端对它的版本有要求太新或太旧都可能出问题具体版本在下一节会给出。3. 环境准备与 Docker 安装要点3.1 宿主机系统选择与资源评估宿主机系统我推荐用 Linux 发行版Ubuntu 或者 Debian 都行。Windows 上通过 Docker Desktop 也能跑但文件挂载的性能和权限处理会多出一些麻烦尤其是数据库数据目录挂载到 Windows 文件系统时权限问题几乎必然出现。如果你只有 Windows 机器建议在虚拟机里装一个 Linux 再跑 Docker虽然多一层但省心。资源方面服务端本身对 CPU 要求不高双核就够但内存是硬指标。数据库容器建议给 1GB 以上认证服务 256MB 左右世界服务根据同时在线人数浮动单人测试 512MB 够用几个人一起玩建议给到 1GB 以上。磁盘方面服务端程序加数据库数据预留 10GB 比较稳妥数据库会随着游戏数据增长。提示如果你打算长期运行建议把数据库的数据目录挂载到宿主机的一个独立分区这样即使容器重建数据也不会丢。这一步在后面的挂载配置里会详细说。3.2 Docker 与 Docker Compose 安装Linux 上安装 Docker 用官方脚本最省事但要注意脚本会从官方源拉取网络条件不好的话可能很慢。可以先用系统包管理器装一个基础版本再按需升级。# Ubuntu/Debian 系统安装 Docker sudo apt update sudo apt install -y docker.io docker-compose-plugin # 启动 Docker 服务并设置开机自启 sudo systemctl enable --now docker # 把当前用户加入 docker 组避免每次都要 sudo sudo usermod -aG docker $USER # 执行完这行需要重新登录一次才生效装完之后用docker version和docker compose version验证一下。如果docker compose提示找不到命令说明装的是老版本的docker-compose中间是横线两者用法基本一致把后面命令里的docker compose换成docker-compose即可。Windows 用户装 Docker Desktop安装过程中如果提示虚拟化未开启需要进 BIOS 打开虚拟化支持。这个提示在热词里出现频率很高本质是主板层面的设置和 Docker 本身无关。开启之后重启Docker Desktop 就能正常启动。3.3 镜像加速与拉取策略国内拉取镜像慢是普遍问题配置镜像加速器能明显改善。在/etc/docker/daemon.json里加上加速地址然后重启 Docker 服务。{ registry-mirrors: [ https://your-mirror-address ] }加速地址会随时间变化建议用之前先确认当前可用的地址。配置完之后sudo systemctl restart docker重启生效。拉取镜像时如果卡在某一层不动可以中断后重试Docker 会复用已经拉下来的层不会从头开始。4. 数据库容器的部署与初始化4.1 数据库版本选择与参数配置服务端对数据库版本有明确要求3.3.5 版本的服务端通常要求 5.7 或 8.0 系列。我实测下来 8.0 系列更稳但要注意 8.0 默认的认证插件和字符集设置可能和服务端的 SQL 脚本不兼容需要在启动参数里显式指定。数据库容器的启动参数里有几个必须设置字符集用utf8mb4认证插件用兼容旧客户端的那个时区设置成和服务端一致。这些参数如果漏了后面导入 SQL 脚本时会报各种奇怪的错误比如中文乱码、连接被拒绝。services: wow-db: image: mysql:8.0 container_name: wow-db restart: unless-stopped environment: MYSQL_ROOT_PASSWORD: your_root_password MYSQL_DATABASE: wow_auth TZ: Asia/Shanghai command: - --character-set-serverutf8mb4 - --collation-serverutf8mb4_unicode_ci - --default-authentication-pluginmysql_native_password volumes: - ./data/db:/var/lib/mysql networks: - wow-netrestart: unless-stopped这个策略很重要它保证容器在宿主机重启后自动拉起除非你手动停过它。数据库这种有状态服务最怕的就是意外退出后没人管。4.2 数据目录挂载与权限处理./data/db:/var/lib/mysql这行把数据库数据目录挂载到宿主机的相对路径下。这样做的好处是容器删了数据还在重建容器后数据自动恢复。但这里有个坑宿主机目录的权限必须和容器内数据库进程的用户匹配。数据库容器内的进程通常以特定用户身份运行如果宿主机目录属于 root 且权限是 755容器内进程没有写权限启动时会直接报错退出。解决办法是提前把宿主机目录的属主改成容器内对应的用户 ID或者干脆把目录权限放宽。mkdir -p ./data/db # 查看容器内数据库用户的 UID通常是 999 # 把宿主机目录属主改成对应 UID sudo chown -R 999:999 ./data/db如果你不确定 UID 是多少可以先启动一次容器看报错信息里提示的 UID或者用docker inspect查看镜像的配置。这个权限问题在 Windows 上更麻烦因为 Windows 文件系统的权限模型和 Linux 不同挂载后经常出现容器内无法写入的情况这也是我前面建议 Windows 用户走虚拟机的原因。4.3 导入服务端 SQL 脚本数据库容器起来之后需要把服务端的 SQL 脚本导入进去。服务端的 SQL 脚本通常分几个文件认证库的、世界库的、角色库的。导入顺序有讲究先建库再导表表之间有外键依赖顺序错了会报错。# 把 SQL 文件复制进容器 docker cp ./sql/auth.sql wow-db:/tmp/auth.sql docker cp ./sql/world.sql wow-db:/tmp/world.sql docker cp ./sql/characters.sql wow-db:/tmp/characters.sql # 进入容器执行导入 docker exec -it wow-db bash mysql -uroot -p /tmp/auth.sql mysql -uroot -p /tmp/world.sql mysql -uroot -p /tmp/characters.sql导入 world 库的脚本时文件通常比较大几百 MB 很常见导入过程可能持续几分钟到十几分钟。这段时间不要中断中断后重新导入可能因为部分表已存在而报错需要先清库再重来。我一般会在导入前先确认磁盘空间充足导入过程中用docker stats观察容器的资源占用确认它在正常工作而不是卡死了。注意导入完成后检查一下几个关键表是否有数据比如认证库里的账号表、世界库里的地图表。如果这些表是空的说明导入没成功后面服务端启动时会因为读不到数据而崩溃。5. 服务端容器的配置与启动5.1 配置文件挂载与关键参数服务端的配置文件通常有两个认证服务的配置和世界服务的配置。这两个文件里需要改的地方主要是数据库连接信息、监听地址、日志级别。数据库连接信息要指向数据库容器的服务名而不是 localhost。在 Docker 自定义网络里容器之间用服务名互相解析所以配置里写wow-db就能连上数据库容器。这一点和传统部署不一样传统部署写 localhost 是因为数据库和服
返回列表