2140 字
11 分钟
Debian 13 上使用 Docker Compose 部署饥荒联机版专用服务器

这篇文章记录如何在 Debian 13(Trixie)上使用 Docker Compose 部署《饥荒联机版》(Don’t Starve Together,以下简称 DST)专用服务器。

最终会运行两个容器:

  • master:地面世界,使用 UDP 10999。
  • caves:洞穴世界,使用 UDP 11000。

两个容器共享同一个存档目录,并通过宿主机回环地址上的 10888 端口完成分片通信。镜像采用社区维护的 webhippie/dst,它会通过 SteamCMD 安装或更新服务器,并根据环境变量生成 cluster.iniserver.ini 和模组配置。

Klei 集群令牌相当于服务器凭据。不要把真实令牌、服务器密码写进公开文章、截图、Git 仓库或 compose.yaml。如果令牌曾经被公开,应先在 Klei 服务器管理页面删除它,再生成新令牌。

一、准备服务器#

本文使用的配置特点如下:

  • Debian 13 服务器,建议使用 64 位系统。
  • 无尽模式,最多 8 人,关闭 PVP。
  • 无玩家时暂停世界。
  • 同时启用地面和洞穴。
  • 使用宿主机网络,避免容器网络影响分片发现和 UDP 通信。
  • 存档持久化到 /opt/dst/data
  • 支持自动下载 Steam Workshop 模组。

地面和洞穴分别是两个服务器进程,Klei 也提醒这种部署比单地面世界需要更多 CPU 和内存。正式开服前应确认服务器有足够资源,并为镜像、游戏文件、模组和存档预留磁盘空间。

二、安装 Docker Engine 和 Compose#

Docker 官方已经支持 Debian 13。这里使用 Docker 官方 APT 软件源安装 Engine 与 Compose 插件,而不是旧版的独立 docker-compose 命令。

Terminal window
sudo apt update
sudo apt install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/debian/gpg \
-o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

添加 Debian 13(Trixie)软件源:

Terminal window
sudo tee /etc/apt/sources.list.d/docker.sources >/dev/null <<EOF
Types: deb
URIs: https://download.docker.com/linux/debian
Suites: trixie
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF
sudo apt update
sudo apt install -y \
docker-ce \
docker-ce-cli \
containerd.io \
docker-buildx-plugin \
docker-compose-plugin

启用服务并检查版本:

Terminal window
sudo systemctl enable --now docker
sudo docker version
sudo docker compose version
sudo docker run --rm hello-world

如果系统以前安装过 docker.io、旧版 docker-composepodman-docker 或自行安装的 containerd,应先按照 Docker 官方 Debian 安装文档处理冲突包,而不是直接混装。

三、获取 Klei 集群令牌#

登录 Klei 账号的 Don’t Starve Together Game Servers 页面,创建一个服务器并复制生成的 Cluster Token。

在线服务器必须拥有有效的集群令牌;令牌用于证明服务器所有权并让服务器出现在公开服务器列表中。一个典型集群目录由 cluster.inicluster_token.txtMaster/Caves/ 等内容组成。

不要把令牌直接放进 Compose 文件。下一节会使用仅限本机读取的 .env 保存它。

四、创建部署目录#

Terminal window
sudo install -d -m 0750 -o "$USER" -g "$USER" /opt/dst/data
cd /opt/dst

创建 .gitignore

.gitignore
.env
data/
backups/

即使暂时不准备把部署目录提交到 Git,也建议保留这份忽略规则,避免以后误提交令牌和存档。

五、创建 .env#

/opt/dst/.env 中填写:

# 从 Klei 服务器管理页面生成的新令牌
DST_CLUSTER_TOKEN='在这里粘贴新的 Klei Cluster Token'
# 留空表示服务器不设密码
DST_CLUSTER_PASSWORD='请替换成自己的服务器密码'
DST_CLUSTER_NAME='Kedaya'
DST_CLUSTER_DESCRIPTION='Kedaya DST Master and Caves'
DST_MAX_PLAYERS='8'
# 模组 ID 使用英文逗号分隔;首次排错时可以暂时设为空字符串
DST_SERVER_MOD_SETUP='1185229307,378160973,2075943614,1530801499,2189004162'

限制文件权限:

Terminal window
chmod 600 /opt/dst/.env

.env 中的单引号会把内容作为字面值处理,对带有特殊字符的令牌和密码更友好。不要在值两边额外加入中文引号。

六、编写 compose.yaml#

/opt/dst/compose.yaml 中写入:

name: dst
x-dst-common: &dst-common
image: webhippie/dst:latest
network_mode: host
restart: unless-stopped
stdin_open: true
tty: true
stop_grace_period: 30s
volumes:
- ./data:/var/lib/game
logging:
driver: local
options:
max-size: "100m"
max-file: "10"
x-dst-environment: &dst-environment
# Klei 认证信息从 .env 读取
DST_CLUSTER_TOKEN: "${DST_CLUSTER_TOKEN:?请在 .env 中设置 DST_CLUSTER_TOKEN}"
# 存档位置
DST_SERVER_PERSISTENT_STORAGE_ROOT: "/var/lib/game"
DST_SERVER_CONF_DIR: "DoNotStarveTogether"
DST_SERVER_CLUSTER: "Cluster_1"
# 服务器信息
DST_NETWORK_CLUSTER_NAME: "${DST_CLUSTER_NAME:-Kedaya}"
DST_NETWORK_CLUSTER_DESCRIPTION: "${DST_CLUSTER_DESCRIPTION:-Kedaya DST Master and Caves}"
DST_NETWORK_CLUSTER_PASSWORD: "${DST_CLUSTER_PASSWORD:-}"
DST_NETWORK_CLUSTER_LANGUAGE: "zh"
DST_NETWORK_CLUSTER_INTENTION: "cooperative"
DST_NETWORK_LAN_ONLY_SERVER: "false"
DST_NETWORK_OFFLINE_CLUSTER: "false"
DST_NETWORK_AUTOSAVER_ENABLED: "true"
DST_NETWORK_TICK_RATE: "15"
DST_NETWORK_WHITELIST_SLOTS: "0"
# 游戏规则:endless 是无尽模式
DST_GAMEPLAY_GAME_MODE: "endless"
DST_GAMEPLAY_MAX_PLAYERS: "${DST_MAX_PLAYERS:-8}"
DST_GAMEPLAY_PVP: "false"
DST_GAMEPLAY_PAUSE_WHEN_EMPTY: "true"
DST_GAMEPLAY_VOTE_ENABLED: "true"
# 地面与洞穴的分片通信只监听宿主机回环地址
DST_SHARD_ENABLED: "true"
DST_SHARD_BIND_IP: "127.0.0.1"
DST_SHARD_MASTER_IP: "127.0.0.1"
DST_SHARD_MASTER_PORT: "10888"
DST_SHARD_CLUSTER_KEY: "default"
DST_MISC_CONSOLE_ENABLED: "true"
# Steam Workshop 模组
DST_SERVER_MOD_SETUP: "${DST_SERVER_MOD_SETUP:-}"
# 自动更新游戏并生成配置文件
DST_SKIP_GAME_UPGRADE: "false"
DST_SKIP_CLUSTER_CONFIG: "false"
DST_SKIP_SERVER_CONFIG: "false"
DST_SKIP_LEVELDATA_OVERRIDE: "false"
DST_SKIP_MOD_SETUP: "false"
DST_SKIP_MOD_OVERRIDES: "false"
DST_SKIP_MOD_SETTINGS: "false"
services:
master:
<<: *dst-common
container_name: dst-master
environment:
<<: *dst-environment
DST_SHARD_NAME: "Master"
DST_SHARD_IS_MASTER: "true"
DST_NETWORK_SERVER_PORT: "10999"
DST_STEAM_MASTER_SERVER_PORT: "27016"
DST_STEAM_AUTHENTICATION_PORT: "8766"
caves:
<<: *dst-common
container_name: dst-caves
depends_on:
- master
environment:
<<: *dst-environment
DST_SHARD_NAME: "Caves"
DST_SHARD_IS_MASTER: "false"
DST_NETWORK_SERVER_PORT: "11000"
DST_STEAM_MASTER_SERVER_PORT: "27017"
DST_STEAM_AUTHENTICATION_PORT: "8767"

这里使用了 YAML Anchor,把两个分片共有的镜像、存档和游戏规则集中到一处。地面和洞穴只覆盖分片名称、主从身份以及三组必须互不冲突的端口。

由于使用 network_mode: host,不需要再写 ports:。这种模式适用于本文的 Debian Linux 主机;容器会直接监听宿主机端口。

DST_SKIP_LEVELDATA_OVERRIDE: "false" 会让镜像为全新集群生成地面和洞穴所需的 leveldataoverride.lua。如果以后导入了自己从游戏客户端生成的完整世界配置,并且不希望容器再次生成该文件,可以在备份存档后将它改成 "true"

七、开放 UDP 端口#

需要在云服务器安全组和宿主机防火墙中允许以下 UDP 端口:

用途地面洞穴
玩家连接端口1099911000
Steam Master Server2701627017
Steam Authentication87668767

分片通信端口 10888 绑定在 127.0.0.1,只供同一台服务器上的地面和洞穴通信,不应向公网开放。

如果服务器已经安装 UFW,可以执行:

Terminal window
sudo ufw allow 10999:11000/udp
sudo ufw allow 27016:27017/udp
sudo ufw allow 8766:8767/udp
sudo ufw status

没有使用 UFW 时,应按照实际采用的 nftables、iptables 或云平台安全组配置等价规则。Docker 官方特别提醒,Docker 的网络规则可能和 UFW 等前端工具产生交互,因此上线后仍要从外部网络实际验证,而不能只看防火墙界面。

八、启动地面和洞穴#

先进行只验证、不打印解析结果的 Compose 检查,避免令牌出现在终端记录中:

Terminal window
cd /opt/dst
sudo docker compose config --quiet

拉取镜像并启动:

Terminal window
sudo docker compose pull
sudo docker compose up -d
sudo docker compose ps

第一次启动需要下载或更新 DST 专用服务器和模组,耗时取决于网络与磁盘性能。查看两个分片的日志:

Terminal window
sudo docker compose logs -f --tail=200 master caves

Ctrl+C 只会退出日志查看,不会停止服务器。

如果 master 已经启动而 caves 因为首次生成较慢没有连上,可以等待地面初始化完成后单独重启洞穴:

Terminal window
sudo docker compose restart caves

随后在游戏服务器列表中搜索 .env 里设置的 DST_CLUSTER_NAME。如果设置了服务器密码,加入时使用该密码,而不是 Klei Cluster Token。

九、模组说明与兼容性#

示例保留了原配置中的五个 Workshop 模组:

Workshop ID名称
1185229307Epic Healthbar
378160973Global Positions
2075943614Extra Equip Slots (Modified)
1530801499Fast Travel (GUI)
2189004162Insight (Show Me+)

webhippie/dst 会根据 DST_SERVER_MOD_SETUP 下载模组,并为两个分片生成模组覆盖配置。洞穴服务器必须拥有与地面一致的必要服务器模组,否则可能在进出洞穴时断线或崩溃。

模组不是服务器镜像的一部分,其兼容性可能随 DST 更新变化。尤其是装备栏和 UI 类旧模组,社区中存在洞穴崩溃或版本过期的报告。因此建议采用下面的顺序排错:

  1. 先把 .env 中的 DST_SERVER_MOD_SETUP 改为空字符串,确认纯净服务器能够启动。
  2. 每次只加入一个模组并重启两个分片。
  3. 同时观察 mastercaves 日志。
  4. 出现 Lua 错误时,先移除最近加入的模组,而不是删除整个存档。

修改模组列表后重新创建容器:

Terminal window
cd /opt/dst
sudo docker compose up -d --force-recreate
sudo docker compose logs -f --tail=200 master caves

十、日常管理#

查看状态:

Terminal window
cd /opt/dst
sudo docker compose ps

查看最近日志:

Terminal window
sudo docker compose logs --tail=200 master caves

停止服务器:

Terminal window
sudo docker compose stop

重新启动:

Terminal window
sudo docker compose start

重启两个分片:

Terminal window
sudo docker compose restart

拉取新镜像并更新容器:

Terminal window
sudo docker compose pull
sudo docker compose up -d
sudo docker compose logs --tail=200 master caves

镜像的 DST_SKIP_GAME_UPGRADEfalse,容器启动时还会检查 DST 服务端更新。大型更新后应重点检查模组日志。

参考资料#