{"id":13469826,"url":"https://github.com/lloesche/valheim-server-docker","last_synced_at":"2025-05-14T04:07:52.414Z","repository":{"id":37081572,"uuid":"336524782","full_name":"lloesche/valheim-server-docker","owner":"lloesche","description":"Valheim dedicated gameserver with automatic update, World backup, BepInEx and ValheimPlus mod support","archived":false,"fork":false,"pushed_at":"2025-03-23T22:01:16.000Z","size":7116,"stargazers_count":2050,"open_issues_count":21,"forks_count":283,"subscribers_count":24,"default_branch":"dev","last_synced_at":"2025-04-13T04:55:28.113Z","etag":null,"topics":["docker","steam","synology","valheim","valheim-server"],"latest_commit_sha":null,"homepage":"https://hub.docker.com/r/lloesche/valheim-server","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lloesche.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-02-06T11:45:41.000Z","updated_at":"2025-04-12T21:04:32.000Z","dependencies_parsed_at":"2024-04-24T10:38:21.762Z","dependency_job_id":"947e3b58-b87e-4305-8a6a-07a07345be38","html_url":"https://github.com/lloesche/valheim-server-docker","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lloesche%2Fvalheim-server-docker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lloesche%2Fvalheim-server-docker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lloesche%2Fvalheim-server-docker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lloesche%2Fvalheim-server-docker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lloesche","download_url":"https://codeload.github.com/lloesche/valheim-server-docker/tar.gz/refs/heads/dev","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254069457,"owners_count":22009557,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker","steam","synology","valheim","valheim-server"],"created_at":"2024-07-31T16:00:17.211Z","updated_at":"2025-05-14T04:07:52.354Z","avatar_url":"https://github.com/lloesche.png","language":"Shell","funding_links":[],"categories":["Apps","Shell"],"sub_categories":["Gaming"],"readme":"# lloesche/valheim-server Docker image\n\n![Valheim](https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/misc/Logo_valheim.png \"Valheim\")\n\nValheim Server in a Docker Container (with [BepInEx](#bepinexpack-valheim) and [ValheimPlus](#valheimplus) support)  \nThis project is hosted at [https://github.com/lloesche/valheim-server-docker](https://github.com/lloesche/valheim-server-docker)\n\n# Table of contents\n\n\u003c!-- vim-markdown-toc GFM --\u003e\n\n- [Basic Docker Usage](#basic-docker-usage)\n- [Environment Variables](#environment-variables)\n  - [Log filters](#log-filters)\n    - [Log filter event hooks](#log-filter-event-hooks)\n      - [Discord log filter event hook example](#discord-log-filter-event-hook-example)\n  - [Event hooks](#event-hooks)\n    - [Event hook examples](#event-hook-examples)\n      - [Install extra packages](#install-extra-packages)\n      - [Copy backups to another location](#copy-backups-to-another-location)\n      - [Notify on Discord](#notify-on-discord)\n  - [Mod config from Environment Variables](#mod-config-from-environment-variables)\n- [System requirements](#system-requirements)\n- [Deployment](#deployment)\n  - [Deploying with Docker and systemd](#deploying-with-docker-and-systemd)\n  - [Deploying with docker compose](#deploying-with-docker-compose)\n  - [Deploying to Kubernetes](#deploying-to-kubernetes)\n  - [Deploying to AWS ECS](#deploying-to-aws-ecs)\n  - [Deploying to Nomad](#deploying-to-nomad)\n- [Updates](#updates)\n- [Crossplay](#crossplay)\n  - [When you need crossplay](#when-you-need-crossplay)\n  - [When you do not](#when-you-do-not)\n  - [Network Ports](#network-ports)\n- [Backups](#backups)\n  - [Manual backup](#manual-backup)\n- [Finding Your Server](#finding-your-server)\n  - [In-game](#in-game)\n    - [Joining Directly via Hostname/IP](#joining-directly-via-hostnameip)\n  - [Steam Server Browser](#steam-server-browser)\n  - [Steam Server Favorites \u0026 LAN Play](#steam-server-favorites--lan-play)\n- [Admin Commands](#admin-commands)\n  - [Enable Admin Console](#enable-admin-console)\n- [Supervisor](#supervisor)\n  - [Supervisor API](#supervisor-api)\n- [Status web server](#status-web-server)\n  - [Monitoring with UptimeKuma](#monitoring-with-uptimekuma)\n- [Modding](#modding)\n  - [BepInExPack Valheim](#bepinexpack-valheim)\n    - [Configuration](#configuration)\n  - [ValheimPlus](#valheimplus)\n    - [Updates](#updates-1)\n    - [Configuration](#configuration-1)\n      - [Disable server password](#disable-server-password)\n- [Changing startup CMD in Portainer](#changing-startup-cmd-in-portainer)\n- [Synology Help](#synology-help)\n  - [First install](#first-install)\n  - [Updating the container image to the latest version](#updating-the-container-image-to-the-latest-version)\n    - [Error after download of new container image](#error-after-download-of-new-container-image)\n- [QNAP NAS Help](#qnap-nas-help)\n  - [Creating container](#creating-container)\n  - [Updating image](#updating-image)\n  - [QNAP ZFS issue](#qnap-zfs-issue)\n- [OpenMediaVault Help](#openmediavault-help)\n  - [Permission denied error](#permission-denied-error)\n- [License](#license)\n- [Legal disclaimer](#legal-disclaimer)\n\u003c!-- vim-markdown-toc --\u003e\n\n# Basic Docker Usage\n\nThe name of the Docker image is `ghcr.io/lloesche/valheim-server`.\n\nVolume mount the server config directory to `/config` within the Docker container.\n\nIf you have an existing world on a Windows system you can copy it from e.g.  \n `C:\\Users\\Lukas\\AppData\\LocalLow\\IronGate\\Valheim\\worlds_local`\nto e.g.  \n `$HOME/valheim-server/config/worlds_local`\nand run the image with `$HOME/valheim-server/config` volume mounted to `/config` inside the container.\nThe container directory `/opt/valheim` contains the downloaded server. It can optionally be volume mounted to avoid having to download the server on each fresh start.\n\n```\n$ mkdir -p $HOME/valheim-server/config/worlds_local $HOME/valheim-server/data\n# copy existing world\n$ docker run -d \\\n    --name valheim-server \\\n    --cap-add=sys_nice \\\n    --stop-timeout 120 \\\n    -p 2456-2457:2456-2457/udp \\\n    -v $HOME/valheim-server/config:/config \\\n    -v $HOME/valheim-server/data:/opt/valheim \\\n    -e SERVER_NAME=\"My Server\" \\\n    -e WORLD_NAME=\"Neotopia\" \\\n    -e SERVER_PASS=\"secret\" \\\n    ghcr.io/lloesche/valheim-server\n```\n\nWarning: `SERVER_PASS` must be at least 5 characters long. Otherwise `valheim_server.x86_64` will refuse to start!\n\nA fresh start will take several minutes depending on your Internet connection speed as the container will download the Valheim dedicated server from Steam (~1 GB).\n\nDo not forget to modify `WORLD_NAME` to reflect the name of your world! For existing worlds that is the filename in the `worlds_local/` folder without the `.db/.fwl` extension.\n\nIf you want to play with friends over the Internet and are behind NAT make sure that UDP ports 2456-2457 are forwarded to the container host. (Remark: If you use crossplay, you don't need port forwarding! See official Valheim Dedicated Server Manual.pdf in the data/server folder.)\nAlso ensure they are publicly accessible in any firewall.\n\n**Crossplay:** To enable crossplay between different platforms add -crossplay to SERVER_ARGS:\n\n```\n    -e SERVER_ARGS=\"-crossplay\"\n```\n\nThere is more info in section [Finding Your Server](#finding-your-server).\n\nFor LAN-only play see section [Steam Server Favorites \u0026 LAN Play](#steam-server-favorites--lan-play)\n\nFor more deployment options see the [Deployment section](#deployment).\n\nGranting `CAP_SYS_NICE` to the container is optional. It allows the Steam library that Valheim uses to give itself more CPU cycles.\nWithout it you will see a message `Warning: failed to set thread priority` in the startup log.\n\n# Environment Variables\n\n**All variable names and values are case-sensitive!**\n\n| Name                        | Default                  | Purpose                                                                                                                                                                                                                                                                                |\n| --------------------------- | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `SERVER_NAME`               | `My Server`              | Name that will be shown in the server browser                                                                                                                                                                                                                                          |\n| `SERVER_PORT`               | `2456`                   | UDP start port that the server will listen on                                                                                                                                                                                                                                          |\n| `WORLD_NAME`                | `Dedicated`              | Name of the world without `.db/.fwl` file extension                                                                                                                                                                                                                                    |\n| `SERVER_PASS`               | `secret`                 | Password for logging into the server - min. 5 characters!                                                                                                                                                                                                                              |\n| `SERVER_PUBLIC`             | `true`                   | Whether the server should be listed in the server browser (`true`) or not (`false`)                                                                                                                                                                                                    |\n| `SERVER_ARGS`               |                          | Additional Valheim server CLI arguments                                                                                                                                                                                                                                                |\n| `ADMINLIST_IDS`             |                          | Space separated list of admin SteamIDs in SteamID64 format. Overrides any existing adminlist.txt entries!                                                                                                                                                                              |\n| `BANNEDLIST_IDS`            |                          | Space separated list of banned SteamIDs in SteamID64 format. Overrides any existing bannedlist.txt entries!                                                                                                                                                                            |\n| `PERMITTEDLIST_IDS`         |                          | Space separated list of whitelisted SteamIDs in SteamID64 format. Overrides any existing permittedlist.txt entries!                                                                                                                                                                    |\n| `CROSSPLAY`                 | `false`                  | Whether the server should accept connections from non-Steam clients (`true`) or not (`false`). Check the [Crossplay](#crossplay) section for details.                                                                                                                                  |\n| `UPDATE_CRON`               | `*/15 * * * *`           | [Cron schedule](https://en.wikipedia.org/wiki/Cron#Overview) for update checks (disabled if set to an empty string or if the legacy `UPDATE_INTERVAL` is set)                                                                                                                          |\n| `IDLE_DATAGRAM_WINDOW`      | `3`                      | The time window, in seconds, to wait for incoming UDP datagrams on non-public servers before determining if the server is idle                                                                                                                                                         |\n| `IDLE_DATAGRAM_MAX_COUNT`   | `30`                     | The number of incoming UDP datagrams the container should tolerate (including useless datagrams such as mDNS, as well as useful datagrams like queries against the UDP query port and active connections by players) on non-public servers before deciding that the server is not idle |\n| `UPDATE_IF_IDLE`            | `true`                   | Only run update check if no players are connected to the server (`true` or `false`)                                                                                                                                                                                                    |\n| `RESTART_CRON`              | `10 5 * * *`             | [Cron schedule](https://en.wikipedia.org/wiki/Cron#Overview) for server restarts (disabled if set to an empty string)                                                                                                                                                                  |\n| `RESTART_IF_IDLE`           | `true`                   | Only run daily restart if no players are connected to the server (`true` or `false`)                                                                                                                                                                                                   |\n| `TZ`                        | `Etc/UTC`                | Container [time zone](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)                                                                                                                                                                                                    |\n| `BACKUPS`                   | `true`                   | Whether the server should create periodic backups (`true` or `false`)                                                                                                                                                                                                                  |\n| `BACKUPS_CRON`              | `5 * * * *`              | [Cron schedule](https://en.wikipedia.org/wiki/Cron#Overview) for world backups (disabled if set to an empty string or if the legacy `BACKUPS_INTERVAL` is set)                                                                                                                         |\n| `BACKUPS_DIRECTORY`         | `/config/backups`        | Path to the backups directory                                                                                                                                                                                                                                                          |\n| `BACKUPS_MAX_AGE`           | `3`                      | Age in days after which old backups are flushed                                                                                                                                                                                                                                        |\n| `BACKUPS_MAX_COUNT`         | `0`                      | Maximum number of backups kept, 0 means infinity                                                                                                                                                                                                                                       |\n| `BACKUPS_IF_IDLE`           | `true`                   | Backup even when no players have been connected for a while                                                                                                                                                                                                                            |\n| `BACKUPS_IDLE_GRACE_PERIOD` | `3600`                   | Grace period in seconds after the last player has disconnected in which we will still create backups when `BACKUPS_IF_IDLE=false`                                                                                                                                                      |\n| `BACKUPS_ZIP`               | `true`                   | Compress Backups with `zip`. If set to `false` Backups will be stored uncompressed.                                                                                                                                                                                                    |\n| `PERMISSIONS_UMASK`         | `022`                    | [Umask](https://en.wikipedia.org/wiki/Umask) to use for backups, config files and directories                                                                                                                                                                                          |\n| `STEAMCMD_ARGS`             | `validate`               | Additional steamcmd CLI arguments                                                                                                                                                                                                                                                      |\n| `PUBLIC_TEST`               | `false`                  | Run the Public Test Beta version of Valheim server. Note that this simply extends existing `STEAMCMD_ARGS` by adding the appropriate beta flags to it.                                                                                                                                 |\n| `VALHEIM_PLUS`              | `false`                  | Whether [ValheimPlus](https://github.com/valheimPlus/ValheimPlus) mod should be loaded (config in `/config/valheimplus`, additional plugins in `/config/valheimplus/plugins`). Can not be used together with `BEPINEX`.                                                                |\n| `VALHEIM_PLUS_REPO`         | `Grantapher/ValheimPlus` | Which ValheimPlus Github repo to use. Useful for switching to forks.                                                                                                                                                                                                                   |\n| `VALHEIM_PLUS_RELEASE`      | `latest`                 | Which version of [ValheimPlus](https://github.com/valheimPlus/ValheimPlus) to download. Will default to latest available. To specify a specific tag set to `tags/0.9.9.8`                                                                                                              |\n| `BEPINEX`                   | `false`                  | Whether [BepInExPack Valheim](https://valheim.thunderstore.io/package/denikson/BepInExPack_Valheim/) mod should be loaded (config in `/config/bepinex`, plugins in `/config/bepinex/plugins`). Can not be used together with `VALHEIM_PLUS`.                                           |\n| `SUPERVISOR_HTTP`           | `false`                  | Turn on supervisor's http server                                                                                                                                                                                                                                                       |\n| `SUPERVISOR_HTTP_PORT`      | `9001`                   | Set supervisor's http server port                                                                                                                                                                                                                                                      |\n| `SUPERVISOR_HTTP_USER`      | `admin`                  | Supervisor http server username                                                                                                                                                                                                                                                        |\n| `SUPERVISOR_HTTP_PASS`      |                          | Supervisor http server password                                                                                                                                                                                                                                                        |\n| `STATUS_HTTP`               | `false`                  | Turn on the status http server. Only useful on public servers (`SERVER_PUBLIC=true`).                                                                                                                                                                                                  |\n| `STATUS_HTTP_PORT`          | `80`                     | Status http server tcp port                                                                                                                                                                                                                                                            |\n| `STATUS_HTTP_CONF`          | `/config/httpd.conf`     | Path to the [busybox httpd config](https://git.busybox.net/busybox/tree/networking/httpd.c)                                                                                                                                                                                            |\n| `STATUS_HTTP_HTDOCS`        | `/opt/valheim/htdocs`    | Path to the status httpd htdocs where `status.json` is written                                                                                                                                                                                                                         |\n| `SYSLOG_REMOTE_HOST`        |                          | Remote syslog host or IP to send logs to                                                                                                                                                                                                                                               |\n| `SYSLOG_REMOTE_PORT`        | `514`                    | Remote syslog UDP port to send logs to                                                                                                                                                                                                                                                 |\n| `SYSLOG_REMOTE_AND_LOCAL`   | `true`                   | When sending logs to a remote syslog server also log local                                                                                                                                                                                                                             |\n| `PUID`                      | `0`                      | UID to run valheim-server as                                                                                                                                                                                                                                                           |\n| `PGID`                      | `0`                      | GID to run valheim-server as                                                                                                                                                                                                                                                           |\n\nThere are a few undocumented environment variables that could break things if configured wrong. They can be found in [`defaults`](defaults).\n\n## Log filters\n\nValheim server by default logs a lot of noise. These env variables allow users to remove unwanted lines from the log.\n\n| Prefix                          | Default      | Purpose                           |\n| ------------------------------- | ------------ | --------------------------------- |\n| `VALHEIM_LOG_FILTER_EMPTY`      | `true`       | Filter empty log lines            |\n| `VALHEIM_LOG_FILTER_UTF8`       | `true`       | Filter invalid UTF-8 characters   |\n| `VALHEIM_LOG_FILTER_MATCH`      | ` `          | Filter log lines exactly matching |\n| `VALHEIM_LOG_FILTER_STARTSWITH` | `(Filename:` | Filter log lines starting with    |\n| `VALHEIM_LOG_FILTER_ENDSWITH`   |              | Filter log lines ending with      |\n| `VALHEIM_LOG_FILTER_CONTAINS`   |              | Filter log lines containing       |\n| `VALHEIM_LOG_FILTER_REGEXP`     |              | Filter log lines matching regexp  |\n\nThe default filter removes:\n\n- Empty log lines\n- Log lines consisting of a single space (wtf?)\n- A repeating line saying `(Filename: ./Runtime/Export/Debug/Debug.bindings.h Line: 35)`\n- Lines flooding the log with `Assertion Failed` warnings on packet processing timeouts (See [#104](https://github.com/lloesche/valheim-server-docker/discussions/104))\n- If ValheimPlus is turned on lines starting with `Fallback handler could not load library`\n\n### Log filter event hooks\n\nIf an environment variable prefixed with `ON_` exists for an identically named log filter, instead of removing the log line the contents of the variable will be executed when the filter matches with the log line piped on stdin.\n\n| Prefix                             | Purpose                                        |\n| ---------------------------------- | ---------------------------------------------- |\n| `ON_VALHEIM_LOG_FILTER_MATCH`      | Run command hook on log lines exactly matching |\n| `ON_VALHEIM_LOG_FILTER_STARTSWITH` | Run command hook on log lines starting with    |\n| `ON_VALHEIM_LOG_FILTER_ENDSWITH`   | Run command hook on log lines ending with      |\n| `ON_VALHEIM_LOG_FILTER_CONTAINS`   | Run command hook on log lines containing       |\n| `ON_VALHEIM_LOG_FILTER_REGEXP`     | Run command hook on regexp match               |\n\nAll environment variables except for `VALHEIM_LOG_FILTER_EMPTY` and `VALHEIM_LOG_FILTER_UTF8` are prefixes. Meaning you can define multiple matches like so:\n\n```\n-e VALHEIM_LOG_FILTER_STARTSWITH=foo \\\n-e VALHEIM_LOG_FILTER_STARTSWITH_BAR=bar \\\n-e VALHEIM_LOG_FILTER_STARTSWITH_SOMETHING_ELSE=\"some other filter\"\n-e VALHEIM_LOG_FILTER_CONTAINS_Connected=\"Got character ZDOID from\"\n-e ON_VALHEIM_LOG_FILTER_CONTAINS_Connected=\"cat \u003e\u003e /tmp/character_login\"\n```\n\n#### Discord log filter event hook example\n\nSends a Discord message whenever a player spawns\n\n```\n-e DISCORD_WEBHOOK=\"https://discord.com/api/webhooks/8171522530...\" \\\n-e VALHEIM_LOG_FILTER_CONTAINS_Spawned=\"Got character ZDOID from\" \\\n-e ON_VALHEIM_LOG_FILTER_CONTAINS_Spawned='{ read l; l=${l//*ZDOID from /}; l=${l// :*/}; msg=\"Player $l spawned into the world\"; curl -sfSL -X POST -H \"Content-Type: application/json\" -d \"{\\\"username\\\":\\\"Valheim\\\",\\\"content\\\":\\\"$msg\\\"}\" \"$DISCORD_WEBHOOK\"; }'\n```\n\nSee [Notify on Discord](#notify-on-discord) below for proper quoting in env and compose files.\n\nIf you are running ValheimPlus and this filter triggers twice, check [this ValheimPlus issue](https://github.com/valheimPlus/ValheimPlus/issues/318).\nThe cause is a misconfigured `BepInEx.cfg` that causes all log lines to be duplicated.\n\n## Event hooks\n\nThe following environment variables can be populated to run commands whenever specific events happen.\n\n| Name                         | Default | Purpose                                                                                                                                                                                                                                                                       |\n| ---------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `PRE_SUPERVISOR_HOOK`        |         | Command to be executed before supervisord is run. Startup is blocked until this command returns.                                                                                                                                                                              |\n| `PRE_BOOTSTRAP_HOOK`         |         | Command to be executed before bootstrapping is done. Startup is blocked until this command returns.                                                                                                                                                                           |\n| `POST_BOOTSTRAP_HOOK`        |         | Command to be executed after bootstrapping is done and before the server or any services are started. Can be used to install additional packages or perform additional system setup. Startup is blocked until this command returns.                                           |\n| `PRE_BACKUP_HOOK`            |         | Command to be executed before a backup is created. The string `@BACKUP_FILE@` will be replaced by the full path of the future backup zip file. Backups are blocked until this command returns.                                                                                |\n| `POST_BACKUP_HOOK`           |         | Command to be executed after a backup is created. The string `@BACKUP_FILE@` will be replaced by the full path of the backup zip file. Backups are blocked until this command returns. See [Copy backups to another location](#copy-backups-to-another-location) for details. |\n| `PRE_UPDATE_CHECK_HOOK`      |         | Command to be executed before an update check is performed. Current update is blocked until this command returns.                                                                                                                                                             |\n| `POST_UPDATE_CHECK_HOOK`     |         | Command to be executed after an update check was performed. Future updates are blocked until this command returns.                                                                                                                                                            |\n| `PRE_START_HOOK`             |         | Command to be executed before the first server start is performed by the valheim-updater. Current start is blocked until this command returns.                                                                                                                                |\n| `POST_START_HOOK`            |         | Command to be executed after the first server start was performed by the valheim-updater. Future restarts and update checks are blocked until this command returns.                                                                                                           |\n| `PRE_RESTART_HOOK`           |         | Command to be executed before a server restart is performed by the valheim-updater. Current restart is blocked until this command returns.                                                                                                                                    |\n| `PRE_SERVER_LISTENING_HOOK`  |         | Command to be executed after the server runs, but before it's able to accept connections. The loop that checks connection status will be blocked until this command returns.                                                                                                  |\n| `POST_SERVER_LISTENING_HOOK` |         | Command to be executed once the server is available for players to connect! The hook only fires after status is updated to `running`.                                                                                                                                         |\n| `POST_RESTART_HOOK`          |         | Command to be executed after a server restart was performed by the valheim-updater. Future restarts and update checks are blocked until this command returns.                                                                                                                 |\n| `PRE_SERVER_RUN_HOOK`        |         | Command to be executed before the server is started. Server startup is blocked until this command returns.                                                                                                                                                                    |\n| `POST_SERVER_RUN_HOOK`       |         | Command to be executed after the server has finished running. Server shutdown is blocked until this command returns or a shutdown timeout is triggered after 29 seconds.                                                                                                      |\n| `PRE_SERVER_SHUTDOWN_HOOK`   |         | Command to be executed before the server is shut down. Server shutdown is blocked until this command returns. If `PRE_SERVER_SHUTDOWN_HOOK` holds the shutdown process for more than 90 seconds, the entire process will be hard-killed by `supervisord`.                     |\n| `POST_SERVER_SHUTDOWN_HOOK`  |         | Command to be executed after the server has finished shutting down.                                                                                                                                                                                                           |\n| `PRE_BEPINEX_CONFIG_HOOK`    |         | Command to be executed before writing BepInEx.cfg.                                                                                                                                                                                                                            |\n| `POST_BEPINEX_CONFIG_HOOK`   |         | Command to be executed after writing BepInEx.cfg. Can be used to write your own mod config using [`env2cfg`](#mod-config-from-environment-variables).                                                                                                                         |\n\n### Event hook examples\n\n#### Install extra packages\n\n```\n-e POST_BOOTSTRAP_HOOK=\"apt-get update \u0026\u0026 DEBIAN_FRONTEND=noninteractive apt-get -y install awscli\"\n```\n\n#### Copy backups to another location\n\nAfter a backup ZIP has been created the command specified by `$POST_BACKUP_HOOK` will be executed if set to a non-zero string.\nWithin that command the string `@BACKUP_FILE@` will be replaced by the full path to the just created ZIP file.\n\n```\n-v $HOME/.ssh/id_rsa:/root/.ssh/id_rsa \\\n-v $HOME/.ssh/known_hosts:/root/.ssh/known_hosts \\\n-e POST_BACKUP_HOOK='timeout 300 scp @BACKUP_FILE@ myself@example.com:~/backups/$(basename @BACKUP_FILE@)'\n```\n\n#### Notify on Discord\n\nBecause proper string quoting on the shell vs. inside a `docker-compose.yaml` vs. an `env_file` can be challenging, here are examples for each use case.\n\n##### Using the commandline\n\nDelay restarts by 1 minute and notify on Discord\n\n```\n-e DISCORD_WEBHOOK=\"https://discord.com/api/webhooks/8171522530...\" \\\n-e DISCORD_MESSAGE=\"Restarting Valheim server in one minute!\" \\\n-e PRE_RESTART_HOOK='curl -sfSL -X POST -H \"Content-Type: application/json\" -d \"{\\\"username\\\":\\\"Valheim\\\",\\\"content\\\":\\\"$DISCORD_MESSAGE\\\"}\" \"$DISCORD_WEBHOOK\" \u0026\u0026 sleep 60'\n```\n\n##### Inside docker-compose.yaml\n\nNotify on Discord with server's name in the message\n\n```\n    environment:\n      - DISCORD_WEBHOOK=https://discord.com/api/webhooks/8171522530...\n      - DISCORD_MESSAGE=Starting Valheim server $$SERVER_NAME\n      - 'PRE_BOOTSTRAP_HOOK=curl -sfSL -X POST -H \"Content-Type: application/json\" -d \"{\\\"username\\\":\\\"Valheim\\\",\\\"content\\\":\\\"$$(eval echo $$DISCORD_MESSAGE)\\\"}\" \"$$DISCORD_WEBHOOK\"'\n```\n\n##### Inside an env_file\n\n```\nDISCORD_WEBHOOK=https://discord.com/api/webhooks/8171522530...\nDISCORD_MESSAGE=Starting Valheim server\nPRE_BOOTSTRAP_HOOK=curl -sfSL -X POST -H \"Content-Type: application/json\" -d \"{\\\"username\\\":\\\"Valheim\\\",\\\"content\\\":\\\"$DISCORD_MESSAGE\\\"}\" \"$DISCORD_WEBHOOK\"\n```\n\n#### Notify on Matrix, inside an env_file\n\nCreate an account for your bot, log in and join the room you want to post to. The room ID is noted in the room's settings.\n\n```\nMATRIX_BOT_SERVER=https://matrix...\nMATRIX_BOT_ROOM_ID=!...\nMATRIX_BOT_ACCESS_TOKEN=...\nPRE_RESTART_HOOK=curl -sfSL -X PUT -d \"{\\\"msgtype\\\":\\\"m.notice\\\",\\\"body\\\":\\\"Valheim is being updated\\\"}\" \"$MATRIX_BOT_SERVER/_matrix/client/r0/rooms/$MATRIX_BOT_ROOM_ID/send/m.room.message/$(date +%s-%N)?access_token=$MATRIX_BOT_ACCESS_TOKEN\"\n```\n\nNote the `$(date +%s-%N)` is used for the required unique txnId.\n\n## Mod config from Environment Variables\n\nMod config can be specified in environment variables using the syntax `\u003cprefix\u003e_\u003csection\u003e_\u003cvariable\u003e=\u003cvalue\u003e`.\n\n**Predefined prefix list**\n| Prefix | Mod | File |\n|----------|----------|----------|\n| `VPCFG` | ValheimPlus | `/config/valheimplus/valheim_plus.cfg` |\n| `BEPINEXCFG` | BepInEx | `/config/valheimplus/BepInEx.cfg` or `/config/bepinex/BepInEx.cfg` depending on whether `VALHEIM_PLUS=true` or `BEPINEX=true` |\n\n**Translation table**  \nSome characters that are allowed as section names in the config files are not allowed as environment variable names. They can be encoded using the following translation table.\n| Variable name string | Replacement |\n|----------|----------|\n| `_DOT_` | `.` |\n| `_HYPHEN_` | `-` |\n| `_UNDERSCORE_` | `_` |\n| `_PLUS_` | `+` |\n| `_SPACE_` | ` ` |\n\nExample:\n\n```\n-e VALHEIM_PLUS=true \\\n-e VPCFG_Server_enabled=true \\\n-e VPCFG_Server_enforceMod=false \\\n-e VPCFG_Server_dataRate=500 \\\n-e BEPINEXCFG_Logging_DOT_Console_Enabled=true\n```\n\nturns into `/config/valheimplus/valheim_plus.cfg`\n\n```\n[Server]\nenabled=true\nenforceMod=false\ndataRate=500\n```\n\nand `/config/valheimplus/BepInEx.cfg`\n\n```\n[Logging.Console]\nEnabled=true\n```\n\nAll existing configuration in those files is retained and a backup of the old config is created as e.g. `/config/valheimplus/valheim_plus.cfg.old` before writing the new config file.\n\nYou could generate your own custom plugin config from environment variables using [the `POST_BEPINEX_CONFIG_HOOK` event hook](#event-hooks) and [`env2cfg`](https://github.com/lloesche/valheim-server-docker/tree/main/env2cfg).\n\n# System requirements\n\nOn our system while idle with no players connected Valheim server consumes around 2.8 GB RSS. All the while using around 30% of one CPU Core on a 2.40 GHz Intel Xeon E5-2620 v3. Valheim server is making use of many threads with two of them seemingly doing the bulk of the work each responsible for around 8-10% of the 30% of idle load.\n\nThe picture changes when players connect. The first player increased overall load to 42%, the second player to 53%. In the thread view we see that a thread that was previously consuming 10% is now hovering around 38%. Meaning while Valheim server creates 50 threads on our system it looks like there is a single thread doing the bulk of all work (~70%) with no way for the Kernel to distribute the load to many cores.\n\nTherefore our minimum requirements would be a dual core system with 4 GB of RAM and our recommended system would be a high clocked 4 core server with 8 GB of RAM. A few very high clocked cores will be more beneficial than having many cores. I.e. two 5 GHz cores will yield better performance than six 2 GHz cores.\nThis holds especially true the more players are connected to the system.\n\n# Deployment\n\n## Deploying with Docker and systemd\n\nCreate a config file `/etc/sysconfig/valheim-server`\n\n```\nSERVER_NAME=My Server\nSERVER_PORT=2456\nWORLD_NAME=Dedicated\nSERVER_PASS=secret\nSERVER_PUBLIC=true\n```\n\nThen enable the Docker container on system boot\n\n```\n$ sudo mkdir -p /etc/valheim /opt/valheim\n$ sudo curl -o /etc/systemd/system/valheim.service https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/valheim.service\n$ sudo systemctl daemon-reload\n$ sudo systemctl enable valheim.service\n$ sudo systemctl start valheim.service\n```\n\n## Deploying with docker compose\n\nCopy and paste the following into your shell\n\n```\nmkdir -p $HOME/valheim-server/config $HOME/valheim-server/data\ncd $HOME/valheim-server/\ncat \u003e $HOME/valheim-server/valheim.env \u003c\u003c EOF\nSERVER_NAME=My Server\nWORLD_NAME=Dedicated\nSERVER_PASS=secret\nSERVER_PUBLIC=true\nEOF\ncurl -o $HOME/valheim-server/docker-compose.yaml https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/docker-compose.yaml\ndocker compose up -d\n```\n\n## Deploying to Kubernetes\n\nKubernetes manifests using this container image, along with a helm chart, are available from the following repository:\n[https://github.com/Addyvan/valheim-k8s](https://github.com/Addyvan/valheim-k8s)\n\nThe chart is also available directly using:\n\n```bash\nhelm repo add valheim-k8s https://addyvan.github.io/valheim-k8s/\nhelm repo update\nhelm install valheim-server valheim-k8s/valheim-k8s # see repo for full config\n```\n\n## Deploying to AWS ECS\n\nCDK Project for spinning up a Valheim game server on AWS Using ECS Fargate and Amazon EFS is available here:\n[https://github.com/rileydakota/valheim-ecs-fargate-cdk](https://github.com/rileydakota/valheim-ecs-fargate-cdk)\n\n## Deploying to Nomad\n\n```\n$ sudo mkdir -p /var/lib/valheim/{config,data}\n$ sudo curl -o /var/lib/valheim/valheim.nomad https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/valheim.nomad\n$ sudo nomad job run /var/lib/valheim/valheim.nomad\n```\n\n# Updates\n\nBy default the container will check for Valheim server updates every 15 minutes if no players are currently connected to the server.\nIf an update is found it is downloaded and the server restarted.\nThis update schedule can be changed using the `UPDATE_CRON` environment variable.\n\n# Crossplay\n\nBy default the container only allow Steam clients. If you enable the `CROSSPLAY=true` option the server will switch from Steam matchmaking to PlayFab, allowing Xbox and Microsoft Store clients to connect. When enabling crossplay, a third port is opened (2458 UDP) used for the crossplay backend communication.\n\nNote that some mods may not work well or at all with crossplay enabled, which is why it is not enabled by default.\n\n## When you need crossplay\n\n- You want Xbox/Microsoft Store players to be able to join.\n- Your player base spans both Steam and Xbox platforms.\n\n## When you do not\n\n- All players use Steam (Windows, Linux, or Steam Deck).\n\n## Network Ports\n\n| Purpose                  | Port |\n| ------------------------ | ---- |\n| Game traffic (UDP)       | 2456 |\n| Steam matchmaking (UDP)  | 2457 |\n| Crossplay (PlayFab, UDP) | 2458 |\n\n# Backups\n\nThe container will on startup and periodically create a backup of the `worlds_local/` directory.\n\nThe default is once per hour but can be changed using the `BACKUPS_CRON` environment variable.\n\nDefault backup directory is `/config/backups/` within the container. A different directory can be set using the `BACKUPS_DIRECTORY` environment variable.\nIt makes sense to have this directory be a volume mount from the host.\nWarning: do not make the backup directory a subfolder of `/config/worlds_local/`. Otherwise each backup will backup all previous backups.\n\nBy default 3 days worth of backups will be kept. A different number can be configured using `BACKUPS_MAX_AGE`. The value is in days.\n\nIt is possible to configure a maximum number of to-be-kept backup files with `BACKUPS_MAX_COUNT`. When going over this limit, the oldest file(s) will be deleted. The default is `0` which means no limit. Note that `BACKUPS_MAX_AGE` will always be respected: if backups get too old, they will be deleted even if `BACKUPS_MAX_COUNT` was not yet reached (or is `0`).\n\nBeware that backups are performed while the server is running. As such files might be in an open state when the backup runs.\nHowever the `worlds_local/` directory also contains a `.db.old` file for each world which should always be closed and in a consistent state.\n\nSee [Copy backups to another location](#copy-backups-to-another-location) for an example of how to copy backups offsite.\n\nIf `BACKUPS_IF_IDLE=false` then backups are only created if there has been recent player activity. Once the last player disconnects\nthere is a grace period `BACKUPS_IDLE_GRACE_PERIOD` in seconds after which backups are still being created. The reason for this is that Valheim\ndedicated server only saves the world in 20 minute intervals and on shutdown. So to make sure that we have a consistent world file backup of\nthe most recent changes we want to wait out one world save. This grace period also needs to be long enough so that our `BACKUPS_CRON` had a chance to run.\n\n`BACKUPS_ZIP=false` can be used to store backups uncompressed in the backup directory. Please note that this will increase the filesize of the backups, due to no compression.\n\n## Manual backup\n\nSending `SIGHUP` to the `valheim-backup` service or restarting the service will create a backup.\nIf `BACKUPS_IF_IDLE=false` sending `SIGHUP` only creates a backup if there has been recent player activity.\nRestarting `valheim-backup` will always create a backup.\n\nThe PID of the running service can be found in `/var/run/valheim-backup.pid`\n\nAssuming your container's name is `valheim-server` here's how both would work:\n\nSending SIGHUP using `supervisorctl`\n\n```\ndocker exec -it valheim-server supervisorctl signal HUP valheim-backup\n```\n\nSending SIGHUP manually\n\n```\ndocker exec -it valheim-server bash -c 'kill -HUP $(\u003c /var/run/valheim-backup.pid)'\n```\n\nRestarting `valheim-backup`\n\n```\ndocker exec -it valheim-server supervisorctl restart valheim-backup\n```\n\nThe restart can also be done from [the Supervisor web UI](#supervisor).\n![Backup Step 1](https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/misc/backup1.png \"Backup Step 1\")\n\n# Finding Your Server\n\nOnce the server is up and running and the log says something like\n\n```\n02/09/2021 10:42:24: Game server connected\n```\n\nit can still be challenging to actually find the server.\n\nThere are three ways of getting to your server. Either using the Steam server browser, adding the IP manually or using the in-game `Community` server list.\n\n## In-game\n\nWhen in-game, click on `Join Game` and select `Community`. Wait for the game to load the list of all 4000+ servers.\nOnly 200 servers will be shown at a time so we will have to enter part of our server name to filter the view.\n![in-game server browser](https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/misc/find1.png \"in-game server browser\")\n\n### Joining Directly via Hostname/IP\n\nValheim has since added the `Join IP` button to the `Join Game` tab. If you click the `Join IP` button, you are prompted to enter your server's IP address and port number.\nIf you left the `SERVER_PORT` at its default value of `2456`, you do not have to enter the port. The hostname or IP of your server will suffice.\nIf you changed the port, you have to specify it like this: `example.com:3333`.\n\nThis method of connecting to your server will work even if your server is not public (i.e., you set `SERVER_PUBLIC` to `false`).\n\n![in-game server browser with join ip button](./misc/find5.png \"in-game server browser with join ip button\")\n![join ip dialog](./misc/find6.png \"join ip dialog\")\n\n## Steam Server Browser\n\nWhen using the Steam server browser, in Steam go to `View -\u003e Servers`. Click on `CHANGE FILTERS` and select Game `Valheim`.\nWait for Steam to load all 4000+ Servers then sort the `SERVERS` column by clicking on its title. Scroll down until you find your server.\n![Steam server browser](https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/misc/find2.png \"Steam server browser\")\nFrom there you can right-click it and add as a favourite.\n\nNote that in my tests when connecting to the server via the Steam server browser I had to enter the server password twice. Once in Steam and once in-game.\n\n## Steam Server Favorites \u0026 LAN Play\n\nA third option within Steam is to add the server manually by IP. This also allows for LAN play without the need to open or forward any firewall ports.\n\nRemark: LAN-Play is only available for Steam-Version without CrossPlay enabled! See official Valheim Dedicated Server Manual.pdf in the data/server folder.\n\nSteps:\n\n1. Within Steam click on `View -\u003e Servers`\n2. `FAVORITES`\n3. `ADD SERVER`\n4. Enter Server IP and port+1. So if the server is running on UDP port `2456` enter `ip:2457`\n5. `FIND GAMES AT THIS ADDRESS...`\n6. `ADD SELECTED GAME SERVER TO FAV...`\n\n![Add server manually](https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/misc/find3.png \"Add server manually\")\n\nDo not use the `ADD THIS ADDRESS TO FAVORITES` button at this point.\n\nNOTE: Sometimes I will get the following error when trying to connect to a LAN server:\n![Steam Server Browser Error](https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/misc/find4.png \"Steam Server Browser Error\")\n\nIn those cases it sometimes helped to add the server again, but this time using port `2456` and now pressing the `ADD THIS ADDRESS TO FAVORITES` button.\nIt will not generate a new entry in the favourites list but seemingly just update the existing one that was originally discovered on port `2457`.\n\nSometimes it also helps to press the `REFRESH` button and then immediately double click on the Server.\n\nOverall LAN play via the Steam Server Browser has been a bit hit and miss for me while online play using the in-game search has resulted in the most consistent success.\n\nNOTE 2: You will only find your Valheim game server using this method if your server is public (`SERVER_PUBLIC` is NOT set to `false`).\nIf you started your server with `SERVER_PUBLIC` set to `false`, you will get the error message: `Server is not responding.` in the list where the servers are supposed to appear.\n\n# Admin Commands\n\nUpon startup the server will create a file `/config/adminlist.txt`. In it you can list the IDs of all administrator users.\n\nThe ID of a user can be gotten either in-game by pressing **_F2_**\n![User ID in-game](https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/misc/admin2.png \"User ID in-game\")\n\nor in the server logs when a user connects.\n![User ID in logs](https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/misc/admin1.png \"User ID in logs\")\n\nAdministrators can press **_F5_** to open the in-game console and use commands like `ban` and `kick`.\n![Kick a user](https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/misc/admin3.png \"Kick a user\")\n\n## Enable Admin Console\n\nIn recent versions of Valheim the game client has to be started with the `-console` flag for **_F5_** to work.\n![Enable Admin Console](https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/misc/admin_console1.png \"Enable Admin Console\")\n\n# Supervisor\n\nThis container uses a process supervisor aptly named [`supervisor`](http://supervisord.org/).\nWithin the container processes can be started and restarted using the command `supervisorctl`. For instance `supervisorctl restart valheim-server` would restart the server.\n\nSupervisor provides a very simple http interface which can be optionally turned on by supplying `SUPERVISOR_HTTP=true` and a password in `SUPERVISOR_HTTP_PASS`.\nThe default `SUPERVISOR_HTTP_USER` is `admin` but can be changed to anything else. Once activated the http server will listen on tcp port `9001` which has to be exposed (`-p 9001:9001/tcp`).\n\n![Supervisor](https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/misc/supervisor.png \"Supervisor\")\n\n## Supervisor API\n\nIf Supervisor's http server is enabled it also provides an XML-RPC API at `/RPC2`. Details can be found in [the official documentation](http://supervisord.org/api.html).\n\n# Status web server\n\nIf `STATUS_HTTP` is set to `true` the status web server will be started.\nBy default it runs on container port `80` but can be customized using `STATUS_HTTP_PORT`.\n\nThis only works for public Valheim servers (`SERVER_PUBLIC=true`) because private ones do not answer to [Steam server queries](https://developer.valvesoftware.com/wiki/Server_queries).\n\nA `/status.json` will be updated every 10 seconds.\n\nWhenever Valheim server is not yet running the status will contain an error like\n\n```\n{\n  \"last_status_update\": \"2021-03-07T21:42:46.307232+00:00\",\n  \"error\": \"timeout('timed out')\"\n}\n```\n\nThe error is just a string representation of whatever Python exception was thrown when trying to connect to the query port (`2457/udp` by default).\n\nOnce the server is running and listening on its UDP ports `/status.json` will contain something like this\n\n```\n{\n  \"last_status_update\": \"2021-03-07T21:42:16.076662+00:00\",\n  \"error\": null,\n  \"server_name\": \"My Docker based server\",\n  \"server_type\": \"d\",\n  \"platform\": \"l\",\n  \"player_count\": 1,\n  \"password_protected\": true,\n  \"vac_enabled\": false,\n  \"port\": 2456,\n  \"steam_id\": 90143789459088380,\n  \"keywords\": \"0.147.3@0.9.4\",\n  \"game_id\": 892970,\n  \"players\": [\n    {\n      \"name\": \"\",\n      \"score\": 0,\n      \"duration\": 7.000421047210693\n    }\n  ]\n}\n```\n\nAll the information in `status.json` is fetched from Valheim servers public query port. You will notice that some of the fields like player name or player score currently contain no information. However for completeness the entire query response is left intact.\n\nWithin the container `status.json` is written to `STATUS_HTTP_HTDOCS` which by default is `/opt/valheim/htdocs`. It can either be consumed directly or the user can add their own html/css/js to this directory to read the json data and present it in whichever style they prefer. A file named `index.html` will be shown on `/` if it exists.\n\nAs mentioned all the information is publicly available on the Valheim server query port. However the option is there to configure a `STATUS_HTTP_CONF` (`/config/httpd.conf` by default) containing [busybox httpd config](https://git.busybox.net/busybox/tree/networking/httpd.c) to limit access to the status web server by IP/subnet or login/password.\n\n## Monitoring with UptimeKuma\n\nThe status web server can be monitored using [UptimeKuma](https://github.com/louislam/uptime-kuma), a popular open source monitoring tool. UptimeKuma supports [JSONata](https://docs.jsonata.org/overview.html) expressions which can be used to determine the health of your Valheim server.\n\nTo monitor your server:\n\n1. Set up UptimeKuma according to their documentation\n2. Add a new monitor with type \"HTTP(s) - Json Query\"\n3. Enter the URL to your status endpoint (e.g., `http://your-server-ip:80/status.json`)\n4. Under \"Json Query\", enter the following:\n\n```\n(\n   $now := $toMillis($now()[0]);  /* Extract first element of $now() array */\n   $lastUpdate := $toMillis(last_status_update);\n   $minutesDiff := ($now - $lastUpdate) / 60000;  /* Difference in minutes */\n   error = null and $minutesDiff \u003c= 1 ? \"healthy\" : \"unhealthy\"\n)\n```\n\n6. Set \"Expected Value\" to `healthy`\n\nThis JSONata expression checks two conditions:\n\n- The server has no errors (`error = null`)\n- The status has been updated within the last minute (`$minutesDiff \u003c= 1`)\n\nIf both conditions are met, the monitor will return \"healthy\", otherwise \"unhealthy\". This provides a simple way to ensure your Valheim server is running properly.\n\n# Modding\n\nRemark: Some Mods are using RPC commands, which needs gameport+2 for communication (e.g. if you're using gamport 2456, you have to open port 2458 too for the network: 2456-2458:2456-2458/udp) and in your firewall rules (if defined).\n\n## BepInExPack Valheim\n\n**Enable with**\n| Variable | Value |\n|----------|----------|\n| `BEPINEX` | `true` |\n\n[BepInExPack Valheim](https://valheim.thunderstore.io/package/denikson/BepInExPack_Valheim/) packages [BepInEx](https://github.com/BepInEx/BepInEx) for Valheim. BepInEx is a plugin / modding framework for Unity Mono, IL2CPP and .NET framework games.\nTo enable BepInExPack provide the env variable `BEPINEX=true`. This can not be specified together with `VALHEIM_PLUS=true`.\nJust like Valheim Server this mod is automatically updated using the `UPDATE_CRON` schedule.\n\nUpon first start BepInExPack will create a new directory `/config/bepinex` where its config files are located.\nBepInEx plugins must be copied into the `/config/bepinex/plugins/` directory. From there they will be automatically copied into `/opt/valheim/bepinex/BepInEx/plugins/` on install/update.\n\n### Configuration\n\nSee [Mod config from Environment Variables](#mod-config-from-environment-variables)\n\n## ValheimPlus\n\n**Enable with**\n| Variable | Value |\n|----------|----------|\n| `VALHEIM_PLUS` | `true` |\n\n[ValheimPlus](https://github.com/valheimPlus/ValheimPlus) is a popular Valheim mod based on BepInEx.\nIt has been incorporated into this container. To enable V+ provide the env variable `VALHEIM_PLUS=true`. This can not be specified together with `BEPINEX=true`.\nUpon first start V+ will create a new directory `/config/valheimplus` where its config files are located.\nAs a user you are mainly concerned with the values in `/config/valheimplus/valheim_plus.cfg`.\nFor most modifications the mod has to be installed both, on the server as well as all the clients that connect to the server.\nA few modifications, like for example changing the `dataRate` can be done server only.\n\n### Updates\n\nValheimPlus is automatically being updated using the same `UPDATE_CRON` schedule the Valheim server uses to check for updates. If an update of either\nValheim server or ValheimPlus is found it is being downloaded, configured and the server automatically restarted.\nThis also means your clients always need to run the latest ValheimPlus version or will not be able to connect. If this is undesired the schedule could be changed to only check for updates once per day. Example `UPDATE_CRON='0 6 * * *'` would only check at 6 AM.\n\n### Configuration\n\nSee [Mod config from Environment Variables](#mod-config-from-environment-variables)\n\n#### Disable server password\n\nAnother popular mod for LAN play that does not require the clients to run ValheimPlus is to turn off password authentication.\n\nTo do so enable ValheimPlus (`VALHEIM_PLUS=true`), set an empty password (`SERVER_PASS=\"\"`), make the server non-public (`SERVER_PUBLIC=false`) and configure the following section in `/config/valheimplus/valheim_plus.cfg`\n\n```\n[Server]\nenabled=true\nenforceMod=false\ndisableServerPassword=true\n```\n\nAlternatively start with `-e VPCFG_Server_enabled=true -e VPCFG_Server_enforceMod=false -e VPCFG_Server_disableServerPassword=true`.\n\nEnsure that the server can not be accessed from the public Internet. If you like to have the LAN experience but over the Internet I can highly recommend [ZeroTier](https://www.zerotier.com/). It is an open source VPN service where you can create a virtual network switch that you and your friends can join. It is like Hamachi but free and open source. They do have a paid product for Businesses with more than 50 users. So for more than 50 users you could either get their Business product or alternatively would have to host the VPN controller yourself.\n\n# Changing startup CMD in Portainer\n\nPortainer retains the startup CMD from the first time the container ist deployed. This is also true if the container is updated using \"Recreate\" in combination with \"Pull latest image\".\n\nRecent changes made it so that the startup CMD of the image was changed. To avoid recreating the container from scratch you can use the \"Duplicate/Edit\" function of Portainer by following the instructions outlined below.\n\n![Portainer Step 1](https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/misc/portainer_step1.png \"Portainer Step 1\")\n\nStop the old container (1) and edit the name (2)\n\n![Portainer Step 2](https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/misc/portainer_step2.png \"Portainer Step 2\")\n\nAppend `_old` or similar to the name (3) save the change (4) and click \"Duplicate/Edit\" (5)\n\n![Portainer Step 3](https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/misc/portainer_step3.png \"Portainer Step 3\")\n\nChange the name back to original name (2) (3) (4).\n\nUnter Advanced container settings override (6) the command and enter `/usr/local/sbin/bootstrap` (7)\n\nMake sure \"Always pull the image\" is enabled.\n\nclick \"Deploy the container\" to finish.\n\nIf your server starts and is working delete the old unused image and the old container.\n\n# Synology Help\n\n## First install\n\nThis is not an extensive tutorial, but I hope these screenshots can be helpful.\nBeware that the server can use multiple GB of RAM and produces a lot of CPU load.\n\n![Step 1](https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/misc/step1.png \"Step 1\")\n![Step 2](https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/misc/step2.png \"Step 2\")\n![Step 3](https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/misc/step3.png \"Step 3\")\n![Step 4](https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/misc/step4.png \"Step 4\")\n![Step 5](https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/misc/step5.png \"Step 5\")\n![Step 6](https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/misc/step6.png \"Step 6\")\n![Step 7](https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/misc/step7.png \"Step 7\")\n![Step 8](https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/misc/step8.png \"Step 8\")\n\n## Updating the container image to the latest version\n\nThe process of updating the image clears all data stored inside the container. So before doing a container image upgrade, make absolutely sure that `/config`, which contains your world, is an external volume stored on your NAS (Step 4 of the [First install](#first-install) process). It is also a good idea to copy the latest version of the world backup to another location, like your PC.\n![Update Step 1](https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/misc/update1.png \"Update Step 1\")\n![Update Step 2](https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/misc/update2.png \"Update Step 2\")\n![Update Step 3](https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/misc/update3.png \"Update Step 3\")\n![Update Step 4](https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/misc/update4.png \"Update Step 4\")\n![Update Step 5](https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/misc/update5.png \"Update Step 5\")\n![Update Step 6](https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/misc/update6.png \"Update Step 6\")\n\n### Error after download of new container image\n\nIf you are getting the following error after an Update:\n![Error Step 1](https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/misc/synology_upgrade_error1.png \"Error Step 1\")\n\n![Error Step 2](https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/misc/synology_upgrade_error2.png \"Error Step 2\")\n\n```\n\"Failure: OCI runtime create failed: container_linux.go:367: [...]\"\n```\n\nYou will need to remove the container completely and perform the [First install](#first-install) steps again.\n![Error Step 3](https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/misc/synology_upgrade_error3.png \"Error Step 3\")\n\nMake sure to use the same folder settings as before so the existing `/config` and `/opt/valheim` directories are used.\n\nThe error is caused by Synology using the old image's `CMD` with the newly downloaded image. By removing the container and recreating it we're forcing Synology to use the new images `CMD`.\n\n# QNAP NAS Help\n\n## Creating container\n\nAs a prerequisite you need to create a folder where you will keep your saves, backups and configuration.\n\nHere is an example `docker-compose.yaml` file that we will use in the next steps.\n\n```yaml\nservices:\n  valheim:\n    image: lloesche/valheim-server\n    cap_add:\n      - sys_nice\n    volumes:\n      - /share/CACHEDEV1_DATA/{path_to_folder}/config:/config\n      - /share/CACHEDEV1_DATA/{path_to_folder}/data:/opt/valheim\n    ports:\n      - \"2456-2457:2456-2457/udp\"\n      - \"9001:9001/tcp\"\n    env_file:\n      - /share/CACHEDEV1_DATA/{path_to_folder}/valheim.env\n    restart: always\n    stop_grace_period: 2m\n    deploy:\n      resources:\n        limits:\n          cpus: \"0.70\"\n          memory: 4gb\n```\n\nThe most important part is `/share/CACHEDEV1_DATA/{path_to_folder}/config`. You need to replace **{path_to_folder}** with the folder path where you want to store data and configuration for your Valheim server.\n\nChange your memory and cpu limit according to your available resources on QNAP. Current settings are 70% of single CPU and 4gb of RAM.\n\nIn this folder you need to create a file `valheim.env` to store configuration variables.\n\nExample `valheim.env`:\n\n```\nSERVER_NAME=My Server\nWORLD_NAME=Dedicated\nSERVER_PASS=secret\nSERVER_PUBLIC=true\n```\n\n![Qnap Step 1](https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/misc/qnap_create_button.png \"Qnap Step 1\")\n\n![Qnap Step 2](https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/misc/qnap_create_application.png \"Qnap Step 2\")\n\n![Qnap Step 3](https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/misc/qnap_create_yaml.png \"Qnap Step 3\")\n\n## Updating image\n\n![Qnap update Step 1](https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/misc/qnap_update_resources.png \"Qnap update Step 1\")\n\n![Qnap update Step 2](https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/misc/qnap_update_button.png \"Qnap update Step 2\")\n\nIn the image name you have to specify the image from the container definition `lloesche/valheim-server`.\n\n![Qnap update Step 3](https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/misc/qnap_update_pull.png \"Qnap update Step 3\")\n\nAfter the image is downloaded restart the container. As you can see the old image is now unused and the new one is in use by the container. You can now safely delete the old image.\n\n![Qnap update Step 4](https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/misc/qnap_update_images.png \"Qnap update Step 4\")\n\n## QNAP ZFS issue\n\nWe have had [a report from a QNAP user](https://github.com/lloesche/valheim-server-docker/issues/275) where Steam failed when using ZFS as the backing filesystem with the following error\n\n```\nvalheim-updater [ 0%] !!! Fatal Error: Steamcmd needs 250MB of free disk space to update.\nvalheim-updater src/tier0/threadtools.cpp (3553) : Assertion Failed: Illegal termination of worker thread 'Thread(0x0x58a1d8f0/0x0xf7780b'\n```\n\nThis appears to be due to a bad Steam/ZFS interaction akin to [this Steam bug](https://github.com/ValveSoftware/steam-for-linux/issues/4982) where very large ZFS volumes get interpreted as very small due to bad overflow handling. There are two workarounds available. Use a non-ZFS volume, or set a quota on the volume, e.g.:\n\n1. Connect to the QNAP SSH console.\n2. Get the ZFS volume ID from within the container\n\n```\ndf /opt/valheim | tail -n 1 | awk '{ print $1 }'\n```\n\n3. Set the quota to 2TB or less from the QNAP SSH console:\n\n```\nzfs set quota=1TB \"volume_id_here\"\n```\n\nYou could also try this one-liner from the SSH console:\n\n```\nCONTAINER=\"your_valheim_container name/id\" \\\n  docker exec -t \"$CONTAINER\" df /opt/valheim | tail -n 1 | awk '{ print $1 }' | \\\n  xargs -I zfs_id sudo zfs set quota=1TB zfs_id\n```\n\nIf you have access to a QNAP NAS running ZFS and can reproduce/debug this issue further, please open a new issue with your findings so we can update this section and provide more information here.\n\n# OpenMediaVault Help\n\n## Permission denied error\n\nIf you are running this container in Portainer on a OpenMediaVault NAS and getting the following error\n\n```\nvalheim-server /usr/local/bin/valheim-server: line 110: /opt/valheim/server/valheim_server.x86_64: Permission denied\n```\n\nthe cause is that the container's filesystem is mounted with the `noexec` flag. Meaning no files are allowed to be executed on that filesystem.\n\nSee [this page](https://openmediavault.readthedocs.io/en/5.x/various/fs_env_vars.html) for detailed information on how to disable noexec for newly created and existing filesystems.\n\nFor existing filesystems edit `/etc/openmediavault/config.xml` and remove the `noexec` option from the filesystem in question. The file should look something like this\n\n![OMV 1](https://raw.githubusercontent.com/lloesche/valheim-server-docker/main/misc/omv1.png \"OMV Step 1\")\n\n# License\n\nCopyright 2021 [Lukas Lösche](mailto:lukas@opensourcery.de)\n\nLicensed under the Apache License, Version 2.0 (the \"License\");  \nyou may not use this file except in compliance with the License.  \nYou may obtain a copy of the License at\n\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;[http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)\n\nUnless required by applicable law or agreed to in writing, software  \ndistributed under the License is distributed on an \"AS IS\" BASIS,  \nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  \nSee the License for the specific language governing permissions and  \nlimitations under the License.\n\n# Legal disclaimer\n\nThis Docker container is not endorsed by, directly affiliated with, maintained, authorized, or sponsored by [Iron Gate Studio](https://irongatestudio.se/).  \n[Valheim](https://www.valheimgame.com/), [Valheim dedicated server](https://steamcommunity.com/app/896660/) and [the Valheim Logo](https://irongatestudio.se/onewebmedia/ValheimPresskit.zip) are © 2021 Iron Gate Studio.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flloesche%2Fvalheim-server-docker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flloesche%2Fvalheim-server-docker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flloesche%2Fvalheim-server-docker/lists"}