KitsuneLab CS2
Go 12
// Overview
The CS2 egg rewritten in Go for Pterodactyl and Pelican, with no shell script in the image. One static binary boots each server, and an optional node daemon shares a single CS2 install and the workshop content between all of them (around 52 GB saved per server) and drops bot floods in nftables before they reach a container. Optional modules add addon caching, Discord alerts, crash bundles, backups and Prometheus metrics.
// Built with
GoDockerPterodactylnftables
// The problem
A CS2 install is 35 GB, so twenty servers on one node meant 700 GB of identical files, twenty SteamCMD runs after every Valve update and twenty downloads of the same workshop map, while the bash egg that handled it had grown to 9,700 lines that users edited and broke.
// Approach
- A static Go binary as the image entrypoint boots the server: configs, SteamCMD, addon updaters, cleanup, console filter and bot guard, with JSON config and real validation instead of a shell.
- An optional systemd daemon on the node shares one CS2 install, the workshop content and addon downloads between every server over a unix socket in each server's volume.
- Independent modules (VPK sync, nftables guard, workshop and addon cache, Discord alerts, crash bundles, backups, metrics, cleanup) switched on one by one.
// Engineering challenges
- Dropping bot floods in nftables before Docker's NAT, fed by the in-game bot detector and by traffic shape.
- Rolling a Valve update across the fleet from one shared install, restarting servers right away or once they are empty.
- Keeping every module isolated, so one that fails to start is logged and dropped while the rest keep running.