Releases: heyvaldemar/kf2-server-docker-compose
Release list
v1.2.1
Security
gameservermanagers/gameserver:kf2was rebuilt upstream; the pin moved fromsha256:52beab070566…tosha256:6d1130d02554…. Same version, same tag, a rebuilt base image — the usual shape of a security fix in a base layer.
Upgrading
git pull (or ./update.sh), then docker compose up -d. Containers on a refreshed image are recreated; data volumes and .env are untouched. This release was cut by fleet triage after the deploy job booted the stack on the refreshed images.
Full history in CHANGELOG.md.
v1.2.0
Killing Floor 2 has no rcon, and its only administrative interface cannot be used without a password that closes the server to players. Until now this template said "set the admin password through WebAdmin on first use". Both times that was done on the machine this template comes from, the server advertised itself as password protected and dropped every client that did not answer the prompt.
So moderation goes through the file. A ban is one line under [Engine.AccessControl] in an ini the engine rewrites on the way out and again on the way up: an edit made while it runs is thrown away at the next stop, and an edit it does not accept is gone by the time it answers a query. tools/kf2-ban.sh stops the server, writes the line as the server's own user, starts it, waits for it to answer, and reports success only after finding the id in the file the server just rewrote. A zero exit from the edit is not that.
A restart ends the round for everyone playing, for a ban that only bites on the next connection anyway. The first version refused while anyone was on and told the moderator to come back later; twice in three days nobody did. So with players on, or a server that does not answer, the id is queued and tools/kf2-ban-queue.sh applies it the moment the server is empty, on a five-minute timer. Both ask one probe, tools/kf2-a2s.sh, from inside the container, so they cannot disagree about what empty means, and an unanswered query is not an empty server. The news goes to KF2_MODERATION_WEBHOOK if .env names a Mattermost or Slack webhook, and a webhook that does not answer fails the run.
tools/kf2-listed.sh asks Steam whether the server is in its list, because for nineteen hours every local signal was green while nobody could find it, and the two local signals tried as a fix both cost restarts.
tests/e2e-moderation.sh proves all of it against the pinned image, with a stand-in on the query port where the game would be: 46 assertions, negatives included, on every push.
Upgrading: git pull or ./update.sh. Nothing in the running stack changes; KF2_SERVER_UPDATE_CHECK and KF2_MODERATION_WEBHOOK are new and optional. The tools need nothing installed on the host beyond docker compose, curl and, for the timer, systemd or cron.
v1.1.1
Security
gameservermanagers/gameserver:kf2was rebuilt upstream; the pin moved fromsha256:5a5c228f0059…tosha256:52beab070566…. Same version, same tag, a rebuilt base image — the usual shape of a security fix in a base layer.
Upgrading
git pull (or ./update.sh), then docker compose up -d. Containers on a refreshed image are recreated; data volumes and .env are untouched. This release was cut by fleet triage after the deploy job booted the stack on the refreshed images.
Full history in CHANGELOG.md.
v1.1.0
Added
update.sh: move between release tags on purpose. It updates to the latest release (a combination this repository's CI has booted and smoke-tested), refuses to cross a major version unattended, refuses to run over local changes, and names any new required variable before anything has moved.--dry-runsays what would happen.
Upgrading
git pull (or ./update.sh). Nothing running changes: this release adds or extends the update script and touches no image pin.
Full history in CHANGELOG.md.
v1.0.0
Added
- A Killing Floor 2 co-op server on LinuxGSM, image pinned by digest as an
interpolation default, sogit pulldelivers the build this repository has
tested and.envoverrides survive it. The tag is the game's name because
LinuxGSM publishes every game under one image and no version: the digest is
the version. - The query port carried under the same number inside and out, written in
both the instance config and the compose file, with the evening it cost
recorded beside it: a remap on the outside sends Steam's directory to a
port where another game answers, the handshake fails, and the server logs
Add unverified connectionand a timeout one second later. - A health check on the game binary with a bracket in the pattern.
pgrep -fmatches the shell running the check, so the unbracketed form
passed for every pattern ever given to it — measured — and a server that
crashed with a core dump reported healthy for seventeen hours. The first
version also matched LinuxGSM's wrapper and was green while SteamCMD was
still downloading the game.tests/e2e-healthcheck.shproves the bracket
against a real container. - Six players as the engine's number, not a choice, with the three ways
eight was refused written down. - Survival, not versus, and difficulty and length as their own variables
in the instance config so a change survives the next restart. - The instance config outside the volume, where git records it and
LinuxGSM's own update cannot overwrite it. - WebAdmin bound to localhost: the game has no rcon, and this form is the
whole administrative interface. - The volume declared external, so
docker compose down -vcannot delete
25 GB of game content and the server's state. - Deployment Verification CI: shell and workflow linting, a Trivy scan of
the pinned image, a daily freshness check on the pin, and the health-check
suite. It deliberately does not boot the game: the first start is a 25 GB
download.
Upgrading
First release: nothing to upgrade from. git clone, copy .env.example to .env, create the external volume where the compose file says so, and docker compose up -d.
Full history in CHANGELOG.md.