Dedicated Valheim server with insights
In this blog post, I will talk about how I have set up our server on Google Cloud, installed Valheim, and added some metrics to Grafana Cloud. Valheim is a brutal exploration and survival game for 1-10 players, set in a procedurally-generated purgatory inspired by viking culture. At Fullstaq where I work, we wanted to be able to play this game on our own server!
But Wiard, you are a Kubernetes fanboy, why a VPS?
I like Kubernetes. Yet it’s not the solution to everything. What I wanted was a minimum effort, maximum satisfaction. Hosting a game-server, especially one like Valheim is not that suitable for a cloud-native build. Especially when I only want one server. It requires a volume, it cannot be scaled over multiple instances/pods nor is there any way to make it highly available. I also need multiple TCP & UDP ports to be available, which is doable in Kubernetes but it’s not that simple as an HTTP load balancer.
Google Cloud Compute Engine
I manually added an instance “e2-medium (2 vCPUs, 4 GB memory)” with the image “ubuntu-1604-xenial-v20210211” and gave it a 30GB SSD persistent disk.
I also gave it a network tag “valheim” for our firewall setup later on.
Why manual and not via Terraform or any other form of infra-as-code? Because it’s just a one-time thing. It’s going to be a temporary project. Let me show you this XKCD https://xkcd.com/1205/

Firewall
For TCP I opened: 2456-2458,27015-27030,27036-27037 For UDP: 2456-2458,4380,27000-27031,27036 The source range is 0.0.0.0/0 (everything) and the target we do by our tag “valheim”.

Linux GSM
Linux Game Server Manager is something I found while using Google on how to host a Valheim server. https://linuxgsm.com/ - It’s pretty great to just set something up.
Let me talk you through on how to set this up;
Adding dependecies:
sudo dpkg --add-architecture i386; sudo apt update; sudo apt install curl wget file tar bzip2 gzip unzip bsdmainutils python util-linux ca-certificates binutils bc jq tmux netcat lib32gcc1 lib32stdc++6 steamcmd libsdl2-2.0-0:i386 libsdl2-2.0-0
Adding the user (which needs sudo rights)
sudo adduser vhserver
Adding sudo rights
sudo visudo
And then add the following:
vhserver ALL=(ALL) NOPASSWD:ALL
Next we move towards our user and start installing things:
su - vhserver
wget -O linuxgsm.sh https://linuxgsm.sh && chmod +x linuxgsm.sh && bash linuxgsm.sh vhserver
./vhserver install
And follow the instructions that follow in the install.
I recommend reading the usage of vhserver
here: https://linuxgsm.com/lgsm/vhserver/
Configuration
Next we add a file for our gameserver that overrides the defaults:
vi /home/vhserver/lgsm/config-lgsm/vhserver/vhserver.cfg
In which you can add the following:
steammaster="true"
servername="YourServerName"
# Minimum password length is 5.
serverpassword="yourpassword"
port="2456"
gameworld="${selfname}"
public="1"
You also could view the configuration in /home/vhserver/lgsm/config-lgsm/vhserver/_default.cfg
and change values of this by adding them to /home/vhserver/lgsm/config-lgsm/vhserver/common.cfg
Getting insights
So I also wanted to monitoring our server or alteast have some insights. Therefor I will use Prometheus with a Prometheus node exporter and Grafana cloud.
setting up Grafana cloud
Go to: https://grafana.com/signup/cloud/connect-account?pg=prod-cloud&plcmt=hero-btn1
Which gives free forever access:
- 3 users
- 10k active metrics
- 50GB Logs
- 2 week data retention
When you are all set, login and go to: https://grafana.com/orgs/{your-org-name}/api-keys
and generate an API key with the role MetricsPublisher
Save this data for our next steps, as we are going to write Prometheus data to this.
Prometheus setup
I’m just going to copy/paste my commands. If you want more information on what/how, I would recommend reading other guides on how Prometheus works and how to properly set this up.
sudo useradd --no-create-home --shell /bin/false prometheus
sudo useradd --no-create-home --shell /bin/false node_exporter
sudo mkdir /etc/prometheus
sudo mkdir /var/lib/prometheus
sudo chown prometheus:prometheus /etc/prometheus
sudo chown prometheus:prometheus /var/lib/prometheus
cd ~
curl -LO https://github.com/prometheus/prometheus/releases/download/v2.25.0/prometheus-2.25.0.linux-amd64.tar.gz
tar xvf prometheus-2.25.0.linux-amd64.tar.gz
sudo cp prometheus-2.25.0.linux-amd64/prometheus /usr/local/bin/
sudo cp prometheus-2.25.0.linux-amd64/promtool /usr/local/bin/
sudo chown prometheus:prometheus /usr/local/bin/prometheus
sudo chown prometheus:prometheus /usr/local/bin/promtool
sudo cp -r prometheus-2.25.0.linux-amd64/consoles /etc/prometheus
sudo cp -r prometheus-2.25.0.linux-amd64/console_libraries /etc/prometheus
sudo chown -R prometheus:prometheus /etc/prometheus/consoles
sudo chown -R prometheus:prometheus /etc/prometheus/console_libraries
rm -rf prometheus-2.25.0.linux-amd64.tar.gz prometheus-2.25.0.linux-amd64
We are also going to use a node exporter:
curl -LO https://github.com/prometheus/node_exporter/releases/download/v1.1.1/node_exporter-1.1.1.linux-amd64.tar.gz
tar -xvf node_exporter-1.1.1.linux-amd64.tar.gz
sudo cp node_exporter-1.1.1.linux-amd64/node_exporter /usr/local/bin/
Setting up Prometheus configuration
sudo vi /etc/prometheus/prometheus.yml
Adding the folowing with the API key data we have created in our Grafana cloud step.
global:
scrape_interval: 15s
remote_write:
- url: https://prometheus-us-central1.grafana.net/api/prom/push
basic_auth:
username: your-grafana-cloud-user
password: your-grafana-cloud-password
scrape_configs:
- job_name: 'prometheus'
scrape_interval: 5s
static_configs:
- targets: ['localhost:9090']
- job_name: 'node'
scrape_interval: 5s
static_configs:
- targets: ['localhost:9100']
And finish with setting the right chown:
sudo chown prometheus:prometheus /etc/prometheus/prometheus.yml
Now we add a service for Prometheus:
sudo vi /etc/systemd/system/prometheus.service
Adding:
[Unit]
Description=Prometheus
Wants=network-online.target
After=network-online.target
[Service]
User=prometheus
Group=prometheus
Type=simple
ExecStart=/usr/local/bin/prometheus \
--config.file /etc/prometheus/prometheus.yml \
--storage.tsdb.retention=1d \
--storage.tsdb.path /var/lib/prometheus/ \
--web.console.templates=/etc/prometheus/consoles \
--web.console.libraries=/etc/prometheus/console_libraries
[Install]
WantedBy=multi-user.target
And a service for our node exporter:
sudo vi /etc/systemd/system/node_exporter.service
Adding:
[Unit]
Description=Node Exporter
Wants=network-online.target
After=network-online.target
[Service]
User=node_exporter
Group=node_exporter
Type=simple
ExecStart=/usr/local/bin/node_exporter --collector.systemd --collector.processes
[Install]
WantedBy=multi-user.target
And enabling and starting everything:
sudo systemctl daemon-reload
sudo systemctl start prometheus
sudo systemctl enable prometheus
sudo systemctl start node_exporter
sudo systemctl enable node_exporter
Now we can also start our game server with:
./vhserver start
Grafana dashboard
Next we can go to Grafana and add a dashboard. I have used this one: https://grafana.com/grafana/dashboards/1860 which can be added by importing a dashboard and inputting ID: 1860
When metrics are coming in, you eventually should end up with something like this:

Enjoy playing Valheim!