PterodactylでMinecraftのサーバー管理を楽にしてみよう

# 対象
- ホスティングサービスではなくセルフホストで動かしたい人
- 多少のLinuxやネットワークの知識
- ホストしたいマシンのカーネルがDockerをサポートしているか
- ~~筆者のようにDockerあんまわからん人~~
- ~~やる気~~

今回はUbuntuを使いますが、別のディストリでも大丈夫そう
~~インストールに関しては[ドキュメント](https://pterodactyl.io/panel/1.0/getting_started.html)+αみたいな感じになるけど気にしないでね...~~

# Panelのインストール
## 依存関係のインストール
```sh
# "add-apt-repository"コマンドの追加
sudo apt -y install software-properties-common curl apt-transport-https ca-certificates gnupg

# PHP, Redis, and MariaDBのレポジトリを追加
LC_ALL=C.UTF-8 add-apt-repository -y ppa:ondrej/php

curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.list

curl -sS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | sudo bash

# おまじない
sudo apt update

# 依存関係のインストール
sudo apt -y install php8.1 php8.1-{common,cli,gd,mysql,mbstring,bcmath,xml,fpm,curl,zip} mariadb-server nginx tar unzip git redis-server

# Composerのインストール
curl -sS https://getcomposer.org/installer | sudo php -- --install-dir=/usr/local/bin --filename=composer
```
PHPとMariaDB(MySQL)を使うのでインストールしておきます

## パネルの動作に必要なファイルのダウンロード
```sh
mkdir -p /var/www/pterodactyl
cd /var/www/pterodactyl
```

```sh
sudo curl -Lo panel.tar.gz https://github.com/pterodactyl/panel/releases/latest/download/panel.tar.gz
sudo tar -xzvf panel.tar.gz
sudo chmod -R 755 storage/* bootstrap/cache/
```
`/var/www/`以下の操作にはsudoが必要なので付け加えてます

# インストール
## データベースの構成
```sh
# MySQLコンソールにrootとしてログイン
mysql -u root -p

# パネル用のユーザーを作成
CREATE USER 'pterodactyl'@'127.0.0.1' IDENTIFIED BY 'パスワード';

# DBを作成
CREATE DATABASE panel;

# さっき作成したDBへの権限を設定
GRANT ALL PRIVILEGES ON panel.* TO 'pterodactyl'@'127.0.0.1' WITH GRANT OPTION;

# Bye
exit;
```

## 構成
```sh
# 設定ファイルのコピー
cp .env.example .env
composer install --no-dev --optimize-autoloader

# 秘密鍵の生成
# .envファイルが絶対に外部へ公開してはいけません!
php artisan key:generate --force
```

### セットアップ
```sh
# setupはほぼyesで問題なかったような気がします
php artisan p:environment:setup
# DBの接続情報はユーザー名はpterodactyl、ホストはlocalhost、パスはさっき決めたもの
php artisan p:environment:database
```

### DBの設定
```
php artisan migrate --seed --force
```
時間がかかる可能性あり

### ユーザーの作成
```
php artisan p:user:make
```
管理ユーザーを作成します。
パスワードは8文字以上、大文字・小文字と数字が混在している必要あり

## Crontabの構成
まず`sudo crontab -e`で設定ファイルを開きます
エディタを聞かれたらお好きなエディタを選んでください~~(自分はnano派)~~
ファイルの一番最後にこれを追記します

```
* * * * * php /var/www/pterodactyl/artisan schedule:run >> /dev/null 2>&1
```
### ワーカーの構成
`sudo nano /etc/systemd/system/pteroq.service`で新しいサービスを作ります

```systemd
# Pterodactyl Queue Worker File
# ----------------------------------

[Unit]
Description=Pterodactyl Queue Worker

[Service]
# On some systems the user and group might be different.
# Some systems use `apache` or `nginx` as the user and group.
User=www-data
Group=www-data
Restart=always
ExecStart=/usr/bin/php /var/www/pterodactyl/artisan queue:work --queue=high,standard,low --sleep=3 --tries=3
StartLimitInterval=180
StartLimitBurst=30
RestartSec=5s

[Install]
WantedBy=multi-user.target
```

最後に起動させます

```sh
sudo systemctl enable --now pteroq.service
```

## Webサーバーの構成
これは使っているWebサーバーやSSLの有無で変わるのでこちらを参照してください
[Webserver Configuration](https://pterodactyl.io/panel/1.0/webserver_configuration.html)
### 注意点
- Cloudflareは使えないのでプロキシを外してください
- nginxとかのlocationでディレクトリを分けて運用でできないっぽいのでサブドメイン取ってバーチャルホストを作成してください

これで無事にWebダッシュボードにアクセスできれば成功です
(筆者の環境ではChromeではログインできなくてFirefoxだとログインできました)

# デーモンのインストール
パネルから指示を受けて裏でDockerの操作とかをするデーモンです(名前がWingsっていうらしい)

## Docekrのインストール
```sh
curl -sSL https://get.docker.com/ | CHANNEL=stable bash
systemctl enable --now docker
```

## Wingsの構成
### ダウンロード
```sh
sudo mkdir -p /etc/pterodactyl
sudo curl -L -o /usr/local/bin/wings "https://github.com/pterodactyl/wings/releases/latest/download/wings_linux_$([[ "$(uname -m)" == "x86_64" ]] && echo "amd64" || echo "arm64")"
sudo chmod u+x /usr/local/bin/wings
```

### 構成
Webダッシュボード(<ドメイン>/admin/)にアクセスし、
Locations->Create New
入力するのは「Short Code」だけで大丈夫です
わかりやすい名前(OsakaやTokyo)にするのが良いと思います

次にNodes->Create New
NameとFQDNを入力します。
FQDNはパネルと同じサーバーで動かすならパネルと同じドメインで大丈夫です

作成したらそのNameをクリックして「Configuration」タブから
Auto-DeployのGenerate Tokenをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701723/a0e65668-9dfd-1a1c-dce8-108dc88e5b2a.png)
ここに表示されたコマンドをコンソールに貼り付けて実行します

### テスト
```sh
sudo wings --debug
```
と入力してみてパネルのNodesの名前の横が緑のハートのマークになれば正常にデーモンと通信できています
エラーが出ていないかを確認してください
`Ctrl+C`で終了します

### デーモン化
エラーが出ていなければデーモン化してしまいます
`sudo nano /etc/systemd/system/wings.service`で

```systemd
[Unit]
Description=Pterodactyl Wings Daemon
After=docker.service
Requires=docker.service
PartOf=docker.service

[Service]
User=root
WorkingDirectory=/etc/pterodactyl
LimitNOFILE=4096
PIDFile=/var/run/wings/daemon.pid
ExecStart=/usr/local/bin/wings
Restart=on-failure
StartLimitInterval=180
StartLimitBurst=30
RestartSec=5s

[Install]
WantedBy=multi-user.target
```
自動起動を有効化して終わり

```sh
systemctl enable --now wings
```

これでインストールは終了です

# Minecraft サーバーを建ててみる

## IPとポートの割り当て
Nodes->Allocationに行き、Assign New Allocationsで作成できます
IPアドレスは「0.0.0.0」
ポートは使いたいポートを入力しましょう
`25565-25567`みたいな複数指定にも対応しています
IP Aliasは鯖を立てるときにわかりやすくするものです。お好みで。

## サーバーの作成
はい、長かったですね。いよいよサーバーを建てます
Servers->Create Newからサーバーを建てます

|設定名|説明|
|---|---|
|Server Name|その名の通りサーバーの名前|
|Server Owner|自分のユーザー名を入力|
|Default Allocation|Minecraftサーバーが使用するポート(25565など)|
|Additional Allocation(s)|追加のポートです(Dynmapとかが使用する8123など)|
|Memory|最大メモリ使用量|
|Disk Space|最大ディスク使用量|
|Nest|Minecraft|
|Egg|お好みで。自分はPaper推奨|
|Docker Image|最新版ならjava_17を選択|
|Minecraft Version|変更するならお好みのMCバージョンを入力|
これでCreate Serverをクリックすればサーバーが作成されます
サーバーの詳細ページのDeleteタブの隣にあるアイコンをクリックすれば管理画面にいけます

途中EULAの規約に同意するか聞かれるのでI Acceptをクリックしましょう

これでサーバーの完成です

ホストのファイアウォールでポート開放してクライアントが入ることができればOK！

# サーバーコンソールでコマンドが受け付けない場合
どうやらLinuxカーネルの問題らしく、JVM引数を付け加えることで解決する模様
Startup->Startup Commandのメモリ指定とjarファイルの間の引数を全部消して
`-Djline.terminal=jline.UnsupportedTerminal`
に置き換えることで解決する

# 定期的に何か実行したい場合
定期的に再起動やバックアップ(要Backup Limitの設定)をしたい場合にはSchedule機能を使います
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701723/f28a1599-11be-0384-4006-c3968fa3cfb8.png)
管理画面からSchedules->CREATE SCHEDULEをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701723/398c4c52-a32e-12cc-6f9d-df491290e621.png)
Nameにはお好きな名前を入力して、
その下は見たことある人ならわかると思いますがcrontabライクな時間指定です
見たこと無い人はこっちを参照→[crontabの書き方](https://www.server-memo.net/tips/crontab.html)

作成したら、NEW TASKをクリックして
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701723/61599397-11f3-6a1c-4ea7-613a5cc2d7ae.png)
ACTIONには実行したいアクション
TIME OFFSETにはスケジュールが発火してから何秒間時差をつけるかというもの
Send commandにしてPAYLOADに
`say スケジュールからこんにちは`
と入力すると指定した時間になればアナウンスしてくれるタスクが作れる
PAYLOADの項目は複数行入力可能です

バックアップならACTIONをCreate backupにして、
再起動ならACTIONをSend power actionにしてPAYLOADをRestart thr serverにすればOK

複数のTASKをスケジュールに登録でき、アナウンスしてから時間差を付けて再起動なんてこともできる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701723/8dfffde3-562c-d4de-d399-604fdc41ff00.png)

# SFTPを使う方法
管理画面からSettingsのページに情報が書いてあります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701723/f154d6d2-50b9-c8a6-eddc-cdb128f5d696.png)
外部から通信する場合はファイアウォールでポートを開けておいてください(デフォルトは2022)
ユーザー名はここに記載されていて、サーバーごとに後ろの英数字が異なります
パスワードはログインしているユーザーのパスワードです

# APIを使う方法
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701723/5fb0ec91-b3c0-8b01-a4a4-ddabc8bc2fc1.png)
右上の人のアイコンをクリックして、API Credentials
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701723/2e3c98c2-e745-e146-4560-9e49da029f19.png)
DESCRIPTIONは説明を入力してALLOWED IPSは許可したいIPを1行ずつ入力していく
CREATEをクリックするとAPIキーが発行されるのでメモっとく

APIリファレンスは[ここ](https://dashflo.net/docs/api/pterodactyl/v1/)にある
Authorizationヘッダーに`Bearer (APIキー)`を入力する(Bearerは必須)
ドキュメントの`pterodactyl_session`については謎で、必須では無いみたい(セッションクッキーらしい...?)

ちなみにadminの方にあるApplication APIについては不明

# AirplaneやARK、Rustのサーバーも動かしたい!
ARKやRustのサーバーはもとから付いています
NestをRustやSource Engineに変えるとEgg一覧に表示されます~~(ARKはUE4だけどなんでSource Engineなんだ...?)~~

この付属以外のゲームAirplane(Paperのフォーク)やTerraria、Left 4 Dead、7 Days to Die、統合版MCサーバー、Five M、DiscordBotなんかも動かせたりします。

まず[この](https://github.com/parkervcp/eggs)レポジトリからお目当てのeggのjsonファイルをダウンロードします
DLしたら、adminのNestsからImport Eggをクリックします

Egg FileにさっきDLしたjsonファイルを指定して
Associated Nestは親となるNestを選択します新規作成したい場合はImport Eggの横のCreate Newをクリックします
インポートが完了するとServer作成時に使えるようになります