普段は、MinecraftはJAVA版でプレイしていますが、統合版も、おもしろそうと言うことで、遅ればせながらプレイを始めて見ました。
しかし、JAVA版と統合版では、色々挙動が違うので、通常のサバイバル用のワールドとは別に、サンドボックス用のクリエイティブのワールドを作りたくなりました。
通常であれば、Realmsを契約する事になりますが、1契約1ワールドですので、課金額もワールド分必要になり、結構なコストになります。幸いにも、自宅にはすでにJAVA版のマイクラサーバが稼働しているので、そこに、複数のワールドをインストールし、プレイできる環境を作ってみたいと思います。
目次
Linuxサーバの準備
今回、サーバは「Ubuntu 20.04.2 LTS」を使用しています。
なお、今回の説明では、ユーザー[minecraft]を作成し、デフォルトのホームディレクトリ配下にこれらを構築していきます。
作業は、ユーザー[minecraft]で行ってください。
もし、ディレクトリを変更される場合は適宜読み替えていただくのと、各スクリプトのパスを修正する必要がありますので、ご注意下さい。
また、構築時に不足するパッケージ等が有りましたら、適宜aptでインストールして下さい。
ディレクトリ構築
今回、複数のサーバを構築するに当たって、以前このサイトでも導入方法を解説した、MineOS風のディレクトリ構造にします。
以下のようにディレクトリを作成してください。
[home]
+---[minecraft]
+---[archive]
+---[profiles]
+---[scripts]
+---[servers]
- [archive]は、バックアップデータが保存されるディレクトリです。
Minecraftサーバ毎に、サブディレクトリが作られます。 - [profiles]は、各バージョンのダウンロードされたサーバソフトウェアの元ファイルが保存されるディレクトリです。
MineOSでは、各バージョンのことをプロファイルと呼称していましたので、それに習っています。 - [scripts]は、Minecraftサーバの制御用のスクリプトが保存されるディレクトリです。
- [servers]は、各サーバの、実際のデータが保存されるディレクトリです。
Minecraftサーバ毎に、サブディレクトリを作ります。
私の実際の運用では、[minecraft]配下は、SSDになっており、[archive]配下のみ、別の大容量HDDをマウントして運用しています。
スクリプトの設置
[scripts]に次のスクリプトを3つ設置してください。
今回、単体サーバ操作スクリプトは、MINECRAFT.SERVER-MEMO.NET様(https://minecraft.server-memo.net/)が公開されている物をベースに、マルチサーバ用に改造しました。
MINECRAFT.SERVER-MEMO.NET様では、CentOSにインストールするための手順が公開されており、それ以外にも、Minecraftサーバを構築する上で、大変参考になる投稿がありますので、興味のある方は、是非訪れてみて下さい。
- 単体サーバ操作スクリプト(bedrock_script.sh)
#!/bin/bash
#
# bedrock_server start/stop/backup/update/create script for single server
#
# bedrock_server 実行ユーザ
USERNAME='minecraft'
# ベースディレクトリ
BASE_PATH="/home/minecraft"
# サーバ名
SERVER_NAME=$2
# プロファイル名
PROFILE_NAME=$3
# bedrock_serverインストールディレクトリ
BEDROCK_PATH="$BASE_PATH/servers/$SERVER_NAME"
# LD_LIBRARY_PATH設定
LD_LIBRARY_PATH="$BEDROCK_PATH"
# 実行する bedrock_server
SERVICE="$BEDROCK_PATH/bedrock_server"
## バックアップ用設定
# バックアップ格納ディレクトリ
BK_DIR="$BASE_PATH/archive/$SERVER_NAME"
# バックアップ取得時間
BK_TIME=`date +%Y-%m-%d_%H:%M:%S`
# 完全バックアップデータ名
FULL_BK_NAME="$BK_DIR/server-full-${SERVER_NAME}_${BK_TIME}.tgz"
# 簡易パックアップデータ名
SIMPLE_BK_NAME="$BK_DIR/server-simple-${SERVER_NAME}_${BK_TIME}.tar"
# 簡易バックアップ対象データ
BK_FILE="$BEDROCK_PATH/worlds \
$BEDROCK_PATH/valid_known_packs.json \
$BEDROCK_PATH/permissions.json \
$BEDROCK_PATH/server.properties \
$BEDROCK_PATH/whitelist.json"
cd $BEDROCK_PATH
if [ ! -d $BK_DIR ]; then
mkdir $BK_DIR
fi
ME=`whoami`
if [ $ME != $USERNAME ]; then
echo "Please run the $USERNAME user."
exit
fi
# 開始処理
start() {
if pgrep -u $USERNAME -f $SERVICE > /dev/null; then
echo "[$SERVER_NAME] $SERVICE is already running!"
else
echo "[$SERVER_NAME] Starting $SERVICE..."
tmux new-session -d -s $SERVER_NAME
tmux send-keys -t $SERVER_NAME:0 "LD_LIBRARY_PATH=$LD_LIBRARY_PATH $SERVICE" C-m
fi
}
# 停止処理
stop() {
if pgrep -u $USERNAME -f $SERVICE > /dev/null; then
echo "[$SERVER_NAME] Stopping $SERVICE"
tmux send-keys -t $SERVER_NAME:0 "say SERVER SHUTTING DOWN IN 10 SECONDS. Saving map..." C-m
sleep 10
tmux send-keys -t $SERVER_NAME:0 "stop" C-m
sleep 10
echo "[$SERVER_NAME] Stopped $SERVICE"
else
echo "[$SERVER_NAME] $SERVICE is not running!"
exit
fi
while :
do
if
pgrep -u $USERNAME -f $SERVICE > /dev/null; then
echo "[$SERVER_NAME] Stopping $SERVICE"
sleep 10
else
tmux kill-session -t $SERVER_NAME
echo "[$SERVER_NAME] Stopped $SERVICE"
break
fi
done
}
# 簡易バックアップ処理
s_backup() {
if pgrep -u $USERNAME -f $SERVICE > /dev/null; then
echo "[$SERVER_NAME] Simple Backup start ..."
tmux send-keys -t $SERVER_NAME:0 "save hold" C-m
sleep 10
tmux send-keys -t $SERVER_NAME:0 "save query " C-m
tar cfv $SIMPLE_BK_NAME $BK_FILE
sleep 10
tmux send-keys -t $SERVER_NAME:0 "save resume" C-m
echo "[$SERVER_NAME] Simple Backup compleate!"
gzip -f $SIMPLE_BK_NAME
else
echo "[$SERVER_NAME] Simple Backup start ..."
tar cfv $SIMPLE_BK_NAME $BK_FILE
gzip -f $SIMPLE_BK_NAME
echo "[$SERVER_NAME] Simple Backup compleate!"
fi
}
# 完全バックアップ処理
f_backup() {
if pgrep -u $USERNAME -f $SERVICE > /dev/null; then
echo "[$SERVER_NAME] Full backup start minecraft data..."
tmux send-keys -t $SERVER_NAME:0 "say SERVER SHUTTING DOWN IN 10 SECONDS. Saving map..." C-m
sleep 10
tmux send-keys -t $SERVER_NAME:0 "save-all" C-m
tmux send-keys -t $SERVER_NAME:0 "stop" C-m
while :
do
if
pgrep -u $USERNAME -f $SERVICE > /dev/null; then
echo "[$SERVER_NAME] Stopping $SERVICE"
sleep 10
else
echo "[$SERVER_NAME] Stopped $SERVICE"
echo "[$SERVER_NAME] Full Backup start ..."
tar cfvz $FULL_BK_NAME $BEDROCK_PATH
echo "[$SERVER_NAME] Full Backup compleate!"
break
fi
done
echo "[$SERVER_NAME] Starting $SERVICE..."
tmux send-keys -t $SERVER_NAME:0 "$SERVICE" C-m
else
echo "[$SERVER_NAME] Full Backup start ..."
tar cfvz $FULL_BK_NAME $BEDROCK_PATH
echo "[$SERVER_NAME] Full Backup compleate!"
fi
}
# 起動状態確認処理
status() {
if pgrep -u $USERNAME -f $SERVICE > /dev/null; then
echo "[$SERVER_NAME] $SERVICE is already running!"
exit
else
echo "[$SERVER_NAME] $SERVICE is not running!"
exit
fi
}
# プロファイルアップデート処理
update() {
if pgrep -u $USERNAME -f $SERVICE > /dev/null; then
echo "[$SERVER_NAME] $SERVICE is already running!"
exit
else
if [ "$PROFILE_NAME" = '' ]; then
get_profile
fi
# プロファイル保存ディレクトリ
PROFILE_PATH="$BASE_PATH/profiles/$PROFILE_NAME"
if [ -d $PROFILE_PATH ]; then
f_backup
rsync -av $PROFILE_PATH/ $BEDROCK_PATH/ --exclude "/permissions.json" --exclude "/server.properties" --exclude "/whitelist.json" --exclude "/valid_known_packs.json" --exclude "/worlds/"
echo "[$SERVER_NAME] Profile update to $PROFILE_NAME!"
else
echo "[$SERVER_NAME] Profile $PROFILE_NAME is not found!"
exit
fi
fi
}
# 新規サーバ設置処理
create() {
if pgrep -u $USERNAME -f $SERVICE > /dev/null; then
echo "[$SERVER_NAME] $SERVICE is already running!"
exit
else
if [ "$PROFILE_NAME" = '' ]; then
get_profile
fi
# プロファイル保存ディレクトリ
PROFILE_PATH="$BASE_PATH/profiles/$PROFILE_NAME"
if [ -d $PROFILE_PATH ]; then
if [ -d $BEDROCK_PATH ]; then
read -p "$SERVER_NAME already exists, can I overwrite it? (y/N): " yn
case "$yn" in [yY]*) ;; *) echo "abort." ; exit ;; esac
rm -Rf $BEDROCK_PATH
fi
cp -a $PROFILE_PATH $BEDROCK_PATH
echo "[$SERVER_NAME] Create complete."
else
echo "[$SERVER_NAME] Profile $PROFILE_NAME is not found!"
exit
fi
fi
}
# プロファイル名未指定時は、サーバから取得する
get_profile(){
echo "Get current profile ..."
CURRENT_PROFILE_NAME=$(curl -sA "BedrockServerVersionCheck/1.0" https://www.minecraft.net/ja-jp/download/server/bedrock | sed -zr 's/.*\/bedrock-server-(.+?)\.zip.*/\1/')
if [ "$CURRENT_PROFILE_NAME" = '' ]; then
echo "The current profile could not be obtained."
exit
fi
PROFILE_NAME=$CURRENT_PROFILE_NAME
echo "Current profile: $PROFILE_NAME"
}
case "$1" in
start)
start
;;
stop)
stop
;;
s_backup)
s_backup
;;
f_backup)
f_backup
;;
status)
status
;;
update)
update
;;
create)
create
;;
*)
echo $"Usage: $0 {start|stop|s_backup|f_backup|status} [SERVER_NAME]"
echo $" $0 {update|create} [SERVER_NAME] [PROFILE_NAME]"
esac
- 全サーバ操作スクリプト(bedrock_script_all.sh)
#!/bin/bash
#
# bedrock_server start/stop/backup/update script for all servers
#
# ベースディレクトリ
BASE_PATH="/home/minecraft"
# bedrock_scriptパス
BEDROCK_SCRIPT="$BASE_PATH/scripts/bedrock_script.sh"
# bedrock サーバパス
BEDROCK_SERVERS="$BASE_PATH/servers"
# サーバ一覧を取得
DIRS=`find $BEDROCK_SERVERS/* -maxdepth 0 -type d`
if [ "$1" = '' ]; then
echo $"Usage: $0 {start|stop|s_backup|f_backup|status}"
echo $" $0 update [PROFILE_NAME]"
exit
fi
if [ "$1" = 'create' ]; then
echo "The action create cannot be used in this script."
exit
fi
for DIR in $DIRS;
do
SERVER_NAME=`basename $DIR`
if [ -e "$BEDROCK_SERVERS/$SERVER_NAME/bedrock_server" ]; then
if [ $PPID != 1 ] || [ $1 != 'start' ] || [ ! -e "$BEDROCK_SERVERS/$SERVER_NAME/disabeAutoStart" ]; then
$BEDROCK_SCRIPT $1 $SERVER_NAME $2
fi
fi
done
- プロファイルダウンロードスクリプト(bedrock_profile_download.sh)
#!/bin/bash
#
# bedrock_server profile download script
#
# bedrock_server 実行ユーザ
USERNAME='minecraft'
# ベースディレクトリ
BASE_PATH="/home/minecraft"
# プロファイル名
PROFILE_NAME=$1
# プロファイル名未指定時は、サーバから取得する
if [ "$PROFILE_NAME" = '' ]; then
echo "Get current profile ..."
CURRENT_PROFILE_NAME=$(curl -sA "BedrockServerVersionCheck/1.0" https://www.minecraft.net/ja-jp/download/server/bedrock | sed -zr 's/.*\/bedrock-server-(.+?)\.zip.*/\1/')
if [ "$CURRENT_PROFILE_NAME" = '' ]; then
echo "The current profile could not be obtained."
exit
fi
PROFILE_NAME=$CURRENT_PROFILE_NAME
echo "Current profile: $PROFILE_NAME"
fi
# 圧縮ファイル名
ARCHIVE_FILE_NAME="bedrock-server-$PROFILE_NAME.zip"
# ダウンロードURL
DOWNLOAD_URL="https://minecraft.azureedge.net/bin-linux/$ARCHIVE_FILE_NAME"
# プロファイルベースディレクトリ
PROFILE_BASE_PATH="$BASE_PATH/profiles"
# プロファイル圧縮ファイル
PROFILE_ARCHIVE_FILE_NAME="$PROFILE_BASE_PATH/$ARCHIVE_FILE_NAME"
# プロファイルディレクトリ
PROFILE_PATH="$PROFILE_BASE_PATH/$PROFILE_NAME"
ME=`whoami`
if [ $ME != $USERNAME ]; then
echo "Please run the $USERNAME user."
exit
fi
cd $PROFILE_BASE_PATH
echo "Target URL: $DOWNLOAD_URL"
read -p "Do you want to start the download? (y/N): " yn
case "$yn" in [yY]*) ;; *) echo "abort." ; exit ;; esac
if [ -e $PROFILE_ARCHIVE_FILE_NAME ]; then
rm -f $PROFILE_ARCHIVE_FILE_NAME
fi
curl -OL $DOWNLOAD_URL
if [ ! -e $PROFILE_ARCHIVE_FILE_NAME ]; then
echo "Profile $PROFILE_NAME download error."
exit
fi
if [ -d $PROFILE_PATH ]; then
rm -Rf $PROFILE_PATH
fi
mkdir $PROFILE_PATH
cd $PROFILE_PATH
unzip $PROFILE_ARCHIVE_FILE_NAME
if [ ! -e "$PROFILE_PATH/bedrock_server" ]; then
echo "Profile $PROFILE_NAME extract error."
exit
fi
echo
echo "Profile $PROFILE_NAME download complete."
echo "To update the server, stop the server and run the following command."
echo
echo "Single server:"
echo "$BASE_PATH/scripts/bedrock_script.sh update [SERVER_NAME] $PROFILE_NAME"
echo
echo "All server:"
echo "$BASE_PATH/scripts/bedrock_script_all.sh update $PROFILE_NAME"
3つのスクリプトは、設置が完了したら、パーミッションを744にして下さい。
プロファイルのダウンロード
プロファイルダウンロードスクリプトを使用して、最新のサーバソフトウェアをダウンロードします。
※MineOSにならって、各バージョンの事をプロファイルと表現しています。
実行方法は以下の通りです。
$ /home/minecraft/scripts/bedrock_profile_download.sh [プロファイル名]
プロファイル名を指定しなかった場合は、ダウンロードサイトの現在のダウンロードファイル名を確認し、現在ダウンロードが可能な最新のプロファイルを自動的に判断します。
※配布サイトの構造が変わると使用できなくなったり、意図しない動作になる可能性がありますので、その点は注意して下さい。
スクリプトを実行すると、[profiles]ディレクトリに配布ファイルをダウンロードし、プロファイル名のサブディレクトリを作成し、そこに配布ファイルを展開します。
新規サーバ設置
単体サーバ操作スクリプトを使用して、新規サーバを設置します。
実行方法は以下の通りです。
$ /home/minecraft/scripts/bedrock_script.sh create [サーバ名] [プロファイル名]
プロファイル名を指定しなかった場合は、ダウンロードサイトの現在のダウンロードファイル名を確認し、現在ダウンロードが可能な最新のプロファイルを自動的に判断します。
※配布サイトの構造が変わると使用できなくなったり、意図しない動作になる可能性がありますので、その点は注意して下さい。
スクリプトを実行すると、[servers]ディレクトリに、サーバ名のサブディレクトリを作成し、そこに指定したプロファイルをコピーします。
その後、展開後のディレクトリに移動し、[server.properties]を適切に設定して下さい。なお、[server.properties]の設定方法については、ここでは説明しません。複数サーバを起動する場合は、ポート番号の変更は必須となります。
サーバ起動
単体サーバ操作スクリプトを使用して、サーバを起動します。
実行方法は以下の通りです。
$ /home/minecraft/scripts/bedrock_script.sh start [サーバ名]
特にエラーが発生しなければ、各クライアントから接続できるか確認して下さい。
自動起動設定
Ubuntuを起動する度に、自動的に起動する様に設定します。
ここの操作は、root権限が必要です。sudoで操作して下さい。
- Systemd設定ファイル(bedrock_server.service)
[Unit]
Description=Minecraft Bedrock Server
After=network.target local-fs.target
[Service]
Type=forking
User=minecraft
ExecStart=/home/minecraft/scripts/bedrock_script_all.sh start
ExecStop=/home/minecraft/scripts/bedrock_script_all.sh stop
[Install]
WantedBy=multi-user.target
上記ファイルを、以下のパスに配置して下さい。
/etc/systemd/system/bedrock_server.service
その後、スクリプトの自動起動を有効にするコマンドを実行して下さい。
$ sudo systemctl enable bedrock_server.service
なお、サーバのディレクトリに「disabeAutoStart」というファイル(中身は空で構いません)を置いておくと、
Ubuntu起動時の自動起動の対象から外れます。
バックアップの設定
バックアップを定時で取るように設定します。
ユーザー[minecraft]で、以下のコマンドを使用して、cronを編集して下さい。
$ crontab -e
エディタが起動したら、スケジュールとスクリプトを記述します。
00 */4 * * * /home/minecraft/scripts/bedrock_script_all.sh s_backup
00 2 * * * /home/minecraft/scripts/bedrock_script_all.sh f_backup
上記の例では、簡易バックアップを4の倍数時間毎の00分、フルバックアップを2時00分に全てのサーバに対して行う設定になっています。好みで変更して下さい。なお、フルバックアップは、サーバを一旦停止して行われますので、停止をしたくない環境の場合は、ご注意下さい。
バックアップは[archive]ディレクトリ内に、サーバ名毎にサブフォルダが作られ、保存されます。
このまま放置すると、ディスク容量が切迫してしまいますので、自動削除を行う様にしたほうが良いと思います。本家様のスクリプトでは、バックアップ時に古いファイルを削除するロジックが含まれていますが、私の場合は、管理上別にしたかったので、/etc/cron.dailyに、以下のスクリプトを設置しています。
※設置時に所有者とパーミッションが正しいことを確認して下さい。
find /home/minecraft/archive/ -name "*.tgz" -mtime +90 -delete
find /home/minecraft/archive/ -name "*.tar.gz" -mtime +90 -delete
find /home/minecraft/archive/ -name "*.tar" -mtime +90 -delete
作成されてから90日以上経過したアーカイブを削除します。日数は、ディスクの空き容量を見ながら調整して下さい。
※フルバックアップは*.tgz、簡易バックアップは*.tar.gz、簡易バックアップの中間ファイルは*.tarですので、3つ指定しています。中間ファイルは、通常運用では残ることはありませんが、ディスクが切迫したり、トラブルが発生して、gzipが失敗したときに発生する可能性がありますので、あえて指定しています。
各スクリプトについて
単体サーバ操作スクリプト
サーバを一つ指定して、各種操作を行います。
単体サーバ操作スクリプトの使用方法は以下の通りです。
$ /home/minecraft/scripts/bedrock_script.sh [動作] [サーバ名] [プロファイル名]
※[プロファイル名]は、[動作]が[update]または[create]の時のみ指定します。
[動作]
start | サーバ起動 | 指定されたサーバを起動します |
stop | サーバ停止 | 指定されたサーバを停止します |
s_backup | 簡易バックアップ | サーバを止めずに必要なファイルのみをバックアップします |
f_backup | フルバックアップ | サーバを止めて全てのファイルをバックアップします |
status | 起動状況確認 | 指定されたサーバの起動状態を確認します |
update | プロファイル更新 | 指定されたサーバのプロファイルを、プロファイル名で指定されたプロファイルで更新します。更新前にフルバックアップが実行されサーバも再起動されます。 |
create | 新規サーバ作成 | 指定されたサーバ名を、プロファイル名で指定されたプロファイルで新規作成します。 |
[サーバ名]
操作対象となるサーバ名を指定します。
[プロファイル名]
操作対象となるプロファイル名を指定します。
プロファイル名を指定しなかった場合は、ダウンロードサイトの現在のダウンロードファイル名を確認し、現在ダウンロードが可能な最新のプロファイルを自動的に判断します。
※配布サイトの構造が変わると使用できなくなったり、意図しない動作になる可能性がありますので、その点は注意して下さい。
MINECRAFT.SERVER-MEMO.NET様のスクリプトからの改造点は以下の通りです。
- 操作対象となるサーバ名を、引数から得られるようにしました。
- 複数のサーバを、ディレクトリを分けて運用できるようにしました。
- バックアップファイルのファイル名と、ディレクトリの様式を、MineOSと同一にしました。
- プロファイルの入れ替え(サーバのバージョンアップ)が行えるようにしました。
- 新規サーバを設置できるようにしました。
全サーバ操作スクリプト
全てのサーバに対して、一括して、各種操作を行います。
全サーバ操作スクリプトの使用方法は以下の通りです。
$ /home/minecraft/scripts/bedrock_script_all.sh [動作] [プロファイル名]
※[プロファイル名]は、[動作]が[update]の時のみ指定します。
サーバ名が無くなっただけで、基本的な使い方は、単体サーバ操作スクリプトと同様ですので、引数の意味はそちらを参照して下さい。ただし、[動作]に[create]は指定できません。
プロファイルダウンロードスクリプト
公式サイトから、サーバソフトウェアをダウンロードします。
プロファイルダウンロードスクリプトの使用方法は以下の通りです。
$ /home/minecraft/scripts/bedrock_profile_download.sh [プロファイル名]
プロファイル名を指定しなかった場合は、ダウンロードサイトの現在のダウンロードファイル名を確認し、現在ダウンロードが可能な最新のプロファイルを自動的に判断します。
通常は、最新版のファイルしかダウンロードできないはずですので、プロファイル名を明示する必要は有りません。
ただ、配布サイトの構造が変わると使用できなくなったり、意図しない動作になる可能性がありますので、その場合はプロファイル名を手動で設定して下さい。
プロファイル名は、公式サイトからダウンロードできるファイルのファイル名で、数値の部分になります。
例)
bedrock-server-1.17.41.01.zip
→プロファイル名: 1.17.41.01
プロファイルをダウンロードしたら、サーバ側のプロファイルを更新して下さい。
実際に更新するには、以下の手順を踏んで下さい。
- 対象となるサーバを停止させる
- 対象となるサーバに対して、updateをプロファイル名を添えて実行する
上記操作は、単体サーバ操作スクリプトか、全サーバ操作スクリプトを用いて下さい。
ターミナルの起動とコマンド操作
サーバの起動は[tmux]を使用して端末を多重化しています。
※MineOSではscreenを採用していました。
ターミナルに接続すると、コマンドを実行することができます。
現在起動しているターミナルの一覧を得るには、以下のコマンドを実行します。
$ tmux ls
特定のサーバのターミナルに接続するには、以下のコマンドを実行します。
$ tmux a -t [セッション名]
セッション名は、サーバ名と同一です。また、先ほどとのターミナルの一覧の先頭、コロンの左側がセッション名となります。
ターミナルから切断するには、[Ctrl]+[B]を押下した後、[D]を押下します。
[Ctrl]+[C]を押下してしまうと、サーバが終了してしまいますので、注意して下さい。
最後に
統合版は、JAVA版には無い、ワクワク感がありますので、まだ体験したことが無い方は、お試し下さい。
なお、最初に記述したとおり、私の管理するサーバでは、JAVA版と、統合版のサーバを1台のマシンで共存させることができていますので、すでにJAVA版のサーバを立てられている方も、いかがでしょうか?