Docker image and Compose stack for a Vintage Story dedicated server. Targets linux/amd64 and linux/arm64.
SmelterWorks is not affiliated with Anego Studios. The server binaries come from the official CDN. Arm64 replaces native binaries with the experimental overlay from anegostudios/VintagestoryServerArm64. Harmony-using coded mods need that overlay line (1.21+).
- Docker Engine with Compose v2 and Buildx
- Open TCP and UDP
42420on the host firewall (wiki) - About 1 GB RAM base plus roughly 300 MB per concurrent player (wiki hardware notes)
Default image pins Vintage Story 1.22.6 (sha256-verified download) on .NET 10.
Published image: ghcr.io/smelterworks/vs-dockerized-server.
Compose (build from this repo):
cp .env.example .env
mkdir -p mods backups
docker compose build
docker compose up -d
docker compose attach vintagestorydocker run (pull the published image):
mkdir -p mods backups
docker run -d --name vintagestory \
--security-opt no-new-privileges:true \
-p 42420:42420/tcp -p 42420:42420/udp \
-v vs-data:/data \
-v "$(pwd)/mods:/mods:ro" \
-v "$(pwd)/backups:/backups" \
--restart unless-stopped \
ghcr.io/smelterworks/vs-dockerized-server:latest
docker attach vintagestoryAttach gives you the server console. Detach with Ctrl-p Ctrl-q. Stop with /stop in the console, or docker compose stop / docker stop vintagestory.
Drop .zip or unpacked mods into ./mods. The container loads them with --addModPath /mods (startup parameters). The bind mount is read-only.
World data, player data, and serverconfig.json live in the vs-data volume at /data.
Timed tar snapshots of Saves, Playerdata, Mods, and serverconfig.json land in ./backups. Interval and retention are set in .env. A shutdown backup runs by default.
Manual run:
docker compose --profile tools run --rm backupThese are best-effort copies while the process is live. Use in-game /genbackup when you need a consistent world dump.
Edit /data/serverconfig.json after the first start (stop the container first), or pass overrides with VS_EXTRA_ARGS / --withconfig as documented on the startup parameters page.
Common .env knobs: VS_PORT, VS_MAX_CLIENTS, VS_CPUS, VS_MEM_LIMIT, backup flags.
Compose defaults: read-only rootfs, cap_drop: ALL plus the few caps needed for the root-to-65532 drop, no-new-privileges, resource limits, TCP healthcheck on 42420, stop_grace_period: 90s.
docker buildx build --platform linux/amd64,linux/arm64 -t ghcr.io/smelterworks/vs-dockerized-server:dev --load .--load only works for a single platform. For both arches, push to a registry or use --push.
Bump VS_VERSION / VS_SHA256 (and the arm overlay args) in the Dockerfile when you change game version. Digests for base images are pinned on the latest tags.
.github/workflows/docker.yml builds an amd64 image, scans OS packages with a pinned Trivy binary (sha256-verified download), runs scripts/ci-smoke.sh (start, healthcheck, uid 65532, backup, stop), then publishes multi-arch images to GHCR on main and v* tags. Publish waits on smoke. After publish, .github/workflows/reusable-badges.yml updates shields.io endpoint JSON under .github/badges/ (image size, publish date, Vintage Story version). Actions are SHA-pinned. CodeQL scans Actions workflows. Dependabot watches Actions and Docker base images weekly. Patterns follow GitHub Actions secure use.