2024.04.27 - Factorio Headless Server
Intro
Prace nad HomeLab/3 postępują i kolejnym ważnym krokiem jest serwerek Factorio (pewnie nawet kilka) 😁
Przygotowanie VM
Postanowiłem zainstalować Factorio Headless Server (alias FHS) na dedykowanej maszynce. W PVE wyklikałem następującą VMkę:
Następnie przygotowałem maszynę z domowego playbooka Ansibla:
- konfiguracja sshd (klucze)
- instalacja pakietów
Instalacja serwera
Serwer będzie chodził bezpośrednio na maszynie (na razie bez dockera).
Przygotowanie katalogów, użytkownika i plików (wszystkie peracje z poziomu root):
# add user
$ adduser --disabled-login --no-create-home --gecos factorio factorio
# download server
$ cd /opt
$ wget -O factorio-headless-1.1.107.tar.xz https://www.factorio.com/get-download/1.1.107/headless/linux64
$ tar -xJf factorio-headless-1.1.107.tar.xz
# prepare folders
$ cd factorio
$ mkdir saves mods
# create config
$ cp -a server-settings.example.json server-settings.json
# set permissions
$ chown -R factorio:factorio /opt/factorio
Następnie poprawiłem konfigurację serwera i ustawiłem grę prywatną z hasełkiem.
$ mcedit /opt/factorio/data/server-settings.json
---
{
"name": "HomeLab/3/Factorio",
"description": "Vanilla",
"tags": ["homelab", "nerdoza"],
"visibility":
{
"public": false,
"lan": true
},
"game_password": "<tajne-przez-poufne>",
"<inne ustawienia>": "(...)"
}
Dodatkowo utworzyłem listę adminów serwera.
$ mcedit /opt/factorio/server-adminlist.json
---
[ "kim-jestes?-jestem-adminem!" ]
Przygotowanie serwisów
Serwer będzie odpalany przez systemd. W przypadku awarii ma zostać wysłane powiadomienie na prywatną instancję ntfy.
"Główny" serwis FHS (gist)
Podczas awarii zostanie wyzwolony serwis ntfy@.service z nazwą aktualnego unitu %n. (docs)
ExecStopPost= powoduje 'fail' serwisu nawet w przypadku ręcznego zatrzymania i wysłanie powiadomienia na ntfy.
Później™ rozszerzę powiadomenia o zdarzeniach uruchomienia/zatrzymania serwera.
$ mcedit /etc/systemd/system/factorio.service
---
[Unit]
Description=Factorio Headless Server
After=network.target
OnFailure=ntfy@%n.service
[Service]
Type=simple
User=factorio
WorkingDirectory=/opt/factorio
ExecStart=/opt/factorio/bin/x64/factorio --start-server-load-latest --server-settings ./data/server-settings.json
ExecStopPost=/bin/false
Restart=on-failure
RestartSec=60s
[Install]
WantedBy=multi-user.target
Serwis do powiadomień ntfy (gist)
Przekazujemy orginalną nazwę unitu w nazwie instancji %i (docs)
$ mcedit /etc/systemd/system/ntfy@.service
---
[Unit]
Description=Notify about service failure
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/ntfy.sh %i
[Install]
WantedBy=multi-user.target
Skrypt notyfikujący ntfy (gist)
$ mcedit /usr/local/sbin/ntfy.sh
---
#!/bin/bash
# Get input
SERVICE_NAME=${1:-service_unknown}
# Local variables
NTFY_URL="https://ntfy.home/"
NTFY_AUTH="Basic <auth>"
NTFY_TOPIC=homelab
# Get status
STATUS=$(systemctl is-active $SERVICE_NAME)
# Compute message
MESSAGE=$(jq -cn '{"topic": $topic, "message": $message}' \
--arg topic "$NTFY_TOPIC" \
--arg message "Service $SERVICE_NAME is ${STATUS:-status_unknown}")
# Send notification
curl -qk --connect-timeout 5 \
-X POST $NTFY_URL \
-H "Authorization: $NTFY_AUTH" \
-H "X-Tags: rotating_light" \
-H "X-Title: $SERVICE_NAME" \
-H "X-Priority: 4" \
-H "Content-Type: application/json" \
-d "$MESSAGE"
Uruchomienie serwera
Za pierwszym razem trzeba wygenerować mapę do gry. Nie bawiłem się w żadne customizacje generatora więc komenda wygląda prosto
$ cd /opt/factorio/saves
$ sudo -u factorio /opt/factorio/bin/x64/factorio --create map01.zip
Odpalenie serwera sprowadza się kilku komend systemctl
# enable service
$ systemctl enable factorio.service
# start service
$ systemctl start factorio.service
# check status
$ systemctl status factorio.service
● factorio.service - Factorio Headless Server
Loaded: loaded (/etc/systemd/system/factorio.service; enabled; preset: enabled)
Active: active (running) since Sat 2024-04-27 20:14:04 CEST; 46min ago
Main PID: 11889 (factorio)
Tasks: 13 (limit: 2303)
Memory: 206.8M
CPU: 15.110s
CGroup: /system.slice/factorio.service
└─11889 /opt/factorio/bin/x64/factorio --start-server-load-latest --server-settings ./data/server-settings.json
Restart serwera powoduje wysłanie powiadomienia na telefon.