Self-hosted Terraria dedicated server in Docker, powered by SteamCMD (AppID 105600).
335
A self-hosted Terraria dedicated server running in Docker, built on
cm2network/steamcmd:root. The container downloads and runs the official
TerrariaServer.bin.x86_64 Linux binary via SteamCMD, then launches it as a
non-root user.
docker compose, not the old
docker-compose).7777/TCP reachable from wherever your players connect from (open it
on your router/firewall and forward it to the machine running Docker if
needed). Terraria only needs TCP — no UDP.Option A — pull the pre-built image from Docker Hub (fastest):
docker pull ludix0/terraria:latest
Then create the two files below (docker-compose.yml and .env) yourself
in an empty folder, and skip straight to step 3.
Option B — clone from GitHub and build the image yourself:
git clone <URL-of-this-repository>
cd terraria
docker build -t ludix0/terraria:latest .
docker-compose.yml and .envCreate a docker-compose.yml like this:
services:
terraria:
image: ludix0/terraria:latest
container_name: terraria
restart: unless-stopped
volumes:
- ./filesServer:/home/steam/terraria_server
- ./saves:/home/steam/terraria_saves
- ./steamcmd:/home/steam/steamcmd
environment:
- TZ=${TZ}
- PUID=${PUID}
- PGID=${PGID}
- UPDATE_ON_START=${UPDATE_ON_START}
- STEAM_USER=${STEAM_USER}
- STEAM_PASSWORD=${STEAM_PASSWORD}
- SERVER_NAME=${SERVER_NAME}
- SERVER_PASSWORD=${SERVER_PASSWORD}
- MAX_PLAYERS=${MAX_PLAYERS}
- SECURE=${SECURE}
- MOTD=${MOTD}
- SERVER_LANG=${SERVER_LANG}
- NPC_STREAM=${NPC_STREAM}
- FORCE_PRIORITY=${FORCE_PRIORITY}
- DISABLE_ANNOUNCEMENT_BOX=${DISABLE_ANNOUNCEMENT_BOX}
- ANNOUNCEMENT_BOX_RANGE=${ANNOUNCEMENT_BOX_RANGE}
- SAVE_NAME=${SAVE_NAME}
- WORLD_SEED=${WORLD_SEED}
- WORLD_SIZE=${WORLD_SIZE}
- WORLD_DIFFICULTY=${WORLD_DIFFICULTY}
ports:
- "${HOST_PORT}:7777/tcp"
And a .env file next to it (never commit this file — it contains your
Steam password):
# --- System ---
TZ=Europe/Paris
PUID=1000
PGID=1000
# --- Steam account (mandatory — see "Why do I need a Steam account?") ---
STEAM_USER=your_steam_login
# If your password contains a literal "$", double it as "$$", otherwise
# Docker Compose tries to interpret it as a variable (e.g. "pa$$word" for
# "pa$word").
STEAM_PASSWORD=your_steam_password
# --- Updates ---
# true = check/download Terraria updates every container start
# false = keep whatever version is already installed (faster restart,
# no repeated Steam Guard prompts)
UPDATE_ON_START=false
# --- Server ---
SERVER_NAME=My_Terraria_Server
SERVER_PASSWORD=changeme
MAX_PLAYERS=8
SECURE=true
MOTD=
SERVER_LANG=en-US
NPC_STREAM=
FORCE_PRIORITY=
DISABLE_ANNOUNCEMENT_BOX=false
ANNOUNCEMENT_BOX_RANGE=
# --- World (only used the FIRST time the world file is created — see
# "World settings only apply once" below) ---
SAVE_NAME=world1
WORLD_SEED=
WORLD_SIZE=2
WORLD_DIFFICULTY=0
# --- Networking ---
# Host port to expose. Change only the left side if you want a different
# public port; the container always listens on 7777 internally.
HOST_PORT=7777
docker compose up -d
docker compose logs -f
First start will take a few minutes: SteamCMD needs to download the game
files. Watch the logs — if STEAM_USER has Steam Guard's mobile
authenticator enabled, confirm the login request in the Steam Mobile app
(check the "Confirmations" tab, not just push notifications) or the
approval email.
| Variable | Required | Default | Meaning |
|---|---|---|---|
TZ | recommended | — | Container timezone (e.g. Europe/Paris) |
PUID / PGID | recommended | 1000 | UID/GID the server runs as, matched to your host user so save files stay writable |
STEAM_USER / STEAM_PASSWORD | yes | — | A Steam account that owns Terraria (see below) |
UPDATE_ON_START | no | false | true = check for updates on every start, false = keep installed version |
SERVER_NAME | no | Ludix_Terraria_FR | Name shown in the server list / world name |
SERVER_PASSWORD | no | password | Password players must enter to join |
MAX_PLAYERS | no | 8 | Max simultaneous players (up to 255) |
SECURE | no | false | Enables Terraria's anti-cheat checks — recommended if the server is reachable from the internet |
MOTD | no | empty | Message shown to players on connect |
SERVER_LANG | no | fr-FR | en-US, fr-FR, de-DE, es-ES, ru-RU, zh-Hans, pt-BR, pl-PL, it-IT |
NPC_STREAM | no | game default | NPC network update rate |
FORCE_PRIORITY | no | system default | CPU priority: 0=Realtime … 5=Low |
DISABLE_ANNOUNCEMENT_BOX | no | false | Disables the in-game "Announcement" block |
ANNOUNCEMENT_BOX_RANGE | no | game default | Range in pixels (-1 = whole server) |
SAVE_NAME | no | world1 | World file name (without .wld) |
WORLD_SEED | no | random | World seed, or a special seed (for the worthy, celebrationmk10, not the bees, no traps, drunk, get fixed boi, constant) |
WORLD_SIZE | no | 3 | 1=small, 2=medium, 3=large |
WORLD_DIFFICULTY | no | 0 | 0=classic, 1=expert, 2=master, 3=journey |
Terraria is a paid game. SteamCMD's anonymous login (which works for many free-to-play dedicated servers) is not authorized for Terraria — you must log in with an account that genuinely owns it on Steam. Using a throwaway/shared account you don't want your primary credentials on is common practice; just make sure it actually owns a copy of Terraria.
Also note: Steam lists AppID 105610 ("Terraria - Dedicated Server") as the
"official" dedicated server listing, but it has been broken since the
Terraria 1.4 update — Re-Logic confirmed this on the Steam forums. This
image uses AppID 105600 (the base game) instead, whose Linux depot also
contains TerrariaServer.bin.x86_64.
SAVE_NAME, WORLD_SEED, WORLD_SIZE and WORLD_DIFFICULTY only affect
the world the first time it's created. Changing them later has no
effect on an existing world — delete the corresponding .wld file inside
your mounted saves folder if you want to regenerate a new world with
different settings.
restart: unless-stopped is set, the container will retry
in a loop and spam Steam Guard confirmation requests — Steam eventually
stops sending them (anti-abuse protection). If this happens:
docker compose down immediately to stop the spam.restart: "no" in
docker-compose.yml to limit retries to a single attempt instead of
looping forever, then switch back to unless-stopped once login
succeeds.WARN ... variable is not set or a broken container name: your
STEAM_PASSWORD likely contains a $ that isn't doubled to $$ in
.env.105600 and that STEAM_USER genuinely owns Terraria — see above.start_server.sh or Dockerfile? Rebuild the image:
docker build -t ludix0/terraria:latest .docker-compose.yml or .env? Just
docker compose up -d — no rebuild needed.Un serveur dédié Terraria auto-hébergé, tournant dans Docker, basé sur
cm2network/steamcmd:root. Le conteneur télécharge et exécute le binaire
Linux officiel TerrariaServer.bin.x86_64 via SteamCMD, puis le lance avec
un utilisateur non-root.
docker compose, pas l'ancien
docker-compose).7777/TCP accessible depuis là où vos joueurs se connectent
(ouvrez-le et redirigez-le vers la machine qui fait tourner Docker si
besoin). Terraria n'a besoin que du TCP — pas d'UDP.Option A — récupérer l'image déjà construite sur Docker Hub (le plus rapide) :
docker pull ludix0/terraria:latest
Créez ensuite vous-même les deux fichiers ci-dessous (docker-compose.yml
et .env) dans un dossier vide, puis passez directement à l'étape 3.
Option B — cloner depuis GitHub et construire l'image soi-même :
git clone <URL-de-ce-dépôt>
cd terraria
docker build -t ludix0/terraria:latest .
docker-compose.yml et .envCréez un docker-compose.yml de ce type :
services:
terraria:
image: ludix0/terraria:latest
container_name: terraria
restart: unless-stopped
volumes:
- ./filesServer:/home/steam/terraria_server
- ./saves:/home/steam/terraria_saves
- ./steamcmd:/home/steam/steamcmd
environment:
- TZ=${TZ}
- PUID=${PUID}
- PGID=${PGID}
- UPDATE_ON_START=${UPDATE_ON_START}
- STEAM_USER=${STEAM_USER}
- STEAM_PASSWORD=${STEAM_PASSWORD}
- SERVER_NAME=${SERVER_NAME}
- SERVER_PASSWORD=${SERVER_PASSWORD}
- MAX_PLAYERS=${MAX_PLAYERS}
- SECURE=${SECURE}
- MOTD=${MOTD}
- SERVER_LANG=${SERVER_LANG}
- NPC_STREAM=${NPC_STREAM}
- FORCE_PRIORITY=${FORCE_PRIORITY}
- DISABLE_ANNOUNCEMENT_BOX=${DISABLE_ANNOUNCEMENT_BOX}
- ANNOUNCEMENT_BOX_RANGE=${ANNOUNCEMENT_BOX_RANGE}
- SAVE_NAME=${SAVE_NAME}
- WORLD_SEED=${WORLD_SEED}
- WORLD_SIZE=${WORLD_SIZE}
- WORLD_DIFFICULTY=${WORLD_DIFFICULTY}
ports:
- "${HOST_PORT}:7777/tcp"
Et un fichier .env à côté (ne le mettez jamais dans un dépôt Git — il
contient votre mot de passe Steam) :
# --- Système ---
TZ=Europe/Paris
PUID=1000
PGID=1000
# --- Compte Steam (obligatoire — voir "Pourquoi un compte Steam ?") ---
STEAM_USER=votre_identifiant_steam
# Si votre mot de passe contient un "$", doublez-le en "$$", sinon Docker
# Compose essaie de l'interpréter comme une variable (ex: "pa$$word" pour
# "pa$word").
STEAM_PASSWORD=votre_mot_de_passe_steam
# --- Mises à jour ---
# true = vérifie/télécharge les mises à jour Terraria à chaque démarrage
# false = garde la version déjà installée (redémarrage plus rapide, pas de
# demande Steam Guard répétée)
UPDATE_ON_START=false
# --- Serveur ---
SERVER_NAME=Mon_Serveur_Terraria
SERVER_PASSWORD=changeme
MAX_PLAYERS=8
SECURE=true
MOTD=
SERVER_LANG=fr-FR
NPC_STREAM=
FORCE_PRIORITY=
DISABLE_ANNOUNCEMENT_BOX=false
ANNOUNCEMENT_BOX_RANGE=
# --- Monde (utilisé UNIQUEMENT à la première création du monde — voir
# "Les réglages du monde ne s'appliquent qu'une fois" ci-dessous) ---
SAVE_NAME=world1
WORLD_SEED=
WORLD_SIZE=2
WORLD_DIFFICULTY=0
# --- Réseau ---
# Port hôte exposé. Ne changez que le côté gauche pour un port public
# différent ; le conteneur écoute toujours en interne sur 7777.
HOST_PORT=7777
docker compose up -d
docker compose logs -f
Le premier démarrage prend quelques minutes : SteamCMD doit télécharger les
fichiers du jeu. Surveillez les logs — si STEAM_USER a l'authentification
mobile Steam Guard activée, confirmez la demande de connexion dans
l'application Steam Mobile (onglet "Confirmations", pas seulement les
notifications push) ou via l'email de validation.
| Variable | Obligatoire | Défaut | Signification |
|---|---|---|---|
TZ | recommandé | — | Fuseau horaire du conteneur (ex. Europe/Paris) |
PUID / PGID | recommandé | 1000 | UID/GID sous lequel tourne le serveur, à faire correspondre à votre utilisateur hôte pour que les sauvegardes restent modifiables |
STEAM_USER / STEAM_PASSWORD | oui | — | Un compte Steam qui possède Terraria (voir ci-dessous) |
UPDATE_ON_START | non | false | true = vérifie les mises à jour à chaque démarrage, false = garde la version installée |
SERVER_NAME | non | Ludix_Terraria_FR | Nom affiché dans la liste des serveurs / nom du monde |
SERVER_PASSWORD | non | password | Mot de passe demandé aux joueurs pour rejoindre |
MAX_PLAYERS | non | 8 | Nombre max de joueurs simultanés (jusqu'à 255) |
SECURE | non | false | Active les vérifications anti-triche de Terraria — recommandé si le serveur est accessible depuis internet |
MOTD | non | vide | Message affiché aux joueurs à la connexion |
SERVER_LANG | non | fr-FR | en-US, fr-FR, de-DE, es-ES, ru-RU, zh-Hans, pt-BR, pl-PL, it-IT |
NPC_STREAM | non | défaut du jeu | Fréquence de mise à jour réseau des PNJ/ennemis |
FORCE_PRIORITY | non | défaut système | Priorité CPU : 0=Temps réel … 5=Faible |
DISABLE_ANNOUNCEMENT_BOX | non | false | Désactive le bloc "Annonce" en jeu |
ANNOUNCEMENT_BOX_RANGE | non | défaut du jeu | Portée en pixels (-1 = tout le serveur) |
SAVE_NAME | non | world1 | Nom du fichier monde (sans .wld) |
WORLD_SEED | non | aléatoire | Seed du monde, ou une seed spéciale (for the worthy, celebrationmk10, not the bees, no traps, drunk, get fixed boi, constant) |
WORLD_SIZE | non | 3 | 1=petit, 2=moyen, 3=grand |
WORLD_DIFFICULTY | non | 0 | 0=classique, 1=expert, 2=maître, 3=voyage |
Terraria est un jeu payant. La connexion anonyme de SteamCMD (qui fonctionne pour beaucoup de serveurs dédiés de jeux free-to-play) n'est pas autorisée pour Terraria — il faut se connecter avec un compte qui le possède réellement sur Steam. Utiliser un compte secondaire/dédié (plutôt que votre compte principal) est une pratique courante ; assurez-vous simplement qu'il possède bien une copie de Terraria.
Autre point important : Steam liste l'AppID 105610 ("Terraria -
Dedicated Server") comme la fiche "officielle" du serveur dédié, mais
elle est cassée depuis la mise à jour Terraria 1.4 — confirmé par
Re-Logic sur les forums Steam. Cette image utilise donc l'AppID 105600
(le jeu de base), dont le dépôt Linux contient aussi
TerrariaServer.bin.x86_64.
SAVE_NAME, WORLD_SEED, WORLD_SIZE et WORLD_DIFFICULTY n'affectent
le monde qu'à sa toute première création. Les changer ensuite n'a
aucun effet sur un monde déjà créé — supprimez le fichier .wld
correspondant dans votre dossier saves monté si vous voulez régénérer un
nouveau monde avec de nouveaux réglages.
restart: unless-stopped est
actif, le conteneur va spammer des demandes de confirmation Steam Guard —
Steam finit par arrêter de les envoyer (protection anti-abus). Si ça
arrive :
docker compose down immédiatement pour arrêter le spam.restart: "no" dans
docker-compose.yml pour limiter les tentatives à un seul essai au
lieu d'une boucle infinie, puis remettez unless-stopped une fois la
connexion validée.WARN ... variable is not set ou un nom de conteneur cassé : votre
STEAM_PASSWORD contient probablement un $ non doublé en $$ dans
.env.105600 et que STEAM_USER possède réellement Terraria —
voir ci-dessus.start_server.sh ou Dockerfile ? Reconstruisez
l'image : docker build -t ludix0/terraria:latest .docker-compose.yml ou .env ? Un simple
docker compose up -d suffit — pas besoin de reconstruire.Content type
Image
Digest
sha256:b84a7f36e…
Size
135.5 MB
Last updated
7 days ago
docker pull ludix0/terraria