One of the best parts of being a self-hoster is being able to host a game server for your friends, right? Well, yes but also it can go sideways and not only because you’re a system admin for more than yourself. There are many ways but Podman, docker-compose, and Syncthing can help!

A videogame character holding a bow is standing on some rocks with a wooden building and garden behind. It has a low-poly look but with beautiful lighting.
Valheim Gameplay Screenshot

Unwarranted exposition

I plan to write a getting started guide at some point but after doing a bit of maintenance to get everything working again I wanted to share some quick thoughts. I did not want to expose Docker to the external web because running Docker as root is easier but also dangerous since root inside the container is root on host – took a bit to really understand that. There are (involved) ways to run Docker rootless and other security measures but after Docker pulled some shenanigans and Podman being almost fully API compatible, it was an easy choice to just switch to Podman.

Valheim

Valheim is a game where you explore, build, craft and conquer in a procedurally generated world inspired by Norse mythology.

Valheim is stunning game that really captured my attention and was an excellent escape during a long winter a few years ago, I describe it as Viking Minecraft. The game supports multiplayer and people have figured out how to run it headless so there’s a persistent world on a server allowing people to play and build asynchronously. It’s quite fun to play with some friends when a simple resource gathering trip turns into a harrowing boondoggle. However, there are a lot of small quality of life improvements that could make the game more enjoyable. These (and many more) things have coalesced into a mod-pack called Valheim Plus.

Valheim Plus

Valheim Plus can live alongside the game and I first used it locally for my solo game. But when a group of friends wanted to play I suggested we keep our options open to enable Valheim Plus and selectively tweak the game. All of that finally led me to this excellent container stack.

The Setup

I went through a couple of different approaches but I’m happy with a docker-compose.yaml, a valheim.env file, and the valheim_plus.cfg file to fully define the “server”. It is a bit annoying that all three files in are their separate file types but that’s just modern development.

Documentation and Version Control

I use a private git forge, Forgejo, for my self-hosted infrastructure so I can commit secrets in .env files and not worry about leaking them accidentally. I wrote up a readme file, screenshot included to show how nice self-hosted Forgejo is and how it pays to do documentation for your own sake.

Screenshot of a readme file showing from a Forgejo instance with sections for Server, Server Staus, Valheim Plus, and Podman
Readme Screenshot

Quick points on each piece of the tech stack, I hope to expound in a planned article on “self-hosting on an affordable VPS”, feedback and topics to cover are very welcome.

Podman

Podman installation is pretty straight forward. I suggest creating a separate user on the server who owns all the containers. If you’re familiar with docker, you can replace all docker commands with podman and it’ll work a treat, Redhat also has a nice article.

Docker Compose

Podman uses an equivalent… podman-compose, I appreciate them not being cute about it and going with a familiar setup. I can share the docker-compose file as is, since I’m using the .env file to store all secrets.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
  version: "3.1"

services:
  valheim-mod-prod:
    image: ghcr.io/lloesche/valheim-server
    cap_add:
      - sys_nice
    volumes:
      - ./config:/config
      - ./data:/opt/valheim
      - ./valheim_plus.cfg:/opt/valheim/plus/BepInEx/config/valheim_plus.cfg:ro
    ports:
      - "2456-2458:2456-2458/udp"
      - "9001:9001/tcp"
    env_file:
      - ./valheim.env
    restart: always
    stop_grace_period: 2m
    networks:
      - reverse_proxy

networks:
  reverse_proxy:
    name: reverse_proxy
    external: true

A couple things to point out:

  • The Valheim Plus documentation will tell you to place the valheim_plus.cfg file in the BepInEx folder (after downloading the and unzipping the mod) but that made version controlling it a bit janky so I map it directly into the location inside the container where it’s expected.
  • Also note the “:ro” at the end, it’s mounted internally as a read-only file. You will see messages in the log stating it’s read-only, that’s not an error and it works just fine. The game will download a fresh config from GitHub if there’s no file present so it’s best to make it read-only so it doesn’t get overwritten accidentally.
  • networks: reverse-proxy refers to Caddy that is proxying the requests coming to the Supervisor (running on port 9001), which is a small web-app that allows control of the pieces of the tech stack.
Web app screenshot showing control options: Restart, Stop, Clear Log, Tail -f Stdout, Tail -f Stderr for the following services: crond, syslogd, valheim-backup, valheim-bootstrap, valheim-server, valheim-updater
Supervisor Status web app

Version Control

With this setup you only have to version control the three files mentioned before: docker-compose.yaml, valheim.env (don’t share publicly), and valheim_plus.cfg (I also suggest creating a README.md with details of your specific setup and version controlling that too).

Syncthing

Syncthing is probably the odd-ball part here, it’s basically the easiest way for me to create an “on-site backup” for my “off-site server” (VPS). This really isn’t in scope but wanted to throw it out there as a cheaper place to backup those frequent and bulky (by cloud storage standards but light for home) backups that the container stack creates.

Takeaway

There are great tools out there to self-host things for fun and to be in control of your data (more on that in the future too). But being able to recreate, reproduce, with reliability requires a little planning and some documenting.

This blog doesn’t have comments but happy to discuss further on Mastodon.