Files
squaddocker/docker-compose.yml
T
gongzhiyongandClaude Opus 5 3a76b40dbf feat: 新增 Squad 服务端 Docker 多实例部署方案
包含 docker-compose.yml(实例 2 用 profile 门控)、.env.example 配置模板、
以及基于实测数据的部署说明。

实测确认的关键点:
- 镜像仅 134MB 不含游戏文件,约 80-100GB 服务端由 SteamCMD 运行时拉取
- 镜像声明 4 个端口,BEACONPORT=15000 官方 wiki 未提及,host 网络下多实例会冲突
- entry.sh 会自动重写 Rcon.cfg 端口,但 sed 只匹配字面量 21114,
  首启后再改 RCONPORT 会静默失败
- entry.sh 每次启动无条件跑 app_update,故共享游戏文件方案有并发写入风险(未验证)
- 发现两个未见于文档的环境变量:SERVER_NAME、MULTIHOME
- RANDOM 环境变量在本镜像中无效(bash 内置特殊变量覆盖不了),已记录为已知问题

凭据一律使用占位符,.gitignore 挡住 .env / Rcon.cfg / License.cfg 等含密文件。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-27 20:48:11 +08:00

93 lines
3.9 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Squad 专用服务器 — 多实例编排
#
# 用法:
# cp .env.example .env 然后按注释填写
# docker compose up -d squad1 仅启动实例 1
# docker compose --profile instance2 up -d 同时启动实例 2(需先满足硬件要求)
#
# 重要:必须用 network_mode: host。Squad 依赖 Steam 查询协议,
# 用 -p 端口映射会导致服务器在游戏内浏览器中搜不到。
# 代价是 Docker 不再隔离端口,多实例端口必须手工错开(见 README §4)。
x-squad-common: &squad-common
image: ${SQUAD_IMAGE:?请在 .env 中设置 SQUAD_IMAGE}
network_mode: host
restart: unless-stopped
# entry.sh 以 `bash SquadGameServer.sh` 结尾而非 exec,信号不会完美转发,
# 给足时间让服务端自行落盘。
stop_grace_period: 120s
# PID 1 是 bash 脚本,用 init 回收僵尸进程
init: true
# 宿主机 ulimit -n 默认 1024 偏低。在容器层面单独调高,
# 不改宿主机配置(最小改动)。
ulimits:
nofile:
soft: 65535
hard: 65535
# Squad 日志量大,磁盘小的机器不轮转会被占满
logging:
driver: json-file
options:
max-size: "50m"
max-file: "3"
services:
# ── 实例 1 ────────────────────────────────────────────────
squad1:
<<: *squad-common
container_name: ${INST1_NAME:-squad1}
environment:
PORT: ${INST1_PORT:-7787}
QUERYPORT: ${INST1_QUERYPORT:-27165}
BEACONPORT: ${INST1_BEACONPORT:-15000}
RCONPORT: ${INST1_RCONPORT:-21114}
FIXEDMAXPLAYERS: ${INST1_MAXPLAYERS:-50}
FIXEDMAXTICKRATE: ${INST1_TICKRATE:-50}
# SERVER_NAME 会被 entry.sh 写入 Server.cfg 的 ServerName
SERVER_NAME: ${INST1_SERVER_NAME:-}
# MULTIHOME 绑定指定网卡 IP。多实例时可用它进一步隔离,
# 留空 / 0.0.0.0 / 127.0.0.1 时 entry.sh 会忽略该参数。
MULTIHOME: ${INST1_MULTIHOME:-}
# 可选:创意工坊 Mod,格式为 bash 数组字面量,例如 (1959152751 2016356569)
MODS: ${INST1_MODS:-()}
# 可选:测试版分支
STEAM_BETA_BRANCH: ${STEAM_BETA_BRANCH:-}
STEAM_BETA_PASSWORD: ${STEAM_BETA_PASSWORD:-}
# 注意:RANDOM 在此镜像中无效,不要设置。原因见 README §10
volumes:
- ${SQUAD_DATA_ROOT:?请在 .env 中设置 SQUAD_DATA_ROOT}/inst1:/home/steam/squad-dedicated
# 内存上限。宿主机无 swap 时,不设上限会让容器 OOM 拖垮整机。
mem_limit: ${INST1_MEM_LIMIT:-6g}
# ── 实例 2 ────────────────────────────────────────────────
# 默认不启动。启用前请确认硬件满足 README §2.2 的双实例要求
# (2 个物理核 + 16GB 内存 + 160GB 磁盘),否则两个实例会双双掉 tick。
squad2:
<<: *squad-common
container_name: ${INST2_NAME:-squad2}
profiles: ["instance2"]
environment:
PORT: ${INST2_PORT:-7797}
QUERYPORT: ${INST2_QUERYPORT:-27175}
BEACONPORT: ${INST2_BEACONPORT:-15010}
RCONPORT: ${INST2_RCONPORT:-21124}
FIXEDMAXPLAYERS: ${INST2_MAXPLAYERS:-50}
FIXEDMAXTICKRATE: ${INST2_TICKRATE:-50}
SERVER_NAME: ${INST2_SERVER_NAME:-}
MULTIHOME: ${INST2_MULTIHOME:-}
MODS: ${INST2_MODS:-()}
STEAM_BETA_BRANCH: ${STEAM_BETA_BRANCH:-}
STEAM_BETA_PASSWORD: ${STEAM_BETA_PASSWORD:-}
volumes:
# 独立安装:各自一份游戏文件(约 80-100GB × 2)
- ${SQUAD_DATA_ROOT}/inst2:/home/steam/squad-dedicated
#
# 共享游戏文件方案见 README §7.2 —— 尚未实测,勿用于生产。
# entry.sh 每次启动都会跑 SteamCMD app_update,两个容器共享同一
# 游戏目录时会并发写入,有损坏风险。
mem_limit: ${INST2_MEM_LIMIT:-6g}