包含 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>
93 lines
3.9 KiB
YAML
93 lines
3.9 KiB
YAML
# 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}
|