Terraria dedicated server for Unraid — native Linux, no Proton
897
A native-Linux Terraria dedicated server. The server is a small checksummed download from terraria.org, and a world generates in seconds on first boot.
Built for Unraid, but it is an ordinary container and runs anywhere.
docker run -d --name terraria \
-p 7777:7777/tcp \
-e WORLD_NAME="World" \
-e MAX_PLAYERS=8 \
-v /path/to/serverfiles:/serverdata/serverfiles \
ferment9348/terraria:latest
Or with compose:
services:
terraria:
image: ferment9348/terraria:latest
restart: unless-stopped
ports:
- "7777:7777/tcp"
environment:
WORLD_NAME: "World"
MAX_PLAYERS: "8"
volumes:
- ./data/terraria:/serverdata/serverfiles
| Port | Proto | Purpose |
|---|---|---|
| 7777 | TCP | Game traffic, the only port to forward. |
Terraria uses TCP on 7777, not UDP. A UDP service on the same number is a different port as far as the network stack is concerned, so the two never collide.
To run on a different port, change it in three places to the same number — both
sides of -p and GAME_PORT:
-p 7779:7779/tcp -e GAME_PORT=7779
Docker gives the container no way to discover which host port it was published
on, so the server can only report the number it binds; keeping the three equal
is what makes the startup log and Terraria's own Listening on port name the
port players type. -p 7779:7777 alone works but logs 7777, and a GAME_PORT
that disagrees with the container side of -p leaves nothing behind the mapping
and no error in the log.
On Unraid, the Container Port box of every port a template supplied is greyed out, so your number will not go in it. Remove the Game Port entry and add your own Port entry with both sides set to your number — an entry you create yourself stays editable. The README has the steps.
| Variable | Default | Notes |
|---|---|---|
WORLD_NAME | World | Picks which world file loads. A new name generates a NEW world; it never renames one. |
WORLD_SIZE | 2 | 1 small, 2 medium, 3 large. Only used the first time a world generates. |
DIFFICULTY | 0 | 0 classic, 1 expert, 2 master, 3 journey. First generation only. |
MAX_PLAYERS | 8 | Applied on every restart. |
SRV_PWD | empty | Join password. Blank for an open server. |
TERRARIA_VERSION | 1458 | Server build to install. Change with TERRARIA_SHA256, see below. |
TERRARIA_SHA256 | pinned | Checksum of the build above. Must match, or the container refuses to install anything. |
STOP_TIMEOUT | 6 | Seconds for a save-and-exit before force kill. |
UID / GID | 99 / 100 | Unraid defaults. |
Full list in the README.
Change the version and checksum together. TERRARIA_VERSION and
TERRARIA_SHA256 are a pair. Bump one without the other and the checksum
check fails before anything is unpacked — the container logs the mismatch and
exits rather than running an unverified binary.
Settings reapply on every restart, except World Name, which points at a different world file rather than renaming the current one. The log lists the worlds it finds on disk whenever the name you set does not match one of them.
Send console commands with docker exec — there is no RCON:
docker exec terraria /opt/scripts/console.sh say hello
Worldgen and save progress are collapsed in the log, on purpose. Terraria prints a line per 0.1% of every generation phase — tens of thousands of lines for one world — which can outrun a log driver badly enough to look like a hung server. Everything else, including chat and joins/leaves, passes through untouched.
The server saves on stop. docker stop tells Terraria to save and exit,
then waits up to STOP_TIMEOUT (default 6s) before force-killing — chosen to
finish inside Docker's own 10s stop grace, so the default container stop
timeout is fine as-is.
Content type
Image
Digest
sha256:d0f34d0bb…
Size
55.2 MB
Last updated
22 days ago
docker pull ferment9348/terraria