概要
身内用にマイクラサーバーを立てる機会があったので、せっかくならとAWS EC2とDockerを使って立ててみました。
AWSには一年間の無料枠があり、EC2サーバーを月750時間動かすことができます。(複数サーバーを立てた場合、サーバーごとではなくそれぞれのサーバーの合計となるので注意)
今回作ったもののソースコードはこちら
AWS EC2サーバーを立てる
今回は以下のような構成でEC2サーバーを立てました。t4g.smallは無料利用枠の対象には書かれていませんが、以下のページによると2024年12月31日まで無料で利用できるようです。
項目 | 値 |
---|---|
名前 | Minecraft Server |
Amazonマシンイメージ | Amazon Linux 2023 AMI |
アーキテクチャ | 64ビット (Arm) |
インスタンスタイプ | t4g.small |
キーペア | RSA(pem形式) |
ストレージ | 8GiB |
ストレージは後からでも追加できるのでとりあえずデフォルトの8GiBにしています。
セキュリティグループの設定
タイプ | ポート範囲 | ソース |
---|---|---|
カスタムTCP | 25565 | Anywhere-IPv4 |
Minecraft Serverはデフォルトで25565ポートを使用するので解放してあげましょう。デフォルトポートを変更した場合はこちらの変更も忘れずに。
Dockerをインストール
sudo yum install -y docker
sudo service docker start
sudo usermod -a -G docker ec2-user
DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker}
mkdir -p $DOCKER_CONFIG/cli-plugins
curl -SL https://github.com/docker/compose/releases/download/v2.4.1/docker-compose-linux-x86_64 -o $DOCKER_CONFIG/cli-plugins/docker-compose
Dockerでマイクラサーバーを立てる
良さそうなDocker Imageがあったのでそれを使います。Minecraftのバージョンは1.21.1です。
Docker Composeをいい感じに設定
services:
mc-1: #サービス名
image: itzg/minecraft-server
tty: true
stdin_open: true
ports:
- "25565:25565"
environment:
EULA: "TRUE"
VERSION: "1.21.1" #Minecraftバージョン
volumes:
- ./data/mc-1:/data #/data/(サービス名)にデータを保存
mc-2:
image: itzg/minecraft-server
tty: true
stdin_open: true
ports:
- "25570:25565" #mc-1と被らないよう25570ポートに変更
environment:
EULA: "TRUE"
VERSION: "1.21.1"
volumes:
- ./data/mc-2:/data
mc-3: ...
Dockerコンテナ上で動かすことで複数のワールドを一つの物理サーバー内で共存させることができます。しかし、今回使用したt4g.smallは性能上同時に一つのワールドまでしか起動できません。(二つ以上起動するとサーバーが死にました。)無料なのでそこは我慢。
ワールドを起動する
docker-compose up -d mc-1(docker-compose.ymlで設定したサービス名)
docker-compose up -dするとすべてのワールドが起動してしまうので、サービス名を指定することで特定のワールドのみ起動できます。
ワールドを停止する
docker-compose rm -fsv mc-1(docker-compose.ymlで設定したサービス名)
docker-compose downではなくdocker-compose rm を使うことで特定のワールドのみ停止できます。
サーバーをバックアップ
まず最初にGitとGitHubの設定をします。
Git, GitHub CLIのインストール
sudo yum install -y git
type -p yum-config-manager >/dev/null || sudo yum install yum-utils
sudo yum-config-manager --add-repo https://cli.github.com/packages/rpm/gh-cli.repo
sudo yum install gh
GitHub CLIでログイン
GitHubでrepo権限をもつTokenを作成
gh auth login
色々聞かれるのでGitHubで生成したTokenを使ってログイン
サーバー制御用スクリプト
#!/bin/bash
MCDIR="~/minecraft"
worlds=("mc-1" "mc-2")
# 全てのワールドを起動
start() {
cd "$MCDIR"
docker-compose up -d
}
# 全てのワールドを停止
stop() {
cd "$MCDIR"
docker-compose down
}
# 全てのワールドを保存
saveAll() {
cd "$MCDIR"
for world in ${worlds[@]}; do
docker-compose exec $world rcon-cli save-all
done
}
case "$1" in
save-all)
saveAll
sleep 30
;;
start)
start
;;
stop)
stop
;;
*)
echo $"Usage: $0 {start|stop|save-all}"
;;
esac
バックアップ用スクリプト
#!/bin/bash
DATE=`date '+%Y-%m-%d %H:%M:%S %z'`
# docker-compose.ymlで設定したサービス名を指定
worlds=("mc-1" "mc-2")
cd ~/minecraft
bash ~/minecraft/scripts/minecraft.sh save-all
for world in ${worlds[@]}; do
docker-compose exec $world rcon-cli "say バックアップ中..."
done
git add -A
git commit -m "$DATE"
git pull origin main --rebase
git push origin main
for world in ${worlds[@]}; do
docker-compose exec $world rcon-cli "say バックアップ完了"
done
リポジトリの設定
適当なリポジトリを作り、docker-compose.yml, /scripts/backup_github.sh, /scripts/minecraft.shを配置します。その後リポジトリを~/minecraftフォルダにcloneします。
cd ~
gh repo clone "リポジトリ名" minecraft
backup_github.shを実行すればバックアップできます。
bash backup_github.sh
バックアップを定期実行する
いちいち手動で実行するのは面倒なのでcronに登録して定期実行します。
# cronをインストール
sudo yum install cronie -y
sudo systemctl enable crond.service
sudo systemctl start crond.service
# 例:一時間ごとにバックアップするよう設定
sudo crontab -e
0 * * * * bash ~/minecraft/scripts/backup_github.sh
sudo systemctl restart cron
感想
- cronの代わりにsystemdのタイマー機能があるらしい。
- docker-composeで全てのコンテナにコマンドを送る方法が分からなかったため、とりあえず配列で全サービスを列挙している。もっとスマートにしたい気持ち。
- そのうちオンプレサーバーに移行する予定。サーバー欲しい。
参考
ローコストで24時間MineCraftサーバーを実現する
AWS EC2インスタンスにdockerとdocker-composeをインストールして簡単なWEBサービスを立ち上げる方法
Minecraft Server on Docker (Java Edition)
Docker Compose の一部のサービスだけ Up/Down する