ODIN โ Valheim Server Manager
Odin is a modern Rust-powered CLI built for managing Dockerized Valheim dedicated servers with reliability, performance, and simplicity in mind. Designed around type-safe configuration, asynchronous mod downloads via the Thunderstore API, and structured error handling, it delivers a seamless server management experience through a single, dependency-free binary. From server lifecycle automation and BepInEx mod management to cross-platform world synchronization between Windows and Linux using rclone and Tailscale, Odin handles the infrastructure complexity so you can stay focused on the game.
Features
- ๐ Server Lifecycle โ start, stop, restart, update, and manage containers with a single command
- ๐งฉ Mod Management โ classify, download, and install mods from Thunderstore with automatic dependency resolution
- ๐ World Sync โ seamless cross-platform world synchronization between Windows and Linux via SSH/rclone
- ๐พ Automated Backups โ scheduled world snapshots with restore capabilities and manual backup support
- ๐ฉบ Health Diagnostics โ comprehensive system, Docker, and configuration validation before first use
- ๐ Monitoring & Logs โ real-time server status, log streaming, and interactive shell access
- ๐ ๏ธ DLL Patching โ apply and verify assembly patches with toggle control via environment variables
- โฐ Scheduled Tasks โ cron-based automation for updates, restarts, and backups
- ๐ BepInEx & Valheim+ โ full mod loader support with mutually exclusive configuration
- ๐ฎ Crossplay Support โ Xbox and Game Pass crossplay enablement
- ๐งช Type-Safe Config โ compile-time validated configuration with sensible defaults
- ๐ฆ Single Binary โ zero runtime dependencies beyond Docker and standard Unix tools
Table of contents
- Why Rust?
- Prerequisites
- Installation
- Configuration
- CLI commands
- Mod management
- World sync
- Build & test
- Project structure
- Best practices
- Troubleshooting
โก Why Rust?
Odin leverages Rust's unique strengths to deliver a production-grade server manager that's both reliable and performant:
-
Type safety โ compile-time guarantees eliminate entire classes of runtime errors. Odin's configuration system, API responses, and error handling are all type-checked at build time, preventing silent failures in production.
-
Fearless concurrency โ async/await with Tokio enables safe, efficient parallel operations. Odin downloads mods concurrently from Thunderstore, monitors server health, and syncs worlds across networks without race conditions or deadlocks.
-
Memory safety without garbage collection โ Rust's ownership model guarantees memory safety while keeping Odin lightweight and predictable. No GC pauses means reliable server management even under sustained load.
-
Performance โ zero-cost abstractions and minimal overhead. Odin runs as a single, lean binary that starts instantly and uses negligible CPU/memory, ideal for always-on server orchestration.
-
Single binary โ no runtime dependencies beyond Docker and standard Unix tools. Deploy Odin anywhere: bare metal, containers, or embedded systems. No Python, Node, or JVM required.
-
Rich ecosystem โ Tokio (async runtime), Reqwest (HTTP client), Serde (serialization), Clap (CLI parsing). Odin uses battle-tested libraries that handle complexity so you don't have to.
-
Excellent error handling โ Result types and the
?operator make error propagation explicit and ergonomic. Server management demands reliability; Odin's error handling is unambiguous and recoverable. -
Cross-platform compilation โ build once, run on Linux, macOS, or Windows. Odin's world sync bridges Windows and Linux seamlessly, powered by Rust's portable standard library.
๐ Prerequisites
System
| Requirement | Minimum | Notes |
|---|---|---|
| Linux kernel | 4.11+ | overlay2 support for Docker |
| CPU cores | 2 (4 recommended) | Valheim idle โ 1โ2 cores |
| RAM | 4 GB (8 GB recommended) | Valheim idle โ 2.8 GB |
| Free disk | 10 GB+ | ~1 GB Docker image + world saves |
Required binaries
| Binary | Purpose |
|---|---|
docker + compose v2 |
Container runtime |
7z |
Mod extraction, world backups |
zip |
Project snapshots |
rclone |
World sync (optional) |
tailscale |
VPN for sync (optional) |
Rust toolchain (build from source only)
|
๐ Installation
Option A โ cargo install (recommended)
&&
Option B โ Download binary from GitHub Releases
Download the pre-built binary for your platform from the Releases page, then:
Option C โ Build from source
&&
What odin init sets up
/srv/valheim/
โโโ docker-compose.yaml โ fetched from GitHub (latest)
โโโ odin โ binary
โโโ valheim.env โ generated from valheim.env.example + your answers
โโโ scripts/ โ fetched from GitHub (apply-patch.sh + any future scripts)
โโโ config/ โ created automatically on first start
โ โโโ backups/
โ โโโ worlds_local/
โ โโโ bepinex/plugins/
โโโ data/ โ created automatically (steamcmd + Valheim binaries)
โโโ mods_list.txt โ optional
odinlooks forvalheim.envnext to the binary, falling back to the working directory.
โ๏ธ Configuration (valheim.env) โ Environment variables
Copy valheim.env.example to valheim.env and edit it.
Core server settings
| Variable | Default | Description |
|---|---|---|
SERVER_NAME |
My Server |
Name in the Steam server browser |
WORLD_NAME |
Dedicated |
World save file name |
SERVER_PASS |
(empty) | Must be โฅ 5 characters |
SERVER_PUBLIC |
false |
List publicly on Steam |
TZ |
Etc/UTC |
Timezone for cron schedules |
โฐ Automatic scheduling
| Variable | Description |
|---|---|
UPDATE_CRON |
Auto-pull latest Docker image |
RESTART_CRON |
Auto-restart container |
BACKUPS_CRON |
Auto-backup world saves |
0 4 * * * โ Daily at 04:00
0 */6 * * * โ Every 6 hours
*/30 * * * * โ Every 30 minutes
Features
| Variable | Default | Description |
|---|---|---|
CROSSPLAY |
false |
Xbox/Game Pass crossplay |
SUPERVISOR_HTTP |
false |
Supervisor web UI on port 9001 |
BEPINEX |
false |
BepInEx mod loader |
VALHEIM_PLUS |
false |
Valheim+ (mutually exclusive with BepInEx) |
APPLY_DLL_PATCH |
false |
Enable/disable DLL patching โ the hook always runs, the script exits early when false |
PRE_SERVER_RUN_HOOK |
/scripts/apply-patch.sh |
Fixed hook โ do not change; controls patch execution via APPLY_DLL_PATCH |
PUID / PGID |
1000 |
UID/GID owning ./data and ./config |
Windows sync (optional)
| Variable | Description |
|---|---|
WIN_HOST |
Windows IP or hostname (Tailscale IP recommended) |
WIN_USER |
Windows account name |
WIN_SSH_USER |
SSH login on Windows |
WIN_SSH_PORT |
SSH port (default: 22) |
WIN_SSH_KEY |
Absolute path to SSH private key |
๐ป CLI commands
Run ./odin with no arguments to see the full command guide.
๐ Setup
Prompts for SERVER_NAME, WORLD_NAME, SERVER_PASS, TZ (auto-detected), and optional Windows sync config. Fetches docker-compose.yaml, valheim.env.example, and the full scripts/ directory from GitHub at runtime so you always get the latest defaults.
๐ฉบ Diagnostic
Server lifecycle
Monitoring
๐พ Backup & restore
Mod management
World sync
๐ฉน DLL Patch
APPLY_DLL_PATCHis the only toggle โ set it totrueorfalseinvalheim.env.Important Docker behaviour:
odin restartreuses the existing container environment. A change toAPPLY_DLL_PATCHinvalheim.envis only picked up after the container is recreated (down+start). Runodin apply-patchto do this automatically: it reads the current value fromvalheim.env, confirms with you, then runsdocker compose down+docker compose up -d.Once the fresh container starts,
PRE_SERVER_RUN_HOOK=/scripts/apply-patch.shruns before every Valheim startup and applies or skips the patch based onAPPLY_DLL_PATCH.Requires
./patches/assembly_valheim.dlland./scripts/apply-patch.sh(both mounted read-only indocker-compose.yaml).
Fixes
๐ฆ Mod management workflow
odin uses mods_list.txt as the source of truth.
# Format: Author-ModName-Version (version optional โ always fetches latest)
Azumatt-AzuAutoStore-1.2.3
ValheimModding-Jotunn-2.20.0
# SomeAuthor-ClientOnlyMod-1.0.0* โ * โ skip entirely
# SomeAuthor-ForceBothMod-1.0.0** โ ** โ force classify as "both"
Updating mods:
# edit mods_list.txt
&&
๐ World sync (Windows โ Linux)
Copies Valheim save files from Windows to the Linux server via rclone SFTP.
# On Windows: enable OpenSSH Server (Settings โ Apps โ Optional features)
# On Linux:
# In valheim.env:
WIN_HOST=100.x.x.x # Tailscale IP recommended
WIN_SSH_KEY=/home/youruser/.ssh/valheim_sync
&&
Sync aborts if Valheim.exe is running on Windows or players are connected.
๐จ Build & test
๐ Project structure
src/
โโโ main.rs โ entry point (env load, banner, dispatch)
โโโ cli.rs โ clap CLI (all commands)
โโโ config.rs โ AppConfig (valheim.env โ typed struct)
โโโ error.rs โ Error enum + Result alias
โโโ api/
โ โโโ thunderstore.rs โ Thunderstore REST API client
โโโ commands/
โ โโโ backups.rs โ clear-backups
โ โโโ docker.rs โ start / stop / restart / down / logs / update / shell
โ โโโ fix.rs โ fix permission
โ โโโ health.rs โ health diagnostic
โ โโโ init.rs โ init wizard (fetch config + scripts from GitHub)
โ โโโ mods.rs โ filter / download / install / clear mods
โ โโโ patch.rs โ apply-patch / verify-patch
โ โโโ status.rs โ status / status-password
โ โโโ worlds.rs โ restore-worlds / sync-worlds
โโโ utils/
โโโ banner.rs โ print_banner() / print_help()
โโโ display.rs โ info / ok / warn / err / confirm
โโโ fs.rs โ sudo_run / sudo_rm_rf / sudo_mkdir_p
โโโ net.rs โ internal_ips() / external_ip()
๐ฎ Best practices
- Run
odin healthbefore first use โ validates the full environment. - Set
SERVER_PASSto โฅ 5 characters or the server won't start. - Match
PUID/PGIDto the user owning./dataand./config(id -u && id -g). - Enable
BACKUPS_CRONfor automatic world snapshots; always backup beforeodin update. - Start with a small mod set (5โ10) to validate the pipeline before scaling up.
- Use a Tailscale IP for
WIN_HOSTโ encrypted, works across networks.
๐ง Troubleshooting
Docker daemon not running
&&
Permission errors on startup
SERVER_PASS too short โ must be โฅ 5 characters; update valheim.env then odin start.
ZFS โ steamcmd fails with "250 MB required"
odin health reports jq missing โ not required; all API calls are handled natively.
Mods not loading after install-mods โ confirm BEPINEX=true, check config/bepinex/plugins/ is non-empty, then odin restart.
sync-worlds SSH refused โ confirm OpenSSH Server is running on Windows and Tailscale is active on both machines.
DLL patch not taking effect after changing APPLY_DLL_PATCH โ odin restart does not re-read valheim.env. Run odin apply-patch to recreate the container with the new value. Use odin verify-patch to confirm.
License
MIT โ see LICENSE.