- Shell 52.9%
- Dockerfile 32%
- C 15.1%
| .gitignore | ||
| build-image.sh | ||
| docker-compose.example.yml | ||
| Dockerfile | ||
| entrypoint.sh | ||
| README.md | ||
| stationeers-ksm.sh | ||
| wine_ksm_interposer.c | ||
Stationeers Dedicated Server — Docker/Wine
This builds a complete, unmodified Stationeers Dedicated Server image from
an existing SteamCMD installation. It is for a normal Docker host, not
Pterodactyl. The game tree is one immutable image layer shared by every
container. Each server gets only its own persistent saves, mods,
scripts, settings and Wine prefix.
The image also installs the version-pinned official BepInEx 5.4.23.5 and
StationeersLaunchPad 1.1.0 Dedicated Server packages. Its configuration
and logs persist below server-01/bepinex/. The legacy StationeersMods
loader must not coexist with LaunchPad; the build stops if it finds it.
Build on the host
The SteamCMD installation must already be complete at /root/stationeers (or
pass its path as the first argument). This never sends Steam credentials or
downloads the game.
cd /root/KI/flixwolf/stationeers-docker
chmod +x build-image.sh stationeers-ksm.sh
./build-image.sh /root/stationeers
The build creates flixwolf/stationeers-dedicated:latest and the first
persistent state directory at runtime/server-01/.
Start one server
cp docker-compose.example.yml runtime/compose.yml
cd runtime
docker compose up -d
docker compose logs -f stationeers
Edit server-01/setting.xml while the container is stopped to set the name,
password, ports, visibility and world/server settings. UDP 32715 and
32716 are published by the sample compose file. Additional servers need
their own data directory, container name and two unique host UDP ports.
The container is non-root, has a read-only root filesystem, drops all Linux
capabilities, and persists no writable state outside ./server-01.
Measured resource profile
These measurements were taken on the Flixwolf host with fresh, comparable Wine-based dedicated-server instances after the Unity startup phase. They are planning figures, not hard limits: world complexity, player count, mods and the Wine/Unity version change the result.
| Configuration | Measured physical RAM (PSS) | Result |
|---|---|---|
| One normal instance, no KSM | about 4.35–4.55 GiB | Baseline after full startup |
| Two normal instances with KSM and the 8 MiB threshold | about 1.9 GiB shared in total | roughly 0.9–1.0 GiB saved per comparable additional instance |
| First-container observation during current startup | about 2.5 GiB container memory | transient; do not size capacity from this alone |
KSM becomes more effective as more near-identical servers run concurrently. It is a host-wide kernel feature, so enable it only after validating normal startup and mods. The 8 MiB marking threshold was the practical balance: a 2 MiB threshold added only about 74 MiB of extra merge candidates while roughly doubling the number of marked memory mappings.
There is deliberately no material disk-space reduction. The complete game tree remains in the shared immutable image so that future mods and updates stay compatible. The resulting image is about 7.0 GB; each extra server persists only its own saves, mods, settings, Wine prefix and BepInEx state.
Optional KSM sharing
The image includes the tested Wine mapping interposer. It remains off until
both host KSM is enabled and KSM_PRELOAD: "1" is set for that instance.
With two comparable fresh servers, the tested
8-MiB threshold saved about 1.9 GiB total physical memory. KSM is host-wide,
so validate one normal server first, then enable it deliberately:
sudo ./stationeers-ksm.sh status
sudo ./stationeers-ksm.sh enable
# Observe at least two matching server instances.
sudo ./stationeers-ksm.sh status
sudo ./stationeers-ksm.sh disable
disable actively unmerges pages and restores the scanner's former values.