RE:NODE

Dedikovaný Valheim server v Dockeru (lloesche/valheim-server)

Text: Tým RE:NODE
11 min čtení


Nejsnazší způsob, jak provozovat Valheim v Dockeru, je komunitní image lloesche/valheim-server (publikovaný v registru GitHubu jako ghcr.io/lloesche/valheim-server). Při prvním startu stáhne server přes SteamCMD, běží pod supervizorem, který navíc každých patnáct minut hledá aktualizace a každou hodinu vytvoří zazipovanou zálohu, a nastavuje se celý přes proměnné prostředí: SERVER_NAME, WORLD_NAME, SERVER_PASS, plus SERVER_ARGS pro cokoli dalšího, například -crossplay. Připojíš dva svazky - /config pro světy, zálohy a soubory seznamů, /opt/valheim pro instalaci serveru - namapuješ UDP 2456-2457, nastavíš lhůtu pro zastavení na pár minut a chová se slušně. Výchozí hodnoty jsou rozumné pro vanilla server; dvě, které bys na modovaném měl změnit, jsou plán aktualizací a, pokud ti záleží na místu na disku, doba uchování záloh.

Článek předpokládá, že Docker a Compose na stroji už fungují. Pokud ne, dostane tě tam Docker na VDS. Instalaci bez kontejneru najdeš v článku Valheim na Linuxu přes SteamCMD.

Proč vůbec provozovat Valheim v kontejneru#

Nativní instalace s jednotkou systemd je naprosto v pořádku, takže si kontejner musí své místo zasloužit. Co dává:

  • Nic nainstalovaného na hostiteli kromě Dockeru. Žádná architektura i386, žádný balíček SteamCMD, žádné knihovny pro crossplay. Přestavba stroje je „nainstaluj Docker, obnov dvě složky, docker compose up -d“.
  • Aktualizace, restarty a zálohy už naplánované, s kontrolou nečinnosti, takže nic z toho nepřeruší hráče. Na nativní instalaci bys ty úlohy psal sám.
  • Čisté oddělení, když na stejném stroji běží i jiné věci - Discord bot, druhý herní server, web. Každé žije ve vlastním kontejneru se svými porty a soubory.

Co to stojí: o jednu vrstvu víc k ladění, logy, které procházejí supervizorem místo přímo ze serveru, a závislost na image udržovaném komunitou. Image je široce používaný a aktivně udržovaný, ale není to produkt Iron Gate; když se něco změní, čti jeho README, protože autoritou pro jeho proměnné je README, ne tento článek. Názvy proměnných a výchozí hodnoty níže jsou ty, které README v době psaní dokumentuje.

Soubor compose#

Soubor docker-compose.yml s nastaveními, na kterých záleží:

docker-compose.yml
services:  valheim:    image: ghcr.io/lloesche/valheim-server    container_name: valheim    cap_add:      - sys_nice    volumes:      - ./config:/config      - ./data:/opt/valheim    ports:      - "2456-2457:2456-2457/udp"    env_file:      - ./valheim.env    restart: unless-stopped    stop_grace_period: 2m
valheim.env
SERVER_NAME=Longship CrewWORLD_NAME=MidgardSERVER_PASS=herring-barrel-42SERVER_PUBLIC=trueTZ=Europe/Berlin
bash
$ mkdir -p ~/valheim && cd ~/valheim$ docker compose up -d$ docker compose logs -f

První start trvá několik minut: kontejner spustí SteamCMD, stáhne server do ./data, pak ho nastartuje a vygeneruje svět. Než se zkusíš připojit, počkej na stejné řádky logu, které vypisuje nativní server - Load world: Midgard a Game server connected.

Tři řádky v souboru compose si zaslouží poznámku:

  • stop_grace_period: 2m dává serveru čas na uložení. Při docker compose down nebo docker stop pošle Docker signál k zastavení, supervizor předá Valheimu čisté ukončení a svět se zapíše. Výchozí lhůta Dockeru je 10 sekund, poté pošle SIGKILL - a velký svět, který se nestihl uložit, přijde o všechno od posledního uložení. Tohle je nejdůležitější řádek v souboru. U docker run je ekvivalentem --stop-timeout 120.
  • cap_add: sys_nice umožní serveru zvýšit si prioritu vlastního procesu, což README doporučuje. Když ho vynecháš, nic se nestane; přijdeš o malou výhodu plánování pod zátěží.
  • restart: unless-stopped vrátí kontejner po restartu nebo pádu, ale ne poté, co jsi ho zastavil schválně.

Soubor s proměnnými drží heslo mimo compose soubor, takže compose soubor můžeš sdílet nebo commitovat, aniž by heslo uniklo. valheim.env nech čitelný jen pro sebe.

Proměnné prostředí, na kterých záleží#

Image má desítky proměnných. Tyhle nastavuje většina serverů nebo by o nich měla vědět:

ProměnnáVýchozíCo dělá
SERVER_NAMEMy ServerNázev v seznamu serverů
SERVER_PORT2456Herní port; server používá i další port nahoru
WORLD_NAMEDedicatedSoubor světa k načtení nebo vytvoření
SERVER_PASSsecretHeslo pro připojení, minimálně 5 znaků
SERVER_PUBLICtrueZobrazit v prohlížeči komunitních serverů
SERVER_ARGSprázdnéDalší argumenty spuštění, předané beze změny
ADMINLIST_IDSprázdnéID oddělená mezerou zapsaná do adminlist.txt
BANNEDLIST_IDSprázdnéID zapsaná do bannedlist.txt
PERMITTEDLIST_IDSprázdnéID zapsaná do permittedlist.txt
TZEtc/UTCČasové pásmo, ve kterém běží plány cronu
PUID / PGID0Uživatel a skupina vlastnící soubory

SERVER_ARGS je místo pro všechno, co nemá vlastní proměnnou - crossplay, modifikátory světa, kratší interval ukládání:

env
SERVER_ARGS=-crossplay -saveinterval 900 -preset casual -modifier portals casual

Neopakuj -name, -world, -password ani -port v SERVER_ARGS; image je už skládá z vyhrazených proměnných a duplicity dávají matoucí výsledky. Každý argument i jeho úskalí jsou v přehledu argumentů Valheim serveru.

Proměnné se seznamy jsou pohodlné, ale mají ostrou hranu: při startu je image zapisuje do souborů seznamů, takže ID, které ručně přidáš do adminlist.txt a zapomeneš dát do ADMINLIST_IDS, nemusí další restart přežít. Vyber si jednu metodu a drž se jí. Formáty ID, včetně prefixů platforem, které crossplay potřebuje, jsou v průvodci soubory seznamů Valheimu.

PUID a PGID určují, komu patří soubory ve svazcích. Při výchozí hodnotě 0 patří na hostiteli rootovi, což ztěžuje jejich úpravu přes SFTP jako běžný uživatel. Pokud budeš soubory na hostiteli upravovat, nastav obě na ID svého uživatele (id -u a id -g) před prvním startem.

Svazky: kde svět doopravdy žije#

Cesta v kontejneruSložka na hostiteli výšeObsah
/config./configworlds_local/, backups/, adminlist.txt a spol., konfigurace BepInEx
/opt/valheim./dataInstalace serveru a instalace BepInEx

/config je ten, který musíš chránit. Je to ekvivalent adresáře s uloženými daty na nativní instalaci: světy v /config/worlds_local, zálohy image v /config/backups, tři soubory seznamů na nejvyšší úrovni. /opt/valheim se dá zahodit; je-li prázdný, kontejner si server při dalším startu stáhne znovu. Namapovat ho se přesto vyplatí, aby se při každé přestavbě kontejneru nestahoval znovu gigabajt či dva.

Pro přesun existujícího světa zastav kontejner, zkopíruj Midgard.db a Midgard.fwl do ./config/worlds_local/, nastav WORLD_NAME=Midgard - přesně včetně velkých písmen - a spusť ho. Pokud log říká, že svět generuje místo načtení, název nesedí. Celý postup, včetně světů ze Steam Cloud, je v článku nahrání lokálního světa Valheimu.

Pro /config používej bind mounty (složky na hostiteli), ne pojmenované svazky. Soubory uvidíš, zkopíruješ obyčejnými nástroji a zazálohuješ je bez zásahu Dockeru.

Aktualizace a restarty podle plánu#

Image spouští kontrolu aktualizací podle cronu uvnitř kontejneru:

ProměnnáVýchozíVýznam
UPDATE_CRON*/15 * * * *Každých 15 minut zkontroluj ve SteamCMD nový build serveru
UPDATE_IF_IDLEtrueAktualizaci aplikuj jen tehdy, když není připojený žádný hráč
RESTART_CRON0 5 * * *Denní restart v 05:00 v TZ
RESTART_IF_IDLEtrueRestart přeskoč, pokud jsou na serveru hráči
STEAMCMD_ARGSvalidateDalší argumenty pro aktualizaci přes SteamCMD

Když kontrola najde nový build a nikdo nehraje, image server čistě zastaví, aktualizuje a znovu spustí. Pro vanilla partu je to přesně správně: po patchi Valheimu je server obvykle aktuální dřív, než si kdokoli stihne aktualizovat vlastní hru.

Pro modovaný server je to přesně špatně. Patch Valheimu rozbije mody BepInEx, dokud je autoři neaktualizují, a image, který se aktualizuje ve chvíli, kdy je server prázdný, ti ráno po dni patche podstrčí rozbitý server. Vypni to nastavením UPDATE_CRON na prázdnou hodnotu a aktualizuj záměrně, až budou mody připravené: zazálohuj, pak docker compose restart - image při startu kontroluje aktualizace - a otestuj. Načasování popisuje aktualizace Valheim serveru.

Denní restart si nech. Dlouho běžící svět roste v paměti a restart v hodinu, kdy nikdo nehraje, ji udržuje na stejné úrovni. Pokud tvoje parta hraje v 05:00 místního času, posuň ho a ujisti se, že je nastavené TZ, jinak plán běží v UTC.

Zálohy uvnitř kontejneru i mimo něj#

Image vytváří vlastní zálohy, oddělené od vestavěné rotace -backups ve Valheimu:

ProměnnáVýchozíVýznam
BACKUPStrueZapnout úlohu záloh
BACKUPS_CRON5 * * * *Každou hodinu, v pět minut po
BACKUPS_DIRECTORY/config/backupsKam archivy putují
BACKUPS_MAX_AGE3Smaž archivy starší než tolik dní
BACKUPS_MAX_COUNT0Uchovej nejvýš tolik (0 znamená bez limitu počtu)
BACKUPS_IF_IDLEtrueZálohuj dál, i když je server prázdný
BACKUPS_IDLE_GRACE_PERIOD3600Sekundy po odchodu posledního hráče, než záloha při nečinnosti přestane
BACKUPS_ZIPtrueKomprimovat archivy

Každou hodinu, uchovávané tři dny, je rozumná výchozí hodnota: 72 snímků světa, který komprimovaný málokdy přesáhne 100 MB. Zálohy se berou ze souborů na disku, takže obsahují svět k poslednímu uložení, ne poslední minutu hry; kratší -saveinterval v SERVER_ARGS je udělá čerstvější.

Slabinou je umístění. /config/backups leží na stejném disku jako svět, který chrání. Mrtvý disk, smazaná složka nebo napadený hostitel vezme obojí. Archivy kopíruj mimo stroj - na jiný server, do objektového úložiště přes rclone nebo AWS CLI, kamkoli jinam - podle vlastního plánu. Image nabízí POST_BACKUP_HOOK, příkaz, který spustí po každém archivu s cestou k souboru dosazenou za @BACKUP_FILE@, což je pěkné místo pro zavěšení nahrávání. Zálohy herních serverů do S3 ukazují stranu nahrávání a zálohy Valheim serveru a poškození světa pokrývají obnovu i rozpoznání poškozeného světa.

Pro obnovu zastav kontejner, rozbal vybraný archiv do ./config/worlds_local/ přes aktuální dvojici .db a .fwl (aktuální dvojici si předtím zkopíruj) a kontejner spusť.

BepInEx a mody v kontejneru#

Nastav BEPINEX=true a image při startu stáhne BepInExPack pro Valheim a server spustí přes něj. Soubory .dll modů pak patří do složky plugins pod /config/bepinex/ v aktuálních verzích image - pokud složka není tam, kde ji čekáš, ověř přesnou cestu v README - a jejich konfigurační soubory se objeví pod /config/bepinex/config po prvním startu s načteným modem. Po přidání nebo odebrání modu kontejner restartuj.

valheim.env (modded)
BEPINEX=trueUPDATE_CRON=

Existuje také VALHEIM_PLUS=true, které místo toho nainstaluje Valheim Plus. Původní projekt Valheim Plus už dlouho nestíhá hru a většina part dnes používá udržované forky nebo jednotlivé mody; nezapínej ho, pokud nevíš, že verze, kterou dostaneš, funguje se současnou hrou. Nikdy nezapínej obojí.

Všechno ostatní o modech je stejné jako na nativním serveru: mody měnící pravidla hry musí být nainstalované ve stejné verzi u každého klienta, hráči z Xboxu se nemohou připojit k serveru, který vyžaduje klientské mody, a mody postavené na Jotunn vykopnou každého, jehož verze nesedí. Mody Valheimu s BepInEx na serveru popisují, které mody patří kam, a vykopnutí kvůli neshodě verzí modů nejčastější selhání.

Řešení potíží s kontejnerem#

Kontejner naběhne, ale nikdo se nemůže připojit. Mapování portů potřebuje /udp; "2456-2457:2456-2457" bez něj mapuje TCP a Valheim nedostane nic. Pak zkontroluj firewall hostitele - Docker vkládá vlastní pravidla iptables, ale firewall cloudového poskytovatele stále potřebuje otevřené UDP 2456-2457. Porty Valheimu vysvětlené mají úplný seznam.

Svět se při každém znovuvytvoření resetuje. /config není namapovaný, nebo je namapovaný na jinou složku než minule. docker compose down následované up zničí kontejner, ale nikdy složku připojenou přes bind mount.

Ztracený postup po `docker compose down`. Lhůta byla příliš krátká a server byl zabit uprostřed ukládání. Nastav stop_grace_period: 2m a při dalším zastavení sleduj v logu dokončení uložení.

Restarty kvůli nedostatku paměti. Kontejner s limitem paměti, který svět přeroste, je zabit bez uložení. Limit buď zvyš, nebo odstraň; kolik RAM potřebuje Valheim server obsahuje reálná čísla.

Soubory v `./config` patří rootovi. PUID a PGID zůstaly na 0. Nastav je a stávající složky jednou přepiš přes chown.

Na RE:NODE už každý server běží ve vlastním kontejneru, takže dostaneš stejnou izolaci bez údržby image: argumenty spuštění jsou pole v záložce Startup, zastavení je vždy čisté uložení a zálohy odcházejí mimo stroj a obnovují se tlačítkem.

FAQ#

Je lloesche/valheim-server oficiální image?

Ne. Je to komunitní projekt, který nepublikuje Iron Gate ani Valve. Je oblíbený a udržovaný, ale jeho README je jediná autorita pro jeho proměnné a chování.

Jak v Dockeru uvidím kód pro připojení při crossplayi?

Přidej -crossplay do SERVER_ARGS, restartuj a přečti ho z docker compose logs. Kód se vypisuje při každém startu a pokaždé se změní.

Jak spustím příkaz v konzoli serveru?

Vanilla Valheim nemá na serveru žádný vstup konzole ani RCON. Admin příkazy zadává ve hře přes F5 hráč uvedený v adminlist.txt, což funguje v kontejneru stejně.

Můžu s tímto image provozovat dva Valheim servery?

Ano. Použij dvě služby s různými container_name, oddělenými složkami config a data, různými hodnotami SERVER_PORT aspoň o tři od sebe a odpovídajícím mapováním portů. Oba mohou sdílet jeden stroj, pokud má dost paměti.

Přidává Docker lag?

Znatelně ne. Mapování portů přidá pár mikrosekund na paket, což je daleko pod tím, co hráč vnímá. network_mode: host použij jen z konkrétního důvodu; odstraní mapování, ale i izolaci.