Minecraft bedrock Server を定期的に停止 / 起動する

Minecraft Bedrock Editionのサーバを運用しています。
日中など、誰も利用しない時間帯においてインスタンスを停止し、費用を節約します。

# 前提

- Minecraft Server Bedrock Editionをセットアップします。
- aws cliをセットアップします。
  - IAMで、[Lightsailのアクション](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/list_amazonlightsail.html#amazonlightsail-actions-as-permissions) `StartInstance`, `StopInstance` を許可したユーザを作成します。
  - aws-cliに作成したユーザを設定します。

# 環境

- AWS Lightsail
- Ubuntu 18.04
- Minecraft Server (Bedrock Edition) / Version 1.16.0.2
- aws-cli / 2.0.36

# サーバ起動 / 停止
サーバの起動および停止は、aws-cliより行います。

## サーバ起動

```
aws lightsail start-instance --instance-name server-name
```
https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lightsail/start-instance.html

## サーバ停止

```
aws lightsail stop-instance --instance-name server-name
```
https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lightsail/stop-instance.html

# Minecraftのサービス開始 / 停止
Minecraftの起動および停止はサーバ自身ではなく、リモートサーバからSSH経由で実行します。
Shellスクリプトをゴニョゴニョしました。

## Minecraftのサービス開始

```
ssh example.com -C 'cd ~/minecraft/;screen -L -Logfile ./logs/$(date +%Y.%m.%d.%H.%M.%S).log -dm -S MinecraftServer /bin/bash -c "LD_LIBRARY_PATH=. ./bedrock_server"'
```
ローカルで実行するならこのような形式となります。

```
screen -L -Logfile ~/minecraft/logs/$(date +%Y.%m.%d.%H.%M.%S).log -dm -S MinecraftServer /bin/bash -c "LD_LIBRARY_PATH= ~/minecraft/bedrock_server"
```

以下スクリプトの一部を抜粋して作成しました。
https://github.com/TheRemote/MinecraftBedrockServer/blob/master/start.sh#L60

## Minecraftのサービス停止

```
ssh example.com -C 'screen -list | grep Minecraft | awk -F "." "{print \$1}" | tr -d "[:space:]" | xargs kill'
```

ローカルで実行するならこのような形式となります。

```
screen -list | grep Minecraft | awk -F '.' '{print $1}' | tr -d '[:space:]' | xargs kill
```

# 動作確認
正常にMinecraftを起動、停止できているかどうかを手動で発行して確認します。
`screen -list`コマンドを発行することで、現在実行されているscreenのプロセス一覧を取得することができます。

- Minecraftのプロセスが実行されていないことを確認する

```
$ ssh example.com -C 'screen -list'
No Sockets found in /run/screen/S-ubuntu.
```

- Minecraftを起動する

```
$ ssh example.com -C 'cd ~/minecraft/;screen -L -Logfile ./logs/$(date +%Y.%m.%d.%H.%M.%S).log -dm -S MinecraftServer /bin/bash -c "LD_LIBRARY_PATH=. ./bedrock_server"'
```

- 起動確認

```
$ ssh example.com -C 'screen -list'
	4597.MinecraftServer	(08/03/20 16:20:03)	(Detached)
1 Socket in /run/screen/S-ubuntu.
```

- Minecraftを停止する

```
$ ssh example.com -C 'screen -list | grep Minecraft | awk -F "." "{print \$1}" | tr -d "[:space:]" | xargs kill'
```

- 停止確認

```
ubuntu@ip-172-26-15-16:~/manage_minecraft$ ssh example.com -C 'screen -list'
No Sockets found in /run/screen/S-ubuntu.
```

# cronへの登録

cronで自動的にインスタンスの起動 / 停止、minecraftサービスの開始 / 停止を行うようにします。

```
SHELL=/bin/bash

0 18 * * 0-4 ubuntu cd ~/manage_minecraft/; source ~/.bashrc; aws lightsail start-instance --instance-name kt-micra-serv
3 18 * * 0-4 ubuntu ssh example.com -C 'cd ~/minecraft/;screen -dm -S MinecraftServer /bin/bash -c "LD_LIBRARY_PATH=. ./bedrock_server"'
0 0 * * 0-4 ubuntu cd ~/manage_minecraft/; source ~/.bashrc;  ssh example.com -C 'screen -list | grep Minecraft | awk -F "." "{print \$1}" | tr -d "[:space:]" | xargs kill'
1 0 * * 0-4 ubuntu aws lightsail stop-instance --instance-name server-name
```

screenコマンドの -l以降については、うまく動かなかったので外しました。エスケープをうまくすれば動作すると思います。

# 参考

- [Minecraft Bedrock Edition – Ubuntu Dedicated Server Guide](https://jamesachambers.com/minecraft-bedrock-edition-ubuntu-dedicated-server-guide/)
- https://github.com/TheRemote/MinecraftBedrockServer/blob/master/

# おわりに

1ヶ月ほど前から構想はあったんですが、実装サボってました。
AWSから余分に2000円分の請求を頂きました。

# 追記

litesailのサーバは停止時課金されます。
そのため、これらの処理を自動実行して利用時間外にサーバを停止しても、料金に変化はありません。

つまり、無意味でした。

とはいえ、EC2とかを使っている方であれば役立てられるかなと思いますので、公開しておきます。