【AWS / Linux】Dockerイメージを使ってPalworldのマルチプレイ用サーバーを爆速で起動する

Palworldのマルチプレイ用サーバーを起動するときに、とあるDockerイメージを使うとめっちゃいい感じに運用できるよというお話です
2024.02.01

こんにちは、芦沢です。

皆さんはPalworldやっていますか?

ソロプレイも楽しいのですが、やっぱり専用サーバーを建てて大人数でプレイしたくなりますよね。 専用サーバーを構築する選択肢はたくさんありますが、やはりAWSをお仕事にさせてもらってる立場としてはAWSで構築してみたくなるもの。

マルチプレイ用のサーバーをAWSのWindowsサーバーで構築するブログは既にDevelopersIOに投稿されています。

AWSのLinuxサーバーでも試してみたいなと思い、こちらのブログを参考に構築してみました。

こちらのブログはよくまとまっていて、構築の進め方がとてもわかりやすく書かれています。ぜひご一読ください。

しかしながら、個人的にAWS環境上にリソースを構築するときは「できるところまで自動化して、早くプロビジョニングしたい!」と常日頃思っています。今回も思ってしまいました。

今回の件もどうにか自動化できないかな と思っていたところ、jammsen/docker-palworld-dedicated-serverというGitHubリポジトリの存在を知りました。

これを使えばなんだかサーバー構築を迅速化・自動化できそう!と思いたち、検証を始めました。

docker-palworld-dedicated-serverとは

このGitHubリポジトリは、Dockerイメージをベースに、Palworldのマルチプレイ用サーバーの管理・運用をよしなにできるスクリプトなどがまとめられています。

事前にマルチプレイ用サーバーの設定に必要な諸々が済んだコンテナを使っているので、Palworldのマルチプレイ用サーバーとして立ち上がるためのサービスをより早く起動できます。

起動が早いだけでなく自動バックアップスクリプトが同梱されており、バックアップ先のディレクトリはDockerコンテナが削除されても問題ないように設計されています。

コンテナの起動はdocker-composeを利用する手順になっていますが、本来PalWorldSettings.iniファイルで定義すべきゲームサーバのパラメータを環境変数として設定変更できたり、RCONを使った外部からゲームサーバー内へのコマンド実行も簡単に実行できるように指定までできます。

要するに、Palworldのマルチプレイ用サーバーが早く起動でき、より簡単かつ便利に運用できるようになるのです!

事前準備

事前に、以下のようなシンプルなVPC-EC2構成をAWS上に構築しておきます。

大雑把な構成やスペック等は以下の通りです。

  • VPC
    • パブリックサブネット x 1
    • インターネットゲートウェイ x 1
  • EC2インスタンス
    • OS
      • Amazon Linux 2023
    • サーバスペック
      • m7i.large(2 vCPU/8GB RAM)
    • セキュリティグループ(インバウンド)
      • 8211ポートを0.0.0.0/0で解放
    • その他
      • パブリックサブネットに配置
      • パブリックIPアドレスを付与
      • 事前にgit、docker、docker-composeを利用できるようにしておく

上記のAWS環境を構築できるTerraformファイル(main.tf)を含むGitHubリポジトリ(palworld_linux_build_by_terraform)を作成しましたので、ご利用ください。

Terraformを実行すると構築される環境と、外部接続のイメージを合わせたものがこちらです。パブリックなEC2ですが、SSH経由ではなくSSM Session Managerでリモートアクセスできるようにしているところがポイントですね。

事前にgit、docker、docker-composeを利用できるようにしておく

palworld_linux_build_by_terraformでは、EC2のUserDataに以下を設定しています。

#!/bin/bash

sudo yum update -y

## Install git
sudo yum install -y git

## Install docker
sudo mkdir -p /usr/local/lib/docker/cli-plugins
sudo yum install -y docker
sudo usermod -a -G docker ec2-user
sudo systemctl start docker
sudo systemctl enable docker

## Install docker-compose
VER=2.5.1
sudo curl \
-L https://github.com/docker/compose/releases/download/v${VER}/docker-compose-$(uname -s)-$(uname -m) \
-o /usr/local/lib/docker/cli-plugins/docker-compose
sudo chmod +x /usr/local/lib/docker/cli-plugins/docker-compose
sudo ln -s /usr/local/lib/docker/cli-plugins/docker-compose /usr/bin/docker-compose

こちらの設定を行うと、EC2のプロビジョニングと同時にgit、docker、docker-compoaseのインストールが行われます。

個別に環境を準備される方も同等の作業を終えておいてください。

やってみた

docker-palworld-dedicated-serverのリポジトリは2024/1/31現在頻繁に更新されているため、今後の更新内容によっては以降紹介する手順で動作しない場合があります。ご注意ください。

EC2のセットアップ

準備ができたら、EC2インスタンスにリモートログインしてください。

※今回の検証環境ではSystems Manager Session Managerを使ってリモートログインしています。

ログインできたらec2-userにスイッチします。スイッチ先は他のユーザーでも問題ないですが、rootユーザーは好ましくないのでroot以外のなんらかのユーザーを使うようにしましょう。

sudo su - ec2-user

GitHubリポジトリ(jammsen/docker-palworld-dedicated-server)をCloneします。

git clone https://github.com/jammsen/docker-palworld-dedicated-server.git

(出力例)
Cloning into 'docker-palworld-dedicated-server'...
remote: Enumerating objects: 486, done.
remote: Counting objects: 100% (178/178), done.
remote: Compressing objects: 100% (47/47), done.
remote: Total 486 (delta 158), reused 131 (delta 131), pack-reused 308
Receiving objects: 100% (486/486), 142.62 KiB | 11.88 MiB/s, done.
Resolving deltas: 100% (291/291), done.

Cloneしたリポジトリのディレクトリ配下に移動し、gameディレクトリをフルアクセス権限(777)で作成します。

cd ./docker-palworld-dedicated-server
mkdir -m 777 game

CloneしたGitHubリポジトリのディレクトリ内にフルアクセスのgameディレクトリがあればOKです。

ls -l

(出力例)
total 96
-rw-r--r--. 1 ec2-user ec2-user  4954 Jan 31 14:36 Dockerfile
-rw-r--r--. 1 ec2-user ec2-user  1073 Jan 31 14:36 LICENSE
-rw-r--r--. 1 ec2-user ec2-user  7687 Jan 31 14:36 README.md
-rw-r--r--. 1 ec2-user ec2-user 28831 Jan 31 14:36 README_ENV.md
-rw-r--r--. 1 ec2-user ec2-user   806 Jan 31 14:36 backupmanager.sh
-rw-r--r--. 1 ec2-user ec2-user  2360 Jan 31 14:36 default.env
-rw-r--r--. 1 ec2-user ec2-user   588 Jan 31 14:36 docker-compose.yml
drwxrwxrwx. 2 ec2-user ec2-user     6 Jan 31 14:36 game
-rw-r--r--. 1 ec2-user ec2-user    83 Jan 31 14:36 rcon.yaml
-rwxr-xr-x. 1 ec2-user ec2-user 25692 Jan 31 14:36 servermanager.sh

ここでdocker-compose.ymlを確認してみましょう。

cat docker-compose.yml

(出力例)
version: '3.9'
services:
  palworld-dedicated-server:
    #build: .
    container_name: palworld-dedicated-server
    image: jammsen/palworld-dedicated-server:latest
    restart: unless-stopped
    ports:
      - target: 8211 # Gamerserver port inside of the container
        published: 8211 # Gamerserver port on your host
        protocol: udp
        mode: host
      - target: 25575 # RCON port inside of the container
        published: 25575 # RCON port on your host
        protocol: tcp
        mode: host
    env_file:
      - ./default.env
    volumes:
      - ./game:/palworld[

restartのパラメータはunless-stoppedに設定されているため、コンテナを手動で起動しない限り自動で起動される設定になっています。EC2自体を再起動してもコンテナが自動で起動してくれそうです。

volumesのパラメータで./game:/palworldと指定することで、コンテナ内の/palworldディレクトリをホスト側の./gameディレクトリにマウントし、データを永続化させるようにしています。Palworldのセーブデータは/palworldに保存されるため、コンテナを削除してもセーブデータは残したままにできます。


パブリックIPアドレスとパスワードを変更する必要があるため、defalt.envを修正します。

TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"`
EC2_PUBLIC_IP=`curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/public-ipv4`
NEW_ADMIN_PASSWORD="P@ssword"
NEW_SERVER_PASSWORD="P@ssword"

sed -i "s/PUBLIC_IP=/PUBLIC_IP=$EC2_PUBLIC_IP/" ./default.env
sed -i "s/ADMIN_PASSWORD=adminPasswordHere/ADMIN_PASSWORD=$NEW_ADMIN_PASSWORD/" ./default.env
sed -i "s/SERVER_PASSWORD=serverPasswordHere/SERVER_PASSWORD=$NEW_SERVER_PASSWORD/" ./default.env

PUBLIC_IP変数にはEC2インスタンスに付与したパブリックIPアドレスを入力、NEW_ADMIN_PASSWORD変数およびNEW_SERVER_PASSWORD変数は新しいパスワードを設定します。

パスワードの変数はデフォルトのパスワードだと起動時にエラーとなるようにスクリプトが組まれているため、修正必須です。修正手順は個人的にやりやすいsedコマンドで置換していますが、他の方法でも問題ないです。

その他、defalt.envでは先述したようにiniファイルで定義されるサーバーのパラメータを環境変数として指定できます。その他のパラメータについてはREADMEを参照ください。

参考: README_ENV.md


docker-compose up -dコマンドを使って、Dockerコンテナを起動します。コンテナ起動と同時にdocker-compose logs -fでログを表示させています。[S_API FAIL] Tried to access Steam interfaceの文字列が見られたらcontrol + cでログの出力を停止してください

※[S_API FAIL] Tried to access Steam interfaceはエラー文ですが本日時点で無視しても良いエラーのようです

docker-compose up -d && docker-compose logs -f

(出力例)
[+] Running 11/11
 ⠿ palworld-dedicated-server Pulled                                                                                   7.3s
 ⠿ 0e0969fcaa82 Pull complete                                                                                         2.1s
 ⠿ e1fb61268ad7 Pull complete                                                                                         4.2s
 ⠿ 4f4fb700ef54 Pull complete                                                                                         4.2s
 ⠿ 17c0f40ccbf1 Pull complete                                                                                         4.3s
 ⠿ b1eccaee4c48 Pull complete                                                                                         4.4s
 ⠿ 89873bb3c424 Pull complete                                                                                         4.4s
 ⠿ d8b61f5588a9 Pull complete                                                                                         4.4s
 ⠿ 0b28e1a33d2a Pull complete                                                                                         4.4s
 ⠿ c4d9e3fcf52c Pull complete                                                                                         4.4s
 ⠿ 2708c30f4327 Pull complete                                                                                         4.5s
[+] Running 2/2
 ⠿ Network docker-palworld-dedicated-server_default  Created                                                          0.1s
 ⠿ Container palworld-dedicated-server               Started                                                          3.1s
palworld-dedicated-server  | >>> Checking for existence of default credentials
palworld-dedicated-server  | >>> Doing a fresh install of the gameserver
palworld-dedicated-server  | time="2024-01-31T15:56:03+01:00" level=info msg="read crontab: cronlist"
(中略)
palworld-dedicated-server  | [S_API] SteamAPI_Init(): Loaded local 'steamclient.so' OK.
palworld-dedicated-server  | CAppInfoCacheReadFromDiskThread took 8 milliseconds to initialize
palworld-dedicated-server  | Setting breakpad minidump AppID = 2394010
palworld-dedicated-server  | [S_API FAIL] Tried to access Steam interface SteamUser021 before SteamAPI_Init succeeded.
palworld-dedicated-server  | [S_API FAIL] Tried to access Steam interface SteamFriends017 before SteamAPI_Init succeeded.
palworld-dedicated-server  | [S_API FAIL] Tried to access Steam interface STEAMAPPS_INTERFACE_VERSION008 before SteamAPI_Init succeeded.
palworld-dedicated-server  | [S_API FAIL] Tried to access Steam interface SteamNetworkingUtils004 before SteamAPI_Init succeeded.

サーバーへ接続

ここまで問題なく進めたら、準備完了です。Palworldのゲームを起動しましょう。

マルチアカウントサーバーの接続画面から画面一番下の枠に[EC2のパブリックIPアドレス]:8821を入力し、パスワードを入力するにチェックを入れ、接続をクリックします。

パスワードを入力し、確定をクリックします。

パスワードが間違っていなければ、キャラクタークリエイト画面が表示されます。

キャラを作成し、オプション画面を表示させると、Palworld-Dedicated-Server runnning in Docker〜と表示されており、Dockerイメージを使って起動できたんだな、と実感できます。

ここからはゲームをお楽しみください!

最後に

Dockerイメージを使ってPalworldのマルチプレイ用サーバーを構築してみました。

「爆速で」と題しながら少し長くなりましたが、単純に起動するところまでならかなりサクッと進められるはずです。

EC2のプロビジョニング、ゲームサーバーの起動、EC2内でのバックアップの取得まではでできていますが、このままAWSでゲームサーバーを運用するためには以下のような課題が残っています。

  • EC2の自動停止起動
    • ゲームをやる19時以降にサーバーを自動起動する、24時になったら自動停止する、など
  • SlackやDiscord経由でのEC2の停止起動
    • AWSを触れなくともサーバーを起動できるようにする仕組みの構築
  • EC2外(S3など)へのセーブデータの自動保存
    • EC2を削除してもセーブデータを保持する仕組み

これらはAWSのサービスを使えば構築できそうなので、機会があれば別の記事でフォローしたいと思います。

注記としたとおり、紹介したGitHubリポジトリは現在頻繁に更新されているため、紹介した手順通りに構築が進められなくなる時も来るかもしれません。その際は以下私のXアカウント(@ashi_ssan)までフィードバックください。

楽しくゲームをやるために、より良いマルチプレイ用サーバー運用も頑張っていきたいなと思う筆者でした。

ここまで読んでくださりありがとうございました。以上です。