Dockerised Necesse dedicated server that always pulls the latest Steam release, keeps saves on the host, and exposes every server flag through environment variables. Published on Docker Hub as andreasgl4ser/necesse-server.
docker run -d \
--name necesse \
-p 14159:14159/udp \
-v $PWD/data:/home/necesse/.config/Necesse \
-e WORLD_NAME=MyWorld \
-e SERVER_PASSWORD=changeme \
-e SERVER_SLOTS=10 \
-e UPDATE_ON_START=true \
-e AUTO_UPDATE_INTERVAL_MINUTES=60 \
andreasgl4ser/necesse-server:latest- Replace
changemewith the password you want (leave blank to disable). - The bind mount stores saves, logs, and
cfg/server.cfgunder./data. - Forward UDP port
14159from your router/firewall to this host.
To follow a specific image, change the tag to e.g. :1.3.0.
docker-compose.yml:
services:
necesse:
image: andreasgl4ser/necesse-server:${IMAGE_TAG:-latest}
container_name: necesse
restart: unless-stopped
ports:
- "14159:14159/udp"
environment:
- SERVER_PORT=${SERVER_PORT:-14159}
- WORLD_NAME=${WORLD_NAME:-MyWorld}
- SERVER_PASSWORD=${SERVER_PASSWORD}
- SERVER_SLOTS=${SERVER_SLOTS}
- SERVER_OWNER=${SERVER_OWNER}
- SERVER_MOTD=${SERVER_MOTD}
- PAUSE_WHEN_EMPTY=${PAUSE_WHEN_EMPTY}
- GIVE_CLIENTS_POWER=${GIVE_CLIENTS_POWER}
- ENABLE_LOGGING=${ENABLE_LOGGING}
- ZIP_SAVES=${ZIP_SAVES}
- SERVER_LANGUAGE=${SERVER_LANGUAGE}
- SETTINGS_FILE=${SETTINGS_FILE}
- BIND_IP=${BIND_IP}
- MAX_CLIENT_LATENCY=${MAX_CLIENT_LATENCY}
- LOCAL_DIR=${LOCAL_DIR:-0}
- DATA_DIR=${DATA_DIR}
- LOGS_DIR=${LOGS_DIR}
- UPDATE_ON_START=${UPDATE_ON_START}
- AUTO_UPDATE_INTERVAL_MINUTES=${AUTO_UPDATE_INTERVAL_MINUTES:-0}
- JAVA_OPTS=${JAVA_OPTS}
- PUID=${PUID}
- PGID=${PGID}
volumes:
- ./data:/home/necesse/.config/Necesse.env (copy from .env.example and adjust):
WORLD_NAME=MyWorld
SERVER_PASSWORD=changeme
SERVER_SLOTS=10
SERVER_OWNER=AdminPlayer
SERVER_MOTD=Welcome to Necesse!
SERVER_PORT=14159
PUID=1000
PGID=1000
UPDATE_ON_START=true
AUTO_UPDATE_INTERVAL_MINUTES=60
IMAGE_TAG=latest
Start / update:
docker compose pull necesse # grab latest published image (optional if IMAGE_TAG pinned)
docker compose up -d # launch or restart the server
docker compose logs -f necesseSet IMAGE_TAG (env or .env) to pin a specific release; use latest (or leave it blank) to follow the newest published image. To build a custom image instead, run docker compose build necesse and Compose will reuse it.
The project ships with a ready-to-run docker-compose.yml and .env.example that mirrors the variables listed below—copy them locally and tweak as needed.
| Variable | Purpose |
|---|---|
WORLD_NAME |
World to load or create. |
SERVER_PASSWORD |
Join password; blank disables. |
SERVER_SLOTS |
Maximum concurrent players (1–250). |
SERVER_OWNER |
Owner player name (grants admin on join). |
SERVER_MOTD |
Message shown on join (\n for newline). |
SERVER_PORT |
UDP port inside the container (default 14159). |
PAUSE_WHEN_EMPTY |
1 pauses when empty, 0 keeps running. |
GIVE_CLIENTS_POWER |
1 smoother clients, 0 strict validation. |
ENABLE_LOGGING |
1 writes log files, 0 disables. |
ZIP_SAVES |
1 compresses saves, 0 stores plain folders. |
SERVER_LANGUAGE |
Language code for server messages (en, de, …). |
MAX_CLIENT_LATENCY |
Max seconds before kick (-maxlatency). |
SETTINGS_FILE |
Path to a custom server.cfg inside the container. |
BIND_IP |
Specific IP/interface for the server to bind. |
LOCAL_DIR |
1 appends -localdir flag for local storage. |
DATA_DIR, LOGS_DIR |
Override in-container paths (folders auto-created). |
UPDATE_ON_START |
true runs SteamCMD on every boot. |
AUTO_UPDATE_INTERVAL_MINUTES |
Background poll interval; container restarts when a new Steam build is detected (0 disables). |
JAVA_OPTS |
Extra JVM flags (e.g. -Xmx2G). |
PUID / PGID |
Host UID/GID to chown bind mounts (useful on rootless hosts). |
IMAGE_TAG |
Override image tag in Compose (default latest). |
- Saves live under
/home/necesse/.config/Necesse(mapped to./data). Back it up regularly before upgrades or migrations. - Set
PUID/PGIDto match the owner of the bind-mounted folder if your Docker daemon runs rootless or you need host-level permissions preserved. The entrypoint remaps thenecesseuser before launching the JVM. - Health check:
pgrep -f 'Server.jar'. Usedocker compose psordocker inspect --format '{{.State.Health.Status}}' necesseto verify. - Tail logs with
docker compose logs -f necesseor fromdata/logs/.
- Auto updates:
UPDATE_ON_START=trueruns SteamCMD each start. SettingAUTO_UPDATE_INTERVAL_MINUTES(e.g.60) enables continuous polling; the container stops, updates, and restarts itself when Steam publishes a new build. - SteamCMD errors: the container keeps the previous server build if SteamCMD fails; inspect
/home/necesse/Steam/logs/stderr.txt(or the custom user home) inside the container for details. - Players cannot join: confirm UDP port forwarding and public IP. Some port testers give false negatives—validate in-game if unsure.
- Config changes ignored: edit
.env, thendocker compose up -dto recreate with new flags. - Version mismatch errors: ensure both
UPDATE_ON_STARTand the interval watcher are enabled, or manually pull the latest image and restart.
Prefer to work from source, tweak the image, or contribute?
git clone git@github.com:andreas-glaser/necesse-docker-server.git
cd necesse-docker-server
cp .env.example .env
docker compose build necesse
docker compose up -d- Lint:
./.github/workflows/ci.ymlruns on PRs (shellcheck + docker build). - Release process:
- Update
CHANGELOG.mdand documentation. git tag -a vX.Y.Z -m "vX.Y.Z"and push with--follow-tags.- GitHub Actions publishes release archives and pushes Docker Hub tags (
latest,X.Y.Z).
- Update
Issues and pull requests welcome!
Released under the MIT License.
