WARHOST

WARHOST

Docker app from suchamoneypit's Repository

Overview

WARHOST runs Eugen's official WARNO dedicated server on Unraid, one server per container. Enter the login and dedicated key Eugen sends you, your public IP, and a game port. The first start opens a base-game Hesse 2v2 lobby named WARHOST - Default Server Name, with no workshop mods. Change the name, map, and mods in the WebUI. Request a login and key from eugsupport@eugensystems.com. One pair runs five servers. Forward each game port to this Unraid server as TCP and UDP. The lobby page listens on WebUI Port. The first server leaves it at 11400, and the Docker button already opens that page. Each added container needs the next WebUI Port. Set Advanced View WebUI to http://[IP]:[PORT:11401]/, or the button still opens 11400. Do not forward the page port.

WARHOST — WARNO Dedicated Server for Unraid

WARHOST runs Eugen Systems' official WARNO dedicated server on Unraid. The install form takes the login and dedicated key Eugen sends you and writes login.ini. The WebUI writes the lobby. The container then starts Eugen's server.

The first start is a 2v2 Conquest lobby on Hesse (_2x2_Hesse_2vs2_CONQ), named WARHOST - Default Server Name, with no workshop mods. Open the WebUI to change the name, map, player limits, and mods.

If you have hosted game servers before, the field descriptions on the Unraid form and a TCP and UDP port forward are likely all you need. Its like other game servers. Setup the server setups, and make sure the game port is port forwarded to the host. WARHOST is listed in Unraid Community Applications: Apps, search WARHOST, Install. The full walkthrough is docs/INSTALL-UNRAID.md. Workshop mods and scenario IDs are further down this page (but probably unnecessary with the WebUI).

What you need

  • A dedicated-server login and key from Eugen. Email eugsupport@eugensystems.com with the email address of your EugNet account and ask for a dedicated-server key; Eugen replies with a login and key pair (Docker Hub). A dedicated key from another Eugen game also works. One pair can run up to five servers.
  • Your public WAN IP, and the game port forwarded on your router as both TCP and UDP to the Unraid server. Eugen recommends host networking and this container uses it, so Unraid shows no Docker port mapping.
  • Outbound internet from the Unraid server, so the game server can reach Eugen's master server (no offline LAN play), and so each start can read a Workshop mod's Version from Steam.

Install

WARHOST is listed in Community Applications. In the Unraid Apps tab, search for WARHOST, choose Install, fill in the form fields, and Apply. That installs the main template, which runs ghcr.io/matthewariel/warhost:latest.

Without Community Applications

Use this route for the dev template, or to install a template change before Community Applications picks it up. Unraid 7 has no field for a template URL (Unraid 6.10 removed it), so copy the template to the flash drive and pick it from the Template dropdown.

In a checkout of this repository, sh scripts/print_template_fetch.sh prints the command in step 1. Paste that command in the Unraid terminal. Paste only the branch you are about to add. Applying a downloaded template still writes my-WARHOST.xml, because <Name> is WARHOST, and leaves a differently named download in the dropdown. A clean-slate command for contributors is in docs/AI-WORKFLOW.md.

  1. Unraid web UI → terminal icon (>_):

    mkdir -p /boot/config/plugins/dockerMan/templates-user
    curl -fsSL -o /boot/config/plugins/dockerMan/templates-user/my-WARHOST.xml \
      https://raw.githubusercontent.com/matthewariel/WARHOST/main/templates/warhost.xml
    
  2. Docker → Add Container → Template → User templates, choose WARHOST, fill in the fields below, Apply.

The dropdown label is the flash filename with my- removed, so my-WARHOST.xml shows WARHOST. On Apply, Unraid writes /boot/config/plugins/dockerMan/templates-user/my-<Name>.xml from the Name on the form. With Name left as WARHOST, that is this download. A different Name leaves this file in the dropdown as a second entry, still labeled WARHOST. Delete warno-dedicated-server.xml or my-WARNO-Dedicated-Server.xml if either is still in that folder. sh scripts/print_template_fetch.sh --private saves warhost.xml under /boot/config/plugins/community.applications/private/matthewariel/. The full command is in the install guide.

The template on main installs ghcr.io/matthewariel/warhost:latest. The template on dev installs ghcr.io/matthewariel/warhost:dev. A container whose repository is still ghcr.io/suchamoneypit/warhost cannot pull that path. Edit it to ghcr.io/matthewariel/warhost:latest, or :dev for the dev template, then Apply. If Apply cannot pull the image, use the pull check in the install guide's troubleshooting table. The first server's settings folder is /mnt/user/appdata/warno/10400/settings.

Form fields

Field What to enter
Settings Folder /mnt/user/appdata/warno/10400/settings for the first server. The next container uses this path with the port number plus 1, for example /mnt/user/appdata/warno/10401/settings. The folder holds the ini files only. Set Advanced View WebUI to http://[IP]:[PORT:11401]/.
Eugen Login The login from Eugen's reply, exactly as written, not your Steam name. This login and the key are a matching pair good for five containers.
Eugen Dedicated Key The key from the same reply. Paste the whole key. The log shows only the last 4 characters.
Public WAN IP The address Eugen's lobby should advertise to players. Look it up at https://www.whatismyip.com/ from a device on that network if you do not know it.
WebUI true serves the lobby page on WebUI Port. Set the server name, map, and mods there. For the next container, set Advanced View WebUI to http://[IP]:[PORT:11401]/. false leaves the Docker button with nothing listening.
Game Port 10400 for the first server. This port must be free on the Unraid host. The next container uses that number plus 1. Forward each number to this Unraid server as TCP and UDP. Set WebUI Port to this number plus 1000. Set Advanced View WebUI to http://[IP]:[PORT:11401]/. Players join by the server name set in the WebUI.
WebUI Port Port the lobby page listens on: 11400 on the first server, then the next number. Set Advanced View WebUI to http://[IP]:[PORT:11401]/ or the Docker button still opens 11400. Do not forward it.
Write Config From Form (Show more settings) true rewrites login.ini each start, fills in missing lobby files, and refreshes a bare Workshop id to id/Version. false leaves the file contents in place and sets login.ini to mode 600.

Show more settings holds Write Config From Form. Two new containers both use WARHOST - Default Server Name until each is changed in its WebUI. Scenario IDs and named mods are in the tables below.

A container saved from an earlier template can still show Server Name, Map, player counts, combat rule, and the workshop fields. This entrypoint ignores those values and prints Lobby settings on the Docker template are ignored. Change the server in the WebUI.

Map

The WebUI map list uses a scenario ID from the lists below. Base-game maps need no workshop mod. A workshop map needs its pack checked under Steam Workshop Maps on that page, from the workshop mods table. When the startup log warns about the map or the mod list, the troubleshooting table in the install guide says what to change.

The size in the ID is the usual lobby. Eugen's variables.ini page does not tie player count to that size. The usual settings are Max Players 2 and Team Size 1 for 1v1, 4 and 2 for 2v2, 6 and 3 for 3v3, 8 and 4 for 4v4, and 20 and 10 for 10v10. Choosing a map in the WebUI fills Max players (NbMaxPlayer) and Team size (MaxTeamSize) from that map, and sets Minimum players (NbMinPlayer) to the same count as Max players. Eugen's variables.ini page says the server starts its launch countdown when that many players have joined, and that the minimum should not be higher than the maximum. A 10v10 therefore fills 20, 10, and 20. PvE hides those three; PvP keeps them editable, and a save writes what they show, so a 2v2 map can still be saved as 8 and 4 or as a 1v1 (max 2, team size 1, minimum 2). A count already in variables.ini is what the page shows until the map is changed.

Workshop mods

The WebUI checklist loads the mod that contains the maps. Check the Workshop id from the table. Save writes the bare id. The next start reads that mod's current Version and writes id/Version. Pick the map from that mod's scenario list below. Red Dragon is the first row: check 3811913066, which sets tags Maps-Scenarios, and choose RDPort_JungleLaw_2v2_CONQ for Jungle Law.

Mod Workshop Mod List Example pin Workshop Mod Tags
WARNO: Red Dragon - Map Pack 3811913066 3811913066/27 Maps-Scenarios
WEST FULDA 1.0 3363584349 3363584349/1023 Maps-Scenarios
Highway to Oslo 3474588989 3474588989/14 Maps-Scenarios
Ramstein Air Base 3705706772 3705706772/9 Maps-Scenarios
Arsenal 3415339374 3415339374/20 Maps-Scenarios
Helbe 3762638679 3762638679/36 Maps-Scenarios
Galactic Divide 3595948209 3595948209/16 Gameplay-Interface-Sound-Scenarios-Maps
A World in Flames 3388575848 3388575848/7 Gameplay-Interface, or Gameplay-Interface-Maps-Scenarios with a map pack

The example pin is that mod's Version from Config.ini at the time the table was written. A pin holds that number, so players are refused once the author increments Version. The WebUI writes the bare id. A pin already in variables.ini stays until that mod is saved again from the page. The dated reads are in docs/EVIDENCE.md.

Galactic Divide is a total conversion and A World in Flames is a modern-day overhaul. Neither has scenario IDs of its own, so the map comes from the base game or a map pack. Check a conversion and a map pack together. The page joins their ids with a hyphen, for example 3595948209-3811913066. Tags are the union of the checked mods. A World in Flames uses Gameplay-Interface alone, and Gameplay-Interface-Maps-Scenarios when a map pack is also checked.

Joining players subscribe to each Workshop item in the list and enable it in WARNO's Mod Center. Eugen's variables.ini page says a joining player who is missing a ModList mod is prompted to download and enable it. To read Version, the container downloads just the mod's Config.ini from Steam with DepotDownloader, on the first start and after each update the author publishes.

Scenario IDs

Map packs come first and the base game is last. Choose the value from the Scenario ID column in the WebUI. The SM_ names under some packs are Army General files; pick a scenario from the tables. For a mod not listed here, step 3 of the install guide shows how to find its IDs. An id already in variables.ini that is not in this list stays if you leave it checked.

Red Dragon map pack (28 scenario IDs)

Check 3811913066 in the WebUI checklist. Every map is Conquest, so leave combat rule as the page sets it.

Map Scenario ID Size
Hell in a Very Small Place RDPort_HellInAVerySmallPlace_1v1_CONQ 1v1
Mud Fight RDPort_MudFight_1v1_CONQ 1v1
Paddy Field RDPort_PaddyField_1v1_CONQ 1v1
Strait to the Point (file name StraitSmall) RDPort_StraitSmall_1v1_CONQ 1v1
Tropic Thunder RDPort_TropicThunder_1v1_CONQ 1v1
Wonsan Harbour Land & Sea (file name WonsanLandSea) RDPort_WonsanLandSea_1v1_CONQ 1v1
Another D-Day RDPort_AnotherDDay_2v2_CONQ 2v2
Apocalypse Imminent RDPort_ApocalypseImminent_2v2_CONQ 2v2
Chosin Reservoir RDPort_ChosinReservoir_2v2_CONQ 2v2
Gunboat Diplomacy RDPort_GunboatDiplomacy_2v2_CONQ 2v2
Hop and Glory RDPort_HopAndGlory_2v2_CONQ 2v2
Jungle Law RDPort_JungleLaw_2v2_CONQ 2v2
Operation Chromite RDPort_OperationChromite_2v2_CONQ 2v2
Paddy Field RDPort_PaddyField_2v2_CONQ 2v2
Strait to the Point Land & Sea (file name StraitSmallLandSea) RDPort_StraitSmallLandSea_2v2_CONQ 2v2
Wonsan Harbour (file name WonsanNative) RDPort_WonsanNative_2v2_CONQ 2v2
38th Perpendicular RDPort_38thPerpendicular_3v3_CONQ 3v3
Another D-Day in Paradise Land & Sea RDPort_AnotherDDayLandSea_3v3_CONQ 3v3
Back to Inchon RDPort_BackToInchon_3v3_CONQ 3v3
Gunboat Diplomacy Land & Sea RDPort_GunboatLandSea_3v3_CONQ 3v3
Strait to the Point RDPort_StraitToThePoint_3v3_CONQ 3v3
38th Parallel RDPort_38thParallel_4v4_CONQ 4v4
Battle of Yuchalnok Pass RDPort_BattleOfYuchalnokPass_4v4_CONQ 4v4
Final Meltdown RDPort_FinalMeltdown_4v4_CONQ 4v4
Floods RDPort_Floods_4v4_CONQ 4v4
Strait to the Point Land & Sea (file name StraitLandSea) RDPort_StraitLandSea_4v4_CONQ 4v4
Sun of Juche RDPort_SunOfJuche_4v4_CONQ 4v4
Asgard RDPort_Asgard_10v10_CONQ 10v10
WEST FULDA 1.0 (16 scenario IDs)

Workshop Mod List 3363584349.

Map Scenario ID Size
West Fulda _3x3_WFulda_4v4_CONQ 4v4 Conquest
West Fulda _3x3_WFulda_4v4_DEST 4v4 Destruction
West Fulda _3x3_WFulda_10v10_CONQ 10v10 Conquest
West Fulda _3x3_WFulda_10v10_DEST 10v10 Destruction
Bimbach _3x3_WFuldaBimbach_2v2_CONQ 2v2 Conquest
Bimbach _3x3_WFuldaBimbach_2v2_DEST 2v2 Destruction
Grossenluder _3x3_WFuldaGrossen_1v1_CONQ 1v1 Conquest
Grossenluder _3x3_WFuldaGrossen_2v2_DEST 2v2 Destruction
Kammerzell _3x3_WFuldaKammerzell_1v1_CONQ 1v1 Conquest
Kammerzell _3x3_WFuldaKammerzell_2v2_CONQ 2v2 Conquest
Kammerzell _3x3_WFuldaKammerzell_2v2_DEST 2v2 Destruction
Malkes _3x3_WFuldaMalkes_3v3_CONQ 3v3 Conquest
Malkes _3x3_WFuldaMalkes_3v3_DEST 3v3 Destruction
Neuenberg _3x3_WFuldaNeuen_1v1_CONQ 1v1 Conquest
Neuenberg _3x3_WFuldaNeuen_2v2_CONQ 2v2 Conquest
Neuenberg _3x3_WFuldaNeuen_2v2_DEST 2v2 Destruction

Army General file names:

  • SM_FO_3x3_WestFulda_01
  • SM_FO_3x3_WestFulda_02
  • SM_PL_3x3_WestFulda_01
  • SM_PL_3x3_WestFulda_02
  • SM_PL_3x3_WestFulda_03
  • SM_PL_3x3_WestFulda_04
  • SM_SU_3x3_WestFulda_01
  • SM_SU_3x3_WestFulda_02
  • SM_SU_3x3_WestFulda_03
Highway to Oslo (4 scenario IDs)

Workshop Mod List 3474588989. The Workshop page lists these as 1v1.

Map Scenario ID Size
Highway to Oslo _2x2_Oslo_Conquest 1v1 Conquest
Highway to Oslo _2x2_Oslo_Destruction 1v1 Destruction
Highway to Oslo _2x2_Oslo_ConquestNS 1v1 Conquest, no sidespawn
Highway to Oslo _2x2_Oslo_DestructionNS 1v1 Destruction, no sidespawn
Ramstein Air Base (2 scenario IDs)

Workshop Mod List 3705706772. The Workshop page lists these as 3v3.

Map Scenario ID Size
Ramstein Air Base _2x2_Ramstein_Conquest 3v3 Conquest
Ramstein Air Base _2x2_Ramstein_Destruction 3v3 Destruction
Arsenal (4 scenario IDs)

Workshop Mod List 3415339374. The Workshop page lists 2v2 and 3v3 layouts, each in Conquest and Destruction.

Map Scenario ID Size
Two Hills _2x3_TwoHills_Conquest 2v2 Conquest
Two Hills _2x3_TwoHills_Destruction 2v2 Destruction
Two Hills _2x3_TwoHills_Conquest_6P 3v3 Conquest
Two Hills _2x3_TwoHills_Destruction_6P 3v3 Destruction
Helbe (12 scenario IDs)

Workshop Mod List 3762638679. Norden's file is a 2v2. The Workshop page calls that layout 3v3; the WebUI fills the size in this table.

Map Scenario ID Size
Helbe _5x3_Helbe_4v4_CONQ 4v4 Conquest
Helbe _5x3_Helbe_10v10_CONQ 10v10 Conquest
Hochland _5x3_HelbeHochland_2v2_CONQ 2v2 Conquest
Norden _5x3_HelbeNorden_2v2_CONQ 2v2 Conquest
Stream _5x3_HelbeStream_2v2_CONQ 2v2 Conquest
Stream _5x3_HelbeStream_3v3_CONQ 3v3 Conquest
Stream _5x3_HelbeStream_10v10_CONQ 10v10 Conquest
Suden _5x3_HelbeSuden_1v1_CONQ_DUEL 1v1 Conquest duel
Wide _5x3_HelbeWide_4v4_CONQ 4v4 Conquest
Wide _5x3_HelbeWide_10v10_CONQ 10v10 Conquest
Zentrum _5x3_HelbeZentrum_3v3_CONQ 3v3 Conquest
Zentrum _5x3_HelbeZentrum_10v10_CONQ 10v10 Conquest

Army General file names:

  • SM_FO_5x3_Helbe_01
  • SM_FO_5x3_Helbe_02
  • SM_FO_5x3_Helbe_03
  • SM_PL_5x3_Helbe_01
  • SM_PL_5x3_Helbe_02
  • SM_PL_5x3_Helbe_03
  • SM_PL_5x3_Helbe_04
  • SM_PL_5x3_Helbe_05
Base game (102 scenario IDs)

Leave the WebUI workshop checklist clear. These are the Map Base Id values from Eugen's Docker Hub page.

Map Scenario ID Size
Airport (duel) _3x3_Airport_1vs1_CONQ_DUEL 1v1 Conquest
Black Forest Storm (duel) _2x3_BlackForestStorm_1vs1_CONQ_DUEL 1v1 Conquest
Chemical (duel) _4x2_Chemical_1vs1_CONQ_DUEL 1v1 Conquest
Death Row (training) _2x3_Death_Row_1vs1_CONQ_TRAINING 1v1 Conquest
Geisa (training) _4x3_geisa_1vs1_CONQ_TRAINING 1v1 Conquest
Hesse (duel) _2x2_Hesse_1vs1_CONQ_DUEL 1v1 Conquest
Kreide (duel) _3x3_Kreide_1vs1_CONQ_DUEL 1v1 Conquest
Mount River (duel) _3x3_MountRiver_1vs1_CONQ_DUEL 1v1 Conquest
Mount River (training) _3x3_MountRiver_1vs1_CONQ_TRAINING 1v1 Conquest
Ohmen (duel) _2x3_Ohmen_1vs1_CONQ_DUEL 1v1 Conquest
Two Lakes (duel) _2x3_Two_lakes_1vs1_CONQ_DUEL 1v1 Conquest
Urban Frontlines (duel) _3x3_UrbanFrontlines_1vs1_CONQ_DUEL 1v1 Conquest
Vertigo (duel) _2x3_Vertigo_1vs1_CONQ_DUEL 1v1 Conquest
Albion Military Base _2x3_Albion_Military_Base_2vs2_CONQ 2v2 Conquest
Black Forest Storm _2x3_BlackForestStorm_2vs2_CONQ 2v2 Conquest
Chemical (training) _4x2_Chemical_2vs2_CONQ_TRAINING 2v2 Conquest
Death Row _2x3_Death_Row_2vs2_CONQ 2v2 Conquest
Hesse _2x2_Hesse_2vs2_CONQ 2v2 Conquest
Loop _5x2_Loop_2vs2_CONQ 2v2 Conquest
Mount River (assault) _3x3_MountRiver_2vs2_CONQ_ASSAULT 2v2 Conquest
Ripple _2x3_Ripple_2vs2_CONQ 2v2 Conquest
Tension _2x2_Tension_2vs2_CONQ 2v2 Conquest
Teufelsmoor _2x2_Teufelsmoor_2vs2_CONQ 2v2 Conquest
Two Lakes _2x3_Two_lakes_2vs2_CONQ 2v2 Conquest
Two Ways _2x3_TwoWays_2vs2_CONQ 2v2 Conquest
Urban Frontlines _3x3_UrbanFrontlines_2vs2_CONQ 2v2 Conquest
Vertigo _2x3_Vertigo_2vs2_CONQ 2v2 Conquest
Death Row _2x3_Death_Row_2vs2_DEST 2v2 Destruction
Ripple _2x3_Ripple_2vs2_DEST 2v2 Destruction
Two Lakes _2x3_Two_lakes_2vs2_DEST 2v2 Destruction
Two Ways _2x3_TwoWays_2vs2_DEST 2v2 Destruction
Vertigo _2x3_Vertigo_2vs2_DEST 2v2 Destruction
Airport _3x3_Airport_3vs3_CONQ 3v3 Conquest
Cliff _4x3_Cliff_3vs3_CONQ 3v3 Conquest
Cyrus _3x3_Cyrus_3vs3_CONQ 3v3 Conquest
Danger Hills _3x3_DangerHills_3vs3_CONQ 3v3 Conquest
Eiche _3x3_Eiche_3vs3_CONQ 3v3 Conquest
Factory _3x3_Factory_3vs3_CONQ 3v3 Conquest
Kreide _3x3_Kreide_3vs3_CONQ 3v3 Conquest
Mount River _3x3_MountRiver_3vs3_CONQ 3v3 Conquest
Railway _3x3_Railway_3vs3_CONQ 3v3 Conquest
Rift _3x3_Rift_3vs3_CONQ 3v3 Conquest
Rocks _3x3_Rocks_3vs3_CONQ 3v3 Conquest
Rocks (assault) _3x3_Rocks_3vs3_CONQ_ASSAULT 3v3 Conquest
Stoneware _3x3_Stoneware_3vs3_CONQ 3v3 Conquest
Surrounded _3x3_Surrounded_3vs3_CONQ 3v3 Conquest
Triple Strike _3x3_TripleStrike_3vs3_CONQ 3v3 Conquest
Twin Cities _3x3_TwinCities_3vs3_CONQ 3v3 Conquest
Two Ways _2x3_TwoWays_3vs3_CONQ 3v3 Conquest
Urban Frontlines _3x3_UrbanFrontlines_3vs3_CONQ 3v3 Conquest
Valley _3x3_Valley_3vs3_CONQ 3v3 Conquest
Volcano _3x3_Volcano_3vs3_CONQ 3v3 Conquest
Airport _3x3_Airport_3vs3_DEST 3v3 Destruction
Cyrus _3x3_Cyrus_3vs3_DEST 3v3 Destruction
Danger Hills _3x3_DangerHills_3vs3_DEST 3v3 Destruction
Eiche _3x3_Eiche_3vs3_DEST 3v3 Destruction
Factory _3x3_Factory_3vs3_DEST 3v3 Destruction
Kreide _3x3_Kreide_3vs3_DEST 3v3 Destruction
Mount River _3x3_MountRiver_3vs3_DEST 3v3 Destruction
Railway _3x3_Railway_3vs3_DEST 3v3 Destruction
Rift _3x3_Rift_3vs3_DEST 3v3 Destruction
Rocks _3x3_Rocks_3vs3_DEST 3v3 Destruction
Stoneware _3x3_Stoneware_3vs3_DEST 3v3 Destruction
Surrounded _3x3_Surrounded_3vs3_DEST 3v3 Destruction
Triple Strike _3x3_TripleStrike_3vs3_DEST 3v3 Destruction
Twin Cities _3x3_TwinCities_3vs3_DEST 3v3 Destruction
Urban Frontlines _3x3_UrbanFrontlines_3vs3_DEST 3v3 Destruction
Valley _3x3_Valley_3vs3_DEST 3v3 Destruction
Volcano _3x3_Volcano_3vs3_DEST 3v3 Destruction
Chemical _4x2_Chemical_4vs4_CONQ 4v4 Conquest
Dark Stream _4x2_DarkStream_4vs4_CONQ 4v4 Conquest
Chemical _4x2_Chemical_4vs4_DEST 4v4 Destruction
Airport _3x3_Airport_10vs10_CONQ 10v10 Conquest
Crown _5x2_crown_10vs10_CONQ 10v10 Conquest
Cyrus _3x3_Cyrus_10vs10_CONQ 10v10 Conquest
Danger Hills _3x3_DangerHills_10vs10_CONQ 10v10 Conquest
Dark Stream _4x2_DarkStream_10vs10_CONQ 10v10 Conquest
Factory _3x3_Factory_10vs10_CONQ 10v10 Conquest
Geisa _4x3_geisa_10vs10_CONQ 10v10 Conquest
Iron Waters _3x3_IronWaters_10vs10_CONQ 10v10 Conquest
Kreide _3x3_Kreide_10vs10_CONQ 10v10 Conquest
Loop _5x2_Loop_10vs10_CONQ 10v10 Conquest
Railway _3x3_Railway_10vs10_CONQ 10v10 Conquest
Rift _3x3_Rift_10vs10_CONQ 10v10 Conquest
Rocks _3x3_Rocks_10vs10_CONQ 10v10 Conquest
Stoneware _3x3_Stoneware_10vs10_CONQ 10v10 Conquest
Surrounded _3x3_Surrounded_10vs10_CONQ 10v10 Conquest
Triple Strike _3x3_TripleStrike_10vs10_CONQ 10v10 Conquest
Twin Cities _3x3_TwinCities_10vs10_CONQ 10v10 Conquest
Urban Frontlines _3x3_UrbanFrontlines_10vs10_CONQ 10v10 Conquest
Valley _3x3_Valley_10vs10_CONQ 10v10 Conquest
Volcano _3x3_Volcano_10vs10_CONQ 10v10 Conquest
Airport _3x3_Airport_10vs10_DEST 10v10 Destruction
Crown _5x2_crown_10vs10_DEST 10v10 Destruction
Cyrus _3x3_Cyrus_10vs10_DEST 10v10 Destruction
Danger Hills _3x3_DangerHills_10vs10_DEST 10v10 Destruction
Geisa _4x3_geisa_10vs10_DEST 10v10 Destruction
Iron Waters _3x3_IronWaters_10vs10_DEST 10v10 Destruction
Kreide _3x3_Kreide_10vs10_DEST 10v10 Destruction
Loop _5x2_Loop_10vs10_DEST 10v10 Destruction
Rocks _3x3_Rocks_10vs10_DEST 10v10 Destruction
Volcano _3x3_Volcano_10vs10_DEST 10v10 Destruction

A second server

Each server is its own container. Add another one from this same template. Do not use Unraid's reinstall action. Reinstall replaces the container you already have.

The container name, Game Port, WebUI Port, and Settings Folder are unique. The server name is set in that container's WebUI, and it has to differ from the other servers. The directory before /settings is that container's Game Port. The next container adds 1 to the Game Port and to the WebUI Port. In Advanced View, change 11400 in the WebUI box to that container's WebUI Port so the Docker button opens its page.

Field First server Second server
Name WARHOST WARHOST2
Game Port 10400 10401
WebUI Port 11400 11401
Advanced View WebUI http://[IP]:[PORT:11400]/ http://[IP]:[PORT:11401]/
Settings Folder /mnt/user/appdata/warno/10400/settings /mnt/user/appdata/warno/10401/settings
Server name in the WebUI WARHOST - Default Server Name until you change it a different name

The map and workshop mods also belong to each container, so one server can run the Red Dragon map pack while another runs a base-game map. Public WAN IP, Eugen login, and Eugen dedicated key stay the same for up to five servers. A sixth container needs another login and key pair. Forward each Game Port to this Unraid server as TCP and UDP. Players join from the WARNO server browser by server name. They are not given a port to type.

Every container uses the same image, stored once. The settings folder holds login.ini, variables.ini, and params_for_ai.json. The wrapper also creates warhost.lock there so two running containers cannot share the folder. Do not copy WARNO or a Workshop folder into it. If the folder is already in use, or the game port is already taken, the start stops and the log says what to change. One pair runs five servers.

Settings files

On each start, Write Config From Form (true) rewrites login.ini in the settings folder. It creates variables.ini only when that file is missing, using the Hesse preset, and creates params_for_ai.json only when that file is missing, as two empty deck lists. An existing variables.ini stays, except a bare Workshop id in ModList, which that start rewrites as id/Version. A symlink at params_for_ai.json is replaced; a regular file is kept.

When ModList holds a bare Workshop id, the start also writes warhost-workshop-versions.txt: one line per id with Steam's update time and the Version written. Delete it to make the next start read each Config.ini again, after a WebUI save has put the bare id back.

The wrapper writes those files in a private .warhost-stage.* folder first, then moves them into place. The next start that locks the settings folder removes one left by a crash or power loss, so do not keep anything under that name.

samples/ shows the shape of those files with placeholders only. Do not replace the placeholders in this repository.

The faction matchup is NATO vs PACT (GameType = 0). Teams must stay the same size (DeltaMaxTeamSize = 0) until a PvE setup save says otherwise. The first params_for_ai.json has no decks. RCON is not configured.

Set Write Config From Form to false only when you need to edit those files by hand. While it is true, the next start still rewrites login.ini, leaves an existing variables.ini and an existing params_for_ai.json in place, and refreshes bare Workshop ids in variables.ini. While it is false, the three files stay as edited, login.ini is set to mode 600, and no Workshop id is looked up on Steam. Any other file the server itself creates in that folder (for example admins.ini or banned_clients.ini, if it creates them) is left alone.

Logs

After the startup lines, the Docker log prints a status line when it changes, and repeats that line about every 5 minutes. status: dedicated server has not reported yet is normal until the server writes its first snapshot. A file left from the previous run is removed at start, so it is not reported as the current lobby. The count includes players and computer players, so a PvE lobby can look full before a human joins.

status: lobby, 1 player, including AI, minimum 2, maximum 4 is a lobby still short of its minimum. Once the count reaches that minimum, the line is status: lobby, 2 players, including AI, minimum 2 reached, maximum 4, warmup setting 60s. The warmup number is WarmupCountdown in variables.ini. It is the saved setting, not seconds remaining. status: GameState 3, 4 players, including AI, maximum 4 is any state other than the lobby. Eugen documents 0 as no game in progress and does not define the other numbers, so the log prints the number. warning: dedicated server status is stale. It has not updated for more than 30 seconds. means the status file stopped changing.

The same lines are appended to .warhost-status.log in the settings folder. That file stays when the container is recreated, rotates at 1 MB, and keeps one previous file. The server rewrites .warhost-status there with the raw snapshot. A quiet server adds about 1 KB an hour.

WebUI

The page listens on WebUI Port. The first server is http://<unraid>:11400/. The next server, with WebUI Port 11401, is http://<unraid>:11401/. Do not forward that port. A container from before this field still listens on the game port plus 1000. Under the heading, the page lists the game port and the WebUI port as a pair, and the game port says (must be port forwarded TCP/UDP). The browser tab names both ports, so several open pages stay distinct. When the page is up, the log says WebUI listening on http://10.0.1.50:11400/. That address is this server's, not the public WAN IP. It can differ from the host in the Docker button when the default route uses another interface. When WebUI Port is not 11400, the next line is If the Docker button opens another server, set Advanced View WebUI to http://[IP]:[PORT:11401]/.

The first server leaves WebUI Port and the Advanced View WebUI box at http://[IP]:[PORT:11400]/. The Docker button already opens that page. A later container's button opens its page only after that box uses the same number as WebUI Port. Changing WebUI Port does not change the box.

false leaves nothing listening. The log says WebUI is off. Nothing is listening on port 11400. If that port is already taken, it says WebUI is off. Port 11400 is already in use. With WebUI left on, a taken page port logs warning: WebUI port 11400 is already in use. The game server will still start. The Docker button still opens the port in the Advanced View box.

  • Map and mods. Steam Workshop Maps lists the named map packs. Full conversions, such as Galactic Divide and A World in Flames, are a second checklist. Checking a pack shows its maps. An id already in variables.ini that is not in either list stays as a checkbox labeled with that id. Search matches the map name and scenario ID. For a map in the list, the combat-rules menu offers only that scenario's rule.
  • PvP and PvE. PvP keeps Max players, Team size, and Minimum players, and does not write params_for_ai.json. PvE hides those three. Humans play as one side and the AI count fills the other. A PvE save writes CoopVsAI (1 or 2), sets minimum players to the human count, max players to the two counts added together, and team size to the larger count. It also writes at least one AI deck: a name, a deck code, and a difficulty from 1 to 6. Switching back to PvP sets CoopVsAI to 0 and leaves the deck file.
  • Save. Save writes the server name, the map, the checked mods as bare ids, and the match dropdowns into variables.ini. Tags come from the checked mods. A modded map whose pack is unchecked is rejected. Save keeps the previous copy as variables.ini.bak and leaves the current match running. Save and restart writes the form when it differs from that file, then restarts the dedicated server. If the page cannot restart the container, restart it in Unraid.

If the page fails to start, the log warns and the game server still starts. A privilege drop that fails leaves the page running, and the log says it stayed root. The page does not show the Eugen login or dedicated key. Scenic view and tactical zones stay text until webui/previews is filled from a local WARNO install. That folder is not in the published image.

Keys

The dedicated key belongs in the Unraid form, which stores it for that container and writes login.ini on the server. The startup log names only the last 4 characters. The key does not belong in this git repository, in an example file, or in a GitHub issue. If a key is ever committed, treat it as compromised even after a later delete, because git history keeps it. .gitignore ignores login.ini and a local settings/ directory.

Updates

Eugen publishes game updates as eugensystems/warno:latest. This repo does not copy their listen, IP, or matchmaking arguments. The wrapper appends -statusfile so the log can report the lobby. entrypoint-unraid.sh writes the settings files and then runs /server/entrypoint2.sh from their image. It stays the container's main process. Save and restart runs that start again so the saved lobby and Workshop versions load.

.github/workflows/rebuild-image.yml checks Eugen's image once a day. The workflow also runs when the Dockerfile, entrypoint-unraid.sh, webui/, or .github/workflows/rebuild-image.yml changes, and a push of those paths publishes :latest from main or :dev from dev. In Unraid, update each server container. A failed build leaves the previous image in place. Fix the Action and run it again. Players on a new WARNO patch need that rebuild before the dedicated server will match the client.

Change the entrypoint only if Eugen renames entrypoint2.sh or the settings filenames. A normal game patch does not require an edit here.

Workshop mods update apart from the image. A WebUI save writes bare ids. The next start reads the current Version of each bare id in variables.ini and writes id/Version. After a mod author publishes, use Save and restart in the WebUI. Until that restart, players who have the update are refused. A pin already stored as id/Version keeps its number until that save.

License

Repository files are MIT (LICENSE). The image is built from Eugen's eugensystems/warno, which states no license, and includes DepotDownloader 3.4.0 under GPL-2.0. Publishing steps for maintainers are in docs/AI-WORKFLOW.md.

Documentation

File Contents
docs/INSTALL-UNRAID.md First install, step by step, with verification and troubleshooting
docs/ARCHITECTURE.md How the wrapper, WebUI, and image behave, with sources
docs/DECISIONS.md Why things are the way they are
docs/ROADMAP.md Goals and known issues
docs/UNRAID-TEMPLATE-GUIDE.md Generic Unraid template guidance, reusable for other game servers
docs/AI-WORKFLOW.md Working on this repository with Cursor and Claude Code

Made with AI tools

This project was built with AI coding assistants (mainly Cursor). Humans directed the work, reviewed what shipped, and remain responsible for it. Treat the template like any other community Docker or Unraid project: verify on your own server, and post in the support thread if something is wrong. Notes for working on the agent setup in this repository are in docs/AI-WORKFLOW.md.

Support

Questions and problems go to the Unraid forum thread. Leave the Eugen key out of the post.

Requirements

A Eugen Systems WARNO dedicated-server login and key. Email eugsupport@eugensystems.com, or reuse a dedicated key from another Eugen game. One pair runs five servers.

Categories

Related apps

Explore more like this

Explore all

Details

Repository
ghcr.io/matthewariel/warhost:latest
Last Updated2026-11-11
First Seen2026-11-11

Runtime arguments

Web UI
http://[IP]:[PORT:11400]/
Network
host
Shell
sh
Privileged
false

Template configuration

Settings FolderPathrw

Ini files for this container only. The next container uses this path with its own game port, for example /mnt/user/appdata/warno/10401/settings. Set Advanced View WebUI to http://[IP]:[PORT:11401]/.

Target
/server/settings
Default
/mnt/user/appdata/warno/10400/settings
Value
/mnt/user/appdata/warno/10400/settings
Eugen LoginVariable

Login from Eugen's reply, exactly as written. Not your Steam name; this login and the key are a matching pair good for five containers.

Target
EUGEN_LOGIN
Eugen Dedicated KeyVariable

Key from the same reply. Paste the whole key. The log shows only the last 4 characters.

Target
EUGEN_DEDICATED_KEY
Public WAN IPVariable

Public address players connect to. Not a hostname, and not this Unraid server's LAN address.

Target
EXPOSEDIP
WebUIVariable

true serves the lobby page on WebUI Port. Set the server name, map, and mods there. For the next container, set Advanced View WebUI to http://[IP]:[PORT:11401]/. false leaves the Docker button with nothing listening.

Target
WEB_UI
Default
true
Value
true
Game PortVariable

This port must be free on the Unraid host. Forward it as TCP and UDP. The next container uses this number plus 1. Set WebUI Port to this number plus 1000. Set Advanced View WebUI to http://[IP]:[PORT:11401]/.

Target
EXPOSEDPORT
Default
10400
Value
10400
WebUI PortVariable

Port the lobby page listens on: 11400 on the first server, then the next number. Set Advanced View WebUI to http://[IP]:[PORT:11401]/ or the Docker button still opens 11400. Do not forward it.

Target
WEB_PORT
Default
11400
Value
11400
Write Config From FormVariable

true rewrites login.ini each start, fills in missing lobby files, and refreshes a bare Workshop id to id/Version. false leaves the file contents in place and sets login.ini to mode 600.

Target
WRITE_CONFIG
Default
true
Value
true