LoginSignup
0
0

palworldのdedicatedサーバーをユーザごとの固有サービスとして起動する話

Posted at

α版としてリリースされたpalworldのdedicatedサーバーは定期的な再起動が必要です。
メモリの消費量が激しく、環境によっては日に複数回のプロセスの再起動が必要になります。

systemdのtimerRuntimeMaxSecを使う方法もありますが、今回はcronを使って制御をしてみました。
cronで扱うためにサービスをユーザーレベルに変更した、というのが今回の経緯です。
おそらくもっとシンプルなやり方もあるのでしょうが、自分の忘備録として残しておきます。

環境

名前 バージョン
OS Ubuntu 22.04

基本的な構築は下記の記事を踏襲しています。
起動シェルとサービスの登録(とcron)が変更箇所になります。

起動用のシェルの作成

知識

tmuxscreenと同じような仮想ターミナルを作成することができます。
下記の記事が参考になります。

https://qiita.com/shin-ch13/items/9d207a70ccc8467f7bab

今回はサーバーの起動をtmux経由で起動します。
起動時のログが消えず、万が一エラーが発生していた際に後から追うことができます。

起動シェル

/home/palworld/Steam/steamapps/common/PalServer/boot.sh

起動シェル例
#!/bin/bash

TMUX_NAME=palworld-server

case $1 in
        start)
                tmux new-session -s $TMUX_NAME -d "/home/palworld/Steam/steamapps/common/PalServer/PalServer.sh -useperfthreads -NoAsyncLoadingThread -UseMultithreadForDS"
                sleep 10;;
        stop)
                /home/palworld/rcon/rcon -a "127.0.0.1:25575" -p password "Broadcast The-server-will-restart-in-60-seconds.Please-prepare-to-exit-the-game."
                sleep 30
                /home/palworld/rcon/rcon -a "127.0.0.1:25575" -p password "Broadcast The-server-will-restart-in-30-seconds.Please-prepare-to-exit-the-game."
                sleep 20
                /home/palworld/rcon/rcon -a "127.0.0.1:25575" -p password "Broadcast The-server-will-restart-in-10-seconds.Please-prepare-to-exit-the-game."
                sleep 5
                /home/palworld/rcon/rcon -a "127.0.0.1:25575" -p password "Broadcast The-server-will-restart-in-5-seconds.Please-prepare-to-exit-the-game."
                sleep 1
                /home/palworld/rcon/rcon -a "127.0.0.1:25575" -p password "Broadcast The-server-will-restart-in-4-seconds.Please-prepare-to-exit-the-game."
                sleep 1
                /home/palworld/rcon/rcon -a "127.0.0.1:25575" -p password "Broadcast The-server-will-restart-in-3-seconds.Please-prepare-to-exit-the-game."
                sleep 1
                /home/palworld/rcon/rcon -a "127.0.0.1:25575" -p password "Broadcast The-server-will-restart-in-2-seconds.Please-prepare-to-exit-the-game."
                sleep 1
                /home/palworld/rcon/rcon -a "127.0.0.1:25575" -p password "Broadcast The-server-will-restart-in-1-seconds.Please-prepare-to-exit-the-game."
                sleep 5
                /home/palworld/rcon/rcon -a "127.0.0.1:25575" -p password "Shutdown 5 shutdown "
                sleep 5;;
        *)
                echo "start | stop"
esac

サービスの登録

ユーザー固有の.serviceファイルの作成

知識

ユーザー固有のサービスにするためには、以下の2つが必要になります。

  • 該当のユーザーにsshでログインができること
  • ~/.config/systemd/user/"service-name".serviceのユニットファイル

ユニットファイル

今回は以下のファイルを作成しました。
必要に応じて所有者を変更しておいてください。
~/.config/systemd/user/palworld-dedicated.service

ユニットファイル例
[Unit]
Description=Palworld Dedicated Server

[Service]
WorkingDirectory=/home/palworld/Steam/steamapps/common/PalServer/
ExecStart=/bin/bash /home/palworld/Steam/steamapps/common/PalServer/boot.sh start
ExecStop=/bin/bash /home/palworld/Steam/steamapps/common/PalServer/boot.sh stop
TimeoutStartSec=300
Restart=always
RemainAfterExit=yes

[Install]
WantedBy=default.target

ユーザーレベルのユニットファイルでは、通常のユニットファイルとは使えるディレクティブが違います。
基本的には同じものが使えますが、UserGroupが使えません。

もし、すでにサービスとして/etc/systemd/system/hogehoge.serviceを登録しているのであれば、解除をしておいてください。

サービスの起動

知識

対象のユーザーにsshでログインしてから実行してください。
ユーザー固有のサービスの起動にはsudoをつける必要がありません。
その代わりに--userをつけて実行する必要があります。

su - hogehogeでは失敗するため注意が必要です。
おそらく下記のエラーで弾かれます。
Failed to connect to bus: $DBUS_SESSION_BUS_ADDRESS and $XDG_RUNTIME_DIR not defined (consider using --machine=<user>@.host --user to connect to bus of other user)

起動

サービスファイルを再読み込みします。

systemctl --user daemon-reload 

サービスを起動します

systemctl --user start palworld-dedicated.service

一度状態を確認します。

systemctl --user status palworld-dedicated.service
結果

palworld@palworld:~$ systemctl --user status palworld-dedicated.service
● palworld-dedicated.service - Palworld Dedicated Server
Loaded: loaded (/home/palworld/.config/systemd/user/palworld-dedicated.service; enabled; vendor preset: enabled)
Active: active (exited) since Mon 2024-02-05 11:01:16 JST; 4h 50min ago
Process: 10005 ExecStart=/bin/bash /home/palworld/Steam/steamapps/common/PalServer/boot.sh start (code=exited, status=0/SU>
Main PID: 10005 (code=exited, status=0/SUCCESS)
Tasks: 40 (limit: 38376)
Memory: 6.1G
CPU: 4h 6min 35.718s
CGroup: /user.slice/user-1001.slice/user@1001.service/app.slice/palworld-dedicated.service
├─10008 tmux new-session -s palworld-server -d "/home/palworld/Steam/steamapps/common/PalServer/PalServer.sh -use>
├─10009 /bin/sh /home/palworld/Steam/steamapps/common/PalServer/PalServer.sh -useperfthreads -NoAsyncLoadingThrea>
└─10018 /home/palworld/Steam/steamapps/common/PalServer/Pal/Binaries/Linux/PalServer-Linux-Test Pal -useperfthrea>

Feb 05 11:01:16 palworld systemd[786]: Started Palworld Dedicated Server.

また、tmuxのセッションを確認してみます。

tmux ls
結果

palworld@palworld:~$ tmux ls
palworld-server: 1 windows (created Mon Feb 5 11:01:16 2024)

tmuxのセッションにアタッチする際は以下
デタッチはctlr+bd

tmux a palworld-server
結果

Shutdown handler: initalize.
Increasing per-process limit of core file size to infinity.
dlopen failed trying to load:
steamclient.so
with error:
steamclient.so: cannot open shared object file: No such file or directory
[S_API] SteamAPI_Init(): Loaded '/home/palworld/.steam/sdk64/steamclient.so' OK. (First tried local 'steamclient.so')
CAppInfoCacheReadFromDiskThread took 2 milliseconds to initialize
dlmopen steamservice.so failed: steamservice.so: cannot open shared object file: No such file or directory
Setting breakpad minidump AppID = 2394010
[S_API FAIL] Tried to access Steam interface SteamUser021 before SteamAPI_Init succeeded.
[S_API FAIL] Tried to access Steam interface SteamFriends017 before SteamAPI_Init succeeded.
[S_API FAIL] Tried to access Steam interface STEAMAPPS_INTERFACE_VERSION008 before SteamAPI_Init succeeded.
[S_API FAIL] Tried to access Steam interface SteamNetworkingUtils004 before SteamAPI_Init succeeded.

問題がなければ一度サービスを停止します。

systemctl --user stop palworld-dedicated.service

cronの登録

再起動したい時間に合わせてcronを記載してください。
下記は11時、23時に再起動するcronです。

0 11 * * * XDG_RUNTIME_DIR=/run/user/$(id -u) systemctl --user restart palworld-dedicated.service 
0 23 * * * XDG_RUNTIME_DIR=/run/user/$(id -u) systemctl --user restart palworld-dedicated.service 

XDG_RUNTIME_DIR=/run/user/$(id -u) を記載しないとエラーを吐いて、再起動をスキップします。

syslogからログを確認するか、systemctl --user statusからアップタイムを確認することで再起動されたかを確認することが出来ます。

戯言

cronではsudoを使えない、というところか模索が始まりました。
セキュリティリスクを減らす観点からrootログインを無効化したかったため、サービスをユーザーレベルに落とし込むことで解決しました。
検証はしていませんが、tmuxを経由せず、サーバー起動のシェルを直接叩いて、サービスをワンショットにすることでoncalenderによる再起動をする、というのがシンプルな解決方法な気がします。
cronにXDG_RUNTIME_DIR=/run/user/$(id -u)を記載する必要がある、という情報もいろんな先駆者が記事を残してくれていたおかげですぐにたどり着くことができました。
ありがたい限りです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0