All apps · 0 apps
Valheim
Docker app from Blairwin's Repository
Overview
Readme
View on GitHubValheim — dedicated server for Unraid
A Valheim dedicated server in a container. The game ships a native Linux server binary, so SteamCMD installs it and it runs directly — no Proton, no wine, no virtual display.
First boot downloads about 2GB and settles at about 2.1GB on disk. Generating a new world takes well under a minute.
The ports, the save layout, the shutdown behaviour and the startup numbers below were read off a real running server, and where that disagreed with the published advice this page says so. The rest — mods, crossplay's effect on them, and how memory behaves over weeks — comes from Iron Gate's own manual and from long-lived community servers, and is marked where it matters.
Get the image
docker run -d --name valheim \
-p 2456:2456/udp -p 2457:2457/udp -p 2458:2458/udp \
-e SERVER_NAME="My Server" \
-e WORLD_NAME="Dedicated" \
-e SRV_PWD="atleast5chars" \
-e UID=99 -e GID=100 \
--stop-timeout 150 \
-v /mnt/user/appdata/valheim:/serverdata/serverfiles \
-v /mnt/user/appdata/steamcmd:/serverdata/steamcmd \
ferment9348/valheim:latest
There is a docker-compose.yml beside this file you can paste instead. It uses
uid/gid 1000 for an ordinary Linux host; Unraid wants 99/100.
Install on Unraid
It is in Community Applications — search for Valheim. The template fills in sensible defaults. The one field you must supply is Server Password, unless you set Public to 0.
Then raise the container stop timeout. See Stopping safely — this matters more here than for most game servers.
The password rules
Three of them, and all three are enforced by the server itself by refusing to start. This container checks them before launching so you get a sentence saying which one you broke, instead of one terse line somewhere in the startup log.
- At least 5 characters.
- The password must not appear anywhere inside the server name. This is the
one that catches people. A server called
Jordan's Valheimwith the passwordvalheimwill not start, and nothing about the error makes that obvious. - A server with Public set to 1 must have a password. There is no such thing as a listed server that anyone can walk into. If you want no password, set Public to 0 and hand out the address instead.
The container's check for rule 2 is case-sensitive, because nothing documents whether the server's own check is. If your password appears in the name only when you ignore case, you get a note in the log rather than a refusal — if the server then declines to start anyway, that note is the thing to act on.
Ports
Three UDP ports, numbered from the game port:
| Port | What it is |
|---|---|
| 2456 | Game traffic |
| 2457 | Steam query — this is the one you type into Steam |
| 2458 | Forwarded on Iron Gate's advice; see below |
To add the server to your Steam favourites, use 2457, not 2456. Steam's View → Servers → Favourites → Add a server box wants the query port. Typing the game port there is the single most common reason someone cannot find their own server.
Reading the bound sockets out of a running container gave this:
- Crossplay off — the server binds 2456 and 2457.
- Crossplay on — the server binds 2457 only.
2458 was never seen bound in either mode, and Iron Gate's own manual — the PDF
that ships inside the server download — says plainly that "the default Port Range
that the Server uses is 2456-2457". The only thing that asks for 2458 is a
comment in the server's own start_server.sh. The template publishes it to match
that comment, since doing so costs nothing if the port is free, but on the
evidence you can remove the row.
Changing the port
The host port, the container port and Server Port must all be the same number. Set the game port to 2500 and you want 2500 in all three places, with the query port following at 2501.
On Unraid, replace the Game Port row instead of editing it
Unraid greys out the Container Port box for every port a template supplied, so you cannot simply type a new number into it. Replace the row instead:
- Click Remove on the Game Port row.
- Click Add another Path, Port, Variable, Label or Device.
- Choose Port, set Container Port and Host Port both to your number, and set Protocol to UDP.
- Do the same for the Query Port row, using your number plus 1.
- Set the Server Port variable to the same number.
- Apply.
A port entry you create yourself has no container port yet, so Unraid leaves it editable. This is all in the Unraid web UI — no terminal, and nothing to toggle in settings.
If a template update puts the stock row back
You will then have two entries: yours, which works, and the stock one, which nothing is listening on. Remove the stock one and Apply.
Crossplay changes which ports matter
With Crossplay set to true the server moves to the PlayFab backend. That means:
- It no longer binds the game port at all, and no port forwarding is needed — traffic is relayed.
- It is listed in the in-game Community servers list and not in the Steam server browser. That is expected, not a fault, and it is the thing people report as "my server disappeared".
- Console players can join. They cannot join a Steam-backend server.
- BepInEx mods are reported not to load under crossplay.
Iron Gate's own shipped start_server.sh passes -crossplay by default now, so
this is worth a thought rather than an assumption. The template ships with it
off, which keeps the familiar Steam server browser behaviour.
Configuration
There is no config file. Every setting is passed to the server as a launch flag, so changing a field and restarting takes effect immediately, and nothing you edit by hand is ever overwritten by this container.
Your world and the three permission lists live under one directory:
<appdata>/savedir/
adminlist.txt
bannedlist.txt
permittedlist.txt
worlds_local/
<World Name>/
_main.N.db2 the world
_main.N.fwl2 metadata and seed
_main.N.chunks chunk index
*.chunk terrain
_main.N.ok written last, marks the save complete
N counts up by one each time the server saves. The server writes _main.N.ok
last and only then removes the generation before it, which is what makes a
half-written save impossible to mistake for a finished one.
World modifiers
Valheim 1.0's world modifier system is exposed as three fields.
World Preset — one of normal, casual, easy, hard, hardcore,
immersive, hammer. Leave blank for normal.
World Modifiers — a comma-separated list of name=value:
| Name | Values |
|---|---|
combat |
veryeasy easy hard veryhard |
deathpenalty |
casual veryeasy easy hard hardcore |
resources |
muchless less more muchmore most |
raids |
none muchless less more muchmore |
portals |
casual hard veryhard |
For example: combat=hard,raids=none,portals=casual.
Each list leaves out its own normal setting on purpose — you name a modifier only to move it away from normal, and there is no spelling for "normal".
World Toggles — a comma-separated list of any of nobuildcost,
playerevents, passivemobs, nomap. Blank means all off.
A name or value that is not in these lists stops the container with a message listing what is valid. That is deliberate: the server's own response to a modifier it does not recognise is to ignore it silently, which would hand you a normal-difficulty world with nothing to explain why.
A preset resets every individual modifier it covers, so order matters. The container always emits the preset first and your individual modifiers after it, so your specific choices win and you cannot get the ordering wrong.
Admins, bans and the permitted list
Three plain text files in savedir, one ID per line. The server creates them
empty on first boot.
Use the ID exactly as the game shows it, and do not retype it. Iron Gate's
own manual calls it the Platform User ID, gives its shape as
[Platform]_[User ID], says it is case sensitive, and tells you to get it
either from the server log or from the in-game F2 panel. Copy it from one of
those two places verbatim.
What it is not is a bare SteamID64. That is what pre-1.0 guides tell you to use, and it is accepted into the file and then silently ignored — no error, no log line, you simply are not an admin. If admin commands do nothing, this is the first thing to check.
The prefix itself is worth not guessing at. The manual's example shape is
Steam_, while several projects shipped fixes after 1.0 for IDs arriving with a
V_ prefix instead. Whichever your copy of the game hands you is the right one —
this container passes the file through untouched and validates nothing, so the
value you paste is the value the server sees.
Assume a restart is needed after editing these. Sources disagree about whether the server re-reads them live, and being wrong in this direction costs you one restart.
permittedlist.txt is an allowlist and it locks out everyone not on it. Iron
Gate's own wording is that adding one person to the permitted list bans everyone
else. A single stray entry will shut out every other player, including you. Leave
it empty unless you specifically want a closed server.
Admins use the in-game F5 console for kick, ban and save. There is no
RCON and no remote console — see Stopping safely for why that
matters.
World Name is not a rename
World Name picks which world the server loads, and creates it if it does not exist. Changing it after first boot starts a new world. The old one stays on disk and setting the name back returns to it. Nothing is renamed and nothing is deleted.
Starting over with a fresh world
Either set World Name to something new, or stop the container and delete
savedir/worlds_local/<World Name>/. Take a copy first if there is any chance
you want it back.
Bringing an existing world in
Put it in savedir/worlds_local/. Not worlds/ — the dedicated server does
not read that directory at all, and if your world is not in worlds_local the
server will not complain. It will quietly generate a brand new world and start up
looking perfectly healthy. That is the usual story behind "my world disappeared".
This container warns in the log if it finds something world-shaped in worlds/.
If the world was last played before Valheim 1.0, copy it somewhere safe first. The first 1.0 load converts it to the new folder format, that conversion is one-way, it can take several minutes, and interrupting it corrupts the world. Back up before the first boot, not after — by the time the server is up, the one-way door has already closed.
Characters are stored on each player's own machine, never on the server, so worlds are the only thing there is to migrate.
Stopping safely
The shutdown save is the only save this container can ask for. Valheim has no RCON, no stdin console and no remote save command, so unlike most game servers there is no second mechanism and nothing to fall back on if the stop goes wrong.
Measured on a real server: a stop took 4.2 seconds end to end and the world was written. That was an empty, freshly generated world — a real one with explored terrain and buildings takes longer, and keeps growing.
The server also autosaves every 30 minutes by default, which you can shorten with Save Interval. An ungraceful kill costs you whatever happened since the last autosave.
Stop timeout
Two numbers, and both have to be right:
- Stop Timeout in this template — how long the container waits for the server to finish saving. Default 120.
- Unraid's own container stop timeout — set this to at least 150.
Docker's default grace period is 10 seconds. If you leave it there, Docker kills the server partway through its save no matter what Stop Timeout says, and on Unraid this is a single global setting rather than a per-container one. It is worth checking after an Unraid update.
If a stop ever hits the timeout, the log says so plainly and tells you to raise both numbers.
Backups
The server has its own backup system and the template exposes it: Backups to Keep, First Backup Interval and Later Backup Interval. Defaults are 4 backups, the first after 2 hours and the rest every 12.
These live beside the world in savedir/worlds_local, which means they protect
you from a corrupted save but not from losing that disk. Copy them somewhere else
for that. Do not point any backup tool into worlds_local — a backup that
lands inside the world directory ends up backing up the previous backups.
Memory
Budget about 3GB for an idle server and 6–8GB for a busy long-running world. Measured here: 1.4GB resident immediately after generating a world, with nobody connected.
Memory use grows over time. This is a known, long-reported trait of this server rather than anything about this container, and the usual answer is a scheduled nightly restart — Unraid can do that on a schedule. A restart is safe as long as the stop timeout is set correctly, because the stop saves the world.
Do not schedule a restart during a pre-1.0 world's first conversion. That takes minutes and interrupting it corrupts the world.
CPU matters more as clock speed than as core count; the server is largely single-threaded.
Mods
There is no mod installer here, and none is needed: the server directory is bind
mounted, so installing BepInEx is a matter of unzipping it next to
valheim_server.x86_64. Mods then go in BepInEx/plugins/.
Every client must run the same mods as the server. Mods are reported not to load at all when crossplay is on.
Editing files over SMB
UMASK defaults to 000 and Data Permissions to 775, which keeps the save
directory and the three permission lists editable over an Unraid share. Set UID
and GID to 99 and 100 so the files belong to nobody:users as the rest of Unraid
expects.
Troubleshooting
The container stops immediately and the log mentions the password. One of the three password rules. The log says which.
The container stops with a message about a modifier or preset. A typo in World Preset, World Modifiers or World Toggles. The message lists the valid values.
I cannot find my server in Steam. If Crossplay is on, that is expected — it is in the in-game Community servers list instead. If it is off, check you added the query port (game port plus 1) in Steam's Add a server box, not the game port.
My world is gone / it generated a new one. The world was probably in
worlds/ rather than worlds_local/, or World Name does not match the folder
name. Nothing is deleted by either mistake — stop the container, put the world in
savedir/worlds_local/, set World Name to match, and start it again.
Admin commands do nothing. The ID in adminlist.txt is almost certainly a
bare SteamID64. Use the V_-prefixed value from the in-game F2 panel and
restart.
Nobody can join, including me, and there is no error. Check
permittedlist.txt is empty. Anything in it locks out everyone else.
The server binary is missing after a SteamCMD run. Check free space on the
appdata path; the install needs about 2.1GB. Set Validate Files to true for
one start to have SteamCMD repair the install.
It lost time on a stop. The stop timeout. Raise both Stop Timeout and Unraid's own container stop timeout, as described above.
License
MIT — see LICENSE.
Install Valheim on Unraid in a few clicks.
Find Valheim in Community Apps on your Unraid server, review the template, and click Install. Unraid handles the Docker app or plugin setup from the published template.
Requirements
Categories
Download Statistics
Related apps
Explore more like this
Explore allDetails
ferment9348/valheim:latestRuntime arguments
- Network
bridge- Shell
bash- Privileged
- false
- Extra Params
--restart=unless-stopped
Template configuration
Game traffic, UDP, and the port to forward on your router. To move it you must set THREE things to the same number: this Host Port box, the Container Port behind the Edit button on this row, and Server Port below. Unraid greys out that Container Port box for every port a template supplied, so you cannot type your number into it. To move this port, Remove this entry and add your own Port entry with the Container Port and the Host Port both set to your number - a port entry you create yourself has no container port yet, and Unraid leaves those editable. Then move the Query and Crossplay rows to your number plus 1 and plus 2 the same way. A template update can restore these entries alongside yours; remove them again. See the README.
- Target
- 2456
- Default
- 2456
- Value
- 2456
Steam's server query port, always Game Port plus 1. This is the port you type into Steam's View, Servers, Favourites, Add a server box - NOT the game port. Getting that wrong is the single most common reason people cannot find their own server. Forward it alongside the game port.
- Target
- 2457
- Default
- 2457
- Value
- 2457
Always Game Port plus 2. The comment block in the server's own start script tells you to forward 2456-2458, so this row exists to match that advice - but the server was never actually seen listening on it, with crossplay on or off, when the ports were read straight out of the running container. Publishing it costs nothing if 2458 is free. Remove the row if you would rather not publish a port nothing has been observed binding.
- Target
- 2458
- Default
- 2458
- Value
- 2458
The port the server binds. It must equal Game Port above, BOTH the Host Port and the Container Port. The query and crossplay ports are derived from it by the game and cannot be set separately. Under Network Type host there is no mapping and this is the only port number there is.
- Target
- GAME_PORT
- Default
- 2456
- Value
- 2456
Where the server, worlds and permission lists live. About 2.1GB - see Requires below. Your worlds are under savedir/worlds_local, and adminlist.txt, bannedlist.txt and permittedlist.txt sit beside that folder in savedir.
- Target
- /serverdata/serverfiles
- Default
- /mnt/user/appdata/valheim
- Value
- /mnt/user/appdata/valheim
SteamCMD itself. Small, and shareable with other SteamCMD containers.
- Target
- /serverdata/steamcmd
- Default
- /mnt/user/appdata/steamcmd
- Value
- /mnt/user/appdata/steamcmd
Name shown in the server list. Applied on every restart. Note that the password below must not appear anywhere inside this name, or the server refuses to start.
- Target
- SERVER_NAME
- Default
- Valheim Server
- Value
- Valheim Server
Names the world the server creates on first boot, and the save it uses - savedir/worlds_local/name. Changing it after first boot starts a NEW world; the old one stays on disk and setting this name back returns to it. It does not rename anything.
- Target
- WORLD_NAME
- Default
- Dedicated
- Value
- Dedicated
REQUIRED unless Public is 0. Three rules, all enforced by the server by refusing to start: at least 5 characters; it must not appear anywhere inside the Server Name above; and a server listed in the browser must have one. This container checks all three before launching and tells you which one failed. Leave blank only with Public set to 0, which gives an unlisted server anyone who can reach the port may join.
- Target
- SRV_PWD
1 lists the server so players can find it by name; 0 hides it, and players join with the Join IP button instead. This is the only way to run without a password.
- Target
- PUBLIC
- Default
- 1
- Value
- 1
Set to true to run on the crossplay (PlayFab) backend instead of Steam. Crossplay is what lets Xbox, PlayStation and Switch players join at all, and it removes the need to forward any port because traffic is relayed. The costs: your server disappears from the Steam server browser and appears in the in-game Community servers list instead, players join with a code rather than by address, and BepInEx mods are reported not to load. A crossplay server also stops listening on the game port entirely - only the query port stays bound - which is the flip side of not needing to forward anything. Iron Gate's own shipped start_server.sh now passes this flag by default, so this setting is worth revisiting rather than assuming.
- Target
- CROSSPLAY
- Default
- false
- Value
- false
World modifier preset, new in Valheim 1.0. One of: normal, casual, easy, hard, hardcore, immersive, hammer. Leave blank for a normal world. A preset resets every individual modifier it covers, and this container always applies it before the fields below so they win.
- Target
- PRESET
Individual world modifiers as a comma separated list of name=value, for example: combat=hard,raids=none,portals=casual. Valid names and values - combat: veryeasy easy hard veryhard | deathpenalty: casual veryeasy easy hard hardcore | resources: muchless less more muchmore most | raids: none muchless less more muchmore | portals: casual hard veryhard. Each list leaves out its own normal setting on purpose: you name a modifier only to move it away from normal. A name or value that is not in these lists stops the container with a message, because the server would otherwise ignore it silently and hand you a normal world.
- Target
- MODIFIERS
World modifier switches, as a comma separated list. Any of: nobuildcost, playerevents, passivemobs, nomap. Leave blank for all off. For example nomap,passivemobs.
- Target
- SETKEYS
Seconds between automatic world saves. Blank uses the game's default of 1800, which is 30 minutes. Lowering it costs a brief pause more often and loses less when something goes wrong.
- Target
- SAVE_INTERVAL
How many of the server's own automatic backups to keep. Blank uses the game's default of 4, which the manual describes as one backup at the short interval and the rest at the long one - so by default one that is 2 hours old and three spaced 12 hours apart. These are the server's built-in backups and they live beside the world in savedir/worlds_local, so they are not protection against losing that disk - copy them elsewhere for that.
- Target
- BACKUP_COUNT
Seconds before the first automatic backup after a start. Blank uses the game's default of 7200, which is 2 hours.
- Target
- BACKUP_SHORT
Seconds between automatic backups after the first one. Blank uses the game's default of 43200, which is 12 hours.
- Target
- BACKUP_LONG
Appended to the launch line verbatim. Nothing routine needs this, since every documented setting already has a field above. Uses: -instanceid something, if you run several servers on one public address, and -logFile /path if you want the server's log written to a file as well.
- Target
- GAME_PARAMS_EXTRA
Set to true to have SteamCMD verify every file on the next start. Slow on a 2.1GB install. Use it after a crash or a failed update.
- Target
- VALIDATE
Seconds to wait for the server to save and exit before force killing it. This IS a save window, unlike some servers: Valheim saves when it is told to stop and has no RCON, no console and no remote save command, so this is the only save there is. Also raise Unraid's own container stop timeout to at least 150, or Docker kills the server partway through the save regardless of what you put here.
- Target
- STOP_TIMEOUT
- Default
- 120
- Value
- 120
Leave blank. The Valheim server downloads anonymously.
- Target
- USERNAME
Leave blank.
- Target
- PASSWRD
User ID. 99 is the Unraid default.
- Default
- 99
- Value
- 99
Group ID. 100 is the Unraid default.
- Default
- 100
- Value
- 100
Mode applied to the top of the server directory.
- Target
- DATA_PERM
- Default
- 775
- Value
- 775
umask for files the server creates. 000 keeps them editable over the share.
- Default
- 000
- Value
- 000