Valheim Dedicated Server built on Ubuntu 24.04 with Bepinex support.
1.6K
A Docker-based Valheim dedicated server on Ubuntu 24.04 with BepInEx mod support, automatic backups, scheduled restarts, and Thunderstore mod management.
modlinks.txt or remote Gist# Pull image
docker pull drummercraig/valheim-server:latest
# Create directory structure
mkdir -p valheim-server && cd valheim-server
# Download required files (option 1: all at once)
curl -L https://gist.github.com/drummercraig/0e1709e9775dd671593d8494c452497c/archive/1ce85ade66f0dc545fda1f9c868bd3c57a95d437.zip -o gist.zip \
&& unzip gist.zip && mv 0e1709e9775dd671593d8494c452497c-*/* . \
&& rm -rf gist.zip 0e1709e9775dd671593d8494c452497c-* && chmod +x *.sh
# Download required files (option 2: individual files)
curl -O https://gist.githubusercontent.com/drummercraig/0e1709e9775dd671593d8494c452497c/raw/docker-run.sh
curl -O https://gist.githubusercontent.com/drummercraig/0e1709e9775dd671593d8494c452497c/raw/valheim.env.example
curl -O https://gist.githubusercontent.com/drummercraig/0e1709e9775dd671593d8494c452497c/raw/modlinks.txt.example
chmod +x docker-run.sh
# Copy example files and configure
cp valheim.env.example valheim.env
cp modlinks.txt.example modlinks.txt
# Configure (edit SERVER_NAME, WORLD_NAME, SERVER_PASS, PUID, PGID)
nano valheim.env
# Configure mods (add Thunderstore URLs, one per line)
nano modlinks.txt # (or Gist configuration, see detailed instructions)
# Optional: Set custom container name (edit CONTAINER_NAME variable)
nano docker-run.sh
# Create directories and configuration files to prep adminlist.txt, modlinks.txt etc.
# (optional - auto-created on first start)
./docker-run.sh setup
# AzuAntiCheat (optional - if using this mod)
nano AzuAntiCheatWhitelist.txt # auto-created from modlinks.txt
nano AzuAntiCheatGreylist.txt # optional client mods
# Open firewall (Ubuntu/Debian)
sudo ufw allow 2456:2457/udp && sudo ufw allow 2456:2457/tcp
# Start server
./docker-run.sh
./docker-run.sh logs
./docker-run.sh # Start server
./docker-run.sh stop # Stop server
./docker-run.sh restart # Restart server
./docker-run.sh logs # View logs (Ctrl+C to exit)
./docker-run.sh status # Check if running
./docker-run.sh shell # Shell into container
./docker-run.sh mods # Run mod manager on host
./docker-run.sh setup # Create directories and files
Important: Always use ./docker-run.sh commands instead of direct docker commands (like docker restart). The script handles directory migrations, volume mounts, and configuration updates that won't apply if you restart the container directly.
valheim-server/
├── docker-run.sh # Server control script
├── valheim.env # Server configuration
├── modlinks.txt # Thunderstore mod URLs
├── AzuAntiCheatWhitelist.txt # Anticheat whitelist (auto-created)
├── AzuAntiCheatGreylist.txt # Anticheat greylist (auto-created)
├── valheim_data/ # Game files (managed by Steam)
├── valheim_config/
│ └── valheim/ # Valheim config directory
│ ├── worlds_local/ # World saves
│ ├── characters_local/ # Character saves
│ ├── adminlist.txt # Admin Steam IDs
│ ├── bannedlist.txt # Banned Steam IDs
│ └── permittedlist.txt # Permitted Steam IDs
├── valheim_config/bepinex/
│ ├── plugins/ # Mod DLLs
│ ├── config/ # Mod configs
│ └── patchers/ # Patcher mods
└── valheim_backups/ # World backups
| Variable | Default | Description |
|---|---|---|
SERVER_NAME | MyServer | Server browser name |
WORLD_NAME | Dedicated | World save name |
SERVER_PASS | secret | Join password (5+ chars) |
SERVER_PORT | 2456 | Server port |
SERVER_PUBLIC | false | List in public browser |
CROSSPLAY | false | Enable Xbox/PC crossplay |
PUID | 1000 | Container user ID |
PGID | 1000 | Container group ID |
ENABLE_BEPINEX | true | Enable mod loader |
UPDATE_MODS | true | Sync mods from modlinks.txt on start |
MODLINKS_URL | (empty) | Remote URL for mod list (replaces local modlinks.txt) |
WHITELIST_URL | (empty) | Remote URL for AzuAntiCheat whitelist |
GREYLIST_URL | (empty) | Remote URL for AzuAntiCheat greylist |
MOD_COMBAT | (empty) | Combat difficulty: veryeasy, easy, hard, veryhard |
MOD_DEATH_PENALTY | (empty) | Death penalty: casual, veryeasy, easy, hard, hardcore |
MOD_RESOURCES | (empty) | Resources: muchless, less, more, muchmore |
MOD_PORTALS | (empty) | Portals: casual, hard, veryhard |
MOD_RAIDS | (empty) | Raids: none, muchless, less, more, muchmore |
SETKEY_PLAYER_EVENTS | false | Scale raids with player count |
SETKEY_NO_MAP | false | Disable map/minimap |
SETKEY_NO_BUILD_COST | false | Free building |
SERVER_ARGS | (empty) | Additional server arguments |
AUTO_RESTART_ENABLED | true | Enable scheduled restart |
AUTO_RESTART_TIME | 05:00 | Restart time (24h format) |
IDLE_RESTART_ENABLED | false | Enable idle restart |
IDLE_RESTART_TIMEOUT | 1800 | Idle seconds before restart |
IDLE_RESTART_MIN_UPTIME | 1800 | Min uptime before idle restart |
BACKUP_ENABLED | true | Enable auto backups |
BACKUP_INTERVAL | 3600 | Backup interval (seconds) |
BACKUP_MAX_AGE | 3 | Days to keep backups |
BACKUP_HOST_PATH | (empty) | Custom backup destination path |
VALIDATE_GAME_FILES | true | Steam file validation on start |
FILTER_SHADER_WARNINGS | true | Filter Unity shader log warnings |
| Mode | Ports Required |
|---|---|
Standard (CROSSPLAY=false) | 2456-2457 UDP/TCP |
Crossplay (CROSSPLAY=true) | 2456-2458 UDP/TCP |
curl -fsSL https://get.docker.com | shOpen a terminal and create a folder for your server:
mkdir valheim-server
cd valheim-server
Download the required files from the configuration gist using the commands in the Quick Start section above.
Copy example files to create your configuration:
cp valheim.env.example valheim.env
cp modlinks.txt.example modlinks.txt
The server needs to run with correct file permissions. Find your user/group ID:
id
You'll see output like: uid=1000(yourname) gid=1000(yourname)
Note the numbers after uid= and gid=.
Open valheim.env in a text editor:
nano valheim.env
Required changes:
| Setting | What to Change |
|---|---|
SERVER_NAME | Your server's display name |
WORLD_NAME | Name for your world save file |
SERVER_PASS | Password to join (5+ characters, cannot contain server name) |
PUID | Your user ID from Step 3 |
PGID | Your group ID from Step 3 |
Save and exit (in nano: Ctrl+X, then Y, then Enter).
If you want mods, edit modlinks.txt:
nano modlinks.txt
Add Thunderstore URLs, one per line:
# Lines starting with # are comments
https://thunderstore.io/c/valheim/p/ValheimModding/Jotunn/
https://thunderstore.io/c/valheim/p/Azumatt/AzuAntiCheat/
The mod manager automatically downloads and installs these when the server starts.
UPDATE_MODS behavior (set in valheim.env):
UPDATE_MODS=true (default):
modlinks.txt on every server startmodlinks.txtvalheim_config/bepinex/config/ are preservedUPDATE_MODS=false:
modlinks.txt will NOT be deletedIf you're using the AzuAntiCheat mod, the mod manager automatically handles whitelist/greylist setup:
AzuAntiCheatWhitelist.txt - Mods clients MUST have (auto-created from modlinks.txt)AzuAntiCheatGreylist.txt - Mods clients MAY have (optional client-side mods)Both files use the same format as modlinks.txt (Thunderstore URLs, one per line).
To customize:
# Edit whitelist (required mods - defaults to your modlinks.txt)
nano AzuAntiCheatWhitelist.txt
# Edit greylist (optional client mods like UI improvements)
nano AzuAntiCheatGreylist.txt
The mod manager downloads these mods to valheim_config/bepinex/config/AzuAntiCheat_Whitelist/ and AzuAntiCheat_Greylist/ for the anticheat to verify.
Instead of using local files, you can fetch mod lists from remote URLs (e.g., GitHub Gists). This is useful for:
| Setting | Description |
|---|---|
MODLINKS_URL | URL to fetch mod list (replaces local modlinks.txt) |
WHITELIST_URL | URL to fetch AzuAntiCheat whitelist (replaces local AzuAntiCheatWhitelist.txt) |
GREYLIST_URL | URL to fetch AzuAntiCheat greylist (replaces local AzuAntiCheatGreylist.txt) |
Setting up a GitHub Gist:
modlinks.txt)valheim.envExample valheim.env configuration:
MODLINKS_URL=https://gist.githubusercontent.com/username/gistid/raw/modlinks.txt
WHITELIST_URL=https://gist.githubusercontent.com/username/gistid/raw/whitelist.txt
GREYLIST_URL=https://gist.githubusercontent.com/username/gistid/raw/greylist.txt
When a URL is set, the remote file takes priority over the local file. Leave the URL empty to use local files.
Note: After updating your gist, restart the server to fetch the new mod list: ./docker-run.sh restart
Players need to connect through your firewall.
Ubuntu/Debian (UFW):
sudo ufw allow 2456:2457/udp
sudo ufw allow 2456:2457/tcp
RHEL/CentOS/Fedora (firewalld):
sudo firewall-cmd --permanent --add-port=2456-2457/udp
sudo firewall-cmd --permanent --add-port=2456-2457/tcp
sudo firewall-cmd --reload
For crossplay, also open port 2458:
# UFW
sudo ufw allow 2458/udp && sudo ufw allow 2458/tcp
# firewalld
sudo firewall-cmd --permanent --add-port=2458/udp
sudo firewall-cmd --permanent --add-port=2458/tcp
sudo firewall-cmd --reload
./docker-run.sh
First startup takes 5-15 minutes as it:
modlinks.txtWatch progress with:
./docker-run.sh logs
Press Ctrl+C to stop watching (server keeps running).
Your server is ready when you see: Game server connected
YOUR-IP:2456
192.168.1.100:2456)| Setting | Default | Description |
|---|---|---|
SERVER_NAME | My Server | Name shown in server browser |
WORLD_NAME | Dedicated | World save file name |
SERVER_PASS | secret | Join password (5+ chars, cannot contain server name) |
SERVER_PORT | 2456 | Network port |
SERVER_PUBLIC | false | Appear in public server list |
CROSSPLAY | false | Enable Xbox/PC crossplay |
| Setting | Default | Description |
|---|---|---|
PUID | 1000 | User ID for file ownership |
PGID | 1000 | Group ID for file ownership |
| Setting | Default | Description |
|---|---|---|
ENABLE_BEPINEX | true | Enable BepInEx mod loader |
UPDATE_MODS | true | Sync mods from modlinks.txt on every start |
When UPDATE_MODS=true, mods are synced to match modlinks.txt on every server start:
modlinks.txt are deletedSimply edit modlinks.txt and restart the server to add, update, or remove mods.
Plugin config files in valheim_config/bepinex/config/ are preserved. Set UPDATE_MODS=false to keep existing plugins and only download missing mods (removed mods will not be deleted).
If using the AzuAntiCheat mod, these files control which mods clients can use:
| File | Purpose |
|---|---|
AzuAntiCheatWhitelist.txt | Required mods (auto-created from modlinks.txt) |
AzuAntiCheatGreylist.txt | Optional client mods (created empty) |
Both use Thunderstore URLs, one per line (same format as modlinks.txt).
| Setting | Options | Description |
|---|---|---|
MOD_COMBAT | veryeasy, easy, hard, veryhard | Enemy difficulty |
MOD_DEATH_PENALTY | casual, veryeasy, easy, hard, hardcore | Death penalty severity |
MOD_RESOURCES | muchless, less, more, muchmore | Resource multiplier |
MOD_PORTALS | casual, hard, veryhard | Portal restrictions |
MOD_RAIDS | none, muchless, less, more, muchmore | Raid frequency |
| Setting | Default | Description |
|---|---|---|
SETKEY_PLAYER_EVENTS | false | Scale raids with player count |
SETKEY_NO_MAP | false | Disable map/minimap |
SETKEY_NO_BUILD_COST | false | Free building |
Restarts the server at a specific time daily (when no players connected).
| Setting | Default | Description |
|---|---|---|
AUTO_RESTART_ENABLED | true | Enable scheduled restart |
AUTO_RESTART_TIME | 05:00 | Time to restart (24h format) |
Restarts the server after a period of inactivity.
| Setting | Default | Description |
|---|---|---|
IDLE_RESTART_ENABLED | true | Enable idle restart |
IDLE_RESTART_TIMEOUT | 1800 | Seconds with no players before restart |
IDLE_RESTART_MIN_UPTIME | 1800 | Minimum uptime before restart allowed |
| Setting | Default | Description |
|---|---|---|
BACKUP_ENABLED | true | Enable automatic backups |
BACKUP_INTERVAL | 3600 | Seconds between backups |
BACKUP_MAX_AGE | 3 | Days to keep backups |
BACKUP_HOST_PATH | (empty) | Custom backup path |
| Setting | Default | Description |
|---|---|---|
VALIDATE_GAME_FILES | false | Full Steam file validation on start |
SERVER_ARGS | (empty) | Additional server arguments |
The game updates automatically on restart:
./docker-run.sh restart
When UPDATE_MODS=true, mods are freshly downloaded on every server start (plugins/patchers directories are cleared first). To add or remove mods:
modlinks.txt (add or remove Thunderstore URLs)./docker-run.sh restartMods will automatically sync to match modlinks.txt on restart.
To manually run the mod manager without restarting:
./docker-run.sh mods
Backups are stored in valheim_backups/ with timestamps:
ls valheim_backups/
./docker-run.sh stop
cp -r valheim_backups/YYYYMMDD_HHMMSS/worlds_local/* valheim_config/valheim/worlds_local/
./docker-run.sh
Add Steam IDs (one per line) to valheim_config/valheim/adminlist.txt:
76561198012345678
76561198087654321
PUID and PGID match your id command outputsudo chown -R $(id -u):$(id -g) valheim_data valheim_config valheim_backups./docker-run.sh logsdocker pssudo lsof -i :2456./docker-run.sh statusVerify ENABLE_BEPINEX=true in valheim.env
Check mod URLs are valid Thunderstore links
Review logs for errors: ./docker-run.sh logs
Ensure mods are compatible with current Valheim version
Content type
Image
Digest
sha256:c04968bae…
Size
88.1 MB
Last updated
7 months ago
docker pull drummercraig/valheim-server