把多人小游戏部署到自己的 Docker 服务器

你画我猜增加了实时房间功能,因此它需要一个持续运行的服务端。部署时选择把它放进独立 Docker,而不是把代码和依赖混进原有静态游戏容器。

静态游戏库与实时服务各自维护

原游戏库继续提供已有的游戏文件、列表和播放页。新服务只负责你画我猜的页面、房间状态和 WebSocket 消息。用户从同一个游戏域名进入 /draw/,内部再由反向代理把这个路径交给新服务。

这种拆分的好处是,游戏开发需要修改服务端时,只需要维护新容器。原来的游戏资源、播放器和浏览器存档不必一起更换。当然,新服务自身重启仍会结束当前内存房间,因此更新应避开朋友正在玩的时候。

WebSocket 不只需要一个普通 HTTP 转发

普通页面通过 HTTP 获取文件,而实时消息需要把连接升级为 WebSocket。反向代理需要使用 HTTP/1.1,并传递 Upgrade 与 Connection 相关头,同时设置适当的读取超时。

上线检查也分两层:先确认页面和静态脚本返回正常,再用实际 WSS 客户端建立连接并交换房间消息。页面返回 200 只能证明网页能访问,不能证明联机功能正常。

端口和资源尽量收敛

新服务的宿主端口只监听回环地址,公网通过原来的 HTTPS 游戏入口访问。容器以非 root 用户运行,使用只读根文件系统,移除不需要的 Linux capabilities,并设置内存、CPU 和进程数限制。

日志使用 Docker json-file 轮转,设置单文件上限和保留份数,避免长期运行后日志不断挤占磁盘。这些限制只应用于新项目,没有为了统一配置而重启其他业务。

应用内部另有限制:房间总数、连接数、单条消息大小、操作频率和每题画笔点数。限制容器资源与限制应用输入是两件事,不能只配一个内存上限就认为服务可以承受任意输入。

依赖版本和上线前检查

服务采用 Node.js 和 ws,依赖固定版本并提交锁文件。安装时禁止执行依赖安装脚本。开发过程中的依赖审计发现原先选定的 ws 版本有已知问题,于是先升级到修复版本,再重新运行房间与网络测试。当前依赖审计没有报告已知漏洞,这也不等于保证未来永远没有漏洞。

部署前保存旧反向代理配置、游戏首页和容器状态。新配置先做 nginx 语法检查,通过后平滑加载;验证失败就恢复旧配置,而不是重启整台服务器或所有 Docker 服务。

备份代码,明确房间的边界

这个版本没有数据库,重要的部署资料是源码、依赖锁文件、Dockerfile、Compose 文件和反向代理配置。房间、聊天与当前画板没有做持久化,不需要把临时房间当成业务数据库备份。

未来如果增加账号、长期排行榜或者玩家作品保存,就需要重新设计存储、保留期限和恢复验证。现在先把小规模朋友联机的流程做好,比一开始加入大量功能更容易维护。

打开多人你画我猜,或者继续看开发记录。

上一篇