GCEにMinecraftサーバーを立てて、バックアップを定期的に取りたい

ちゃんと技術的なメモも残しておいたほうが良いよねということで、書きます。どうやってマイクラ鯖をGoogleのクラウドに載せるか。

まず、このページを見ます。Google様 ぶっちゃけこれで完結します。

ただ一応、バックアップのスクリプトも書いたのでそこを紹介する。

マインクラフトの鯖ヲ立てるのは非常に簡単で、Minecraftの公式サイトからサーバーアプリをDLしてきて、好きなところにおいて、そのアプリを実行するだけ。なんという簡単な。ただし、初回実行時はeula.txtというファイルの中の設定をFalseからTrueにしなければならない。それを直す。そしてまた起動すればおしまい。

ただ、他の人が実際にサーバにアクセスして遊べるようにするためには、ポートを開ける必要がある。ファイアウォール設定。MinecraftはTCPの25565番使っているので、これを開放するように設定します。そしたらもう実際に遊べるようになります。簡単すぎる。

これだけだと常に起動しっぱなしで、データが壊れた時におしまいになるので、データを定期的にバックアップしたいですね。そのためにシェルスクリプトを書き申しました。これは、サーバーの入っているフォルダを丸ごとコピーするだけです。コピー先のフォルダ名を日時にして、3日分だけ保存しておきます。3日を超えたバックアップデータを削除するようにして、直近の3日間のみのバックアップデータを残すようにしました。無尽蔵にコピペし続けると容量を食ってしまうのでね。bashが便利すぎてやばいというお話でした。もちろんこれだとGCEのインスタンスを落としたら全部消えてしまうので、本音を言えば他のDriveとかに移しておきたいんですが、いまはまだいいや。さすがにね。


#!/bin/bash

screen -r mcs -X stuff '/save-all\n/save-off\n'

find backups-ver-1-15-2/ -maxdepth 1 -name "$(date --date "-3 days" "+%Y%m%d")*" -exec rm -r "{}" \;

cp -r ver-1-15-2 backups-ver-1-15-2/$(date "+%Y%m%d_%H")

screen -r mcs -X stuff '/save-on\n'

    

screenについてはあまり気にしなくていいです。tmuxとかdocker run -d するときと同じような感じ。つまり、Minecraftのサーバーは別のターミナルで動いてるので、マイクラ鯖自体ににコマンドを投げたい場合には


screen -r mcs -X stuff '実行したいコマンド'
    

という感じにして、screenの中にコマンドを投げます。そんで、次に、過去3日間に該当しないバックアップを先に削除するコマンドを叩きます。findコマンドを駆使します。最後に、新たなバックアップをその時の日付で作成します。cpコマンドを駆使します。それで終了です。screen -r mcs -X の初めと終わりでなにをしているかというと、マイクラ鯖はデフォルトで自動で鯖のデータを保存するようになっているんですが、バックアップとるときだけ一時的にその保存を中止する、ということにしています。そんで、バックアップ作り終えたらまた保存設定をONにすると。

で、これを定期的に実行したいので、cronを呼んで、6時間に一回とかに設定します。もっと頻度多めでもいいよ。これは、crontab -e と打てば編集できます。これを最後の行に足せば、あとはサーバーを動かしている限りcronが回っていい具合にさっきのshellが叩かれ続けます。ちなみにちゃんと動くかはまだ検証できていないので、3日後をお待ちください。3日経つ前にそれおかしいぞっていうところを発見した方は教えてください。


0 */6 * * * /home/minecraft/backup.sh
    

過去3日間て少なくね?と思ったかもしれませんが、とりあえずお試しでそう書きました。たぶんあとで14日間とかに増やすでしょう。しらんけど。

ちなみに、bashの躓きポイントとして、ダブル、シングルクオーテーションの違いがあります。ダブルで囲むと、中身の変数が展開されて、ちゃんと"$date" は 202004として表示されますが、'$date'は$dateとして捉えられてしまいます。参考資料

もう一つあげると、3行目はfindでmatchしたディレクトリ(ファイル)名を-execでrm -r を呼び出すことで、日付にマッチするものだけ削除するという仕組みを実現しています。参考資料

[修正済み]最後に、目敏い方はお気付きかもしれませんが、下の二行の中で、dateに渡すformatの書き方が異なっています。"+%Y%m%d"と+"%Y%m%d"。


find backups-ver-1-15-2/ -maxdepth 1 -name "$(date --date "-3 days" "+%Y%m%d")*" -exec rm -r "{}" \;

cp -r ver-1-15-2 backups-ver-1-15-2/$(date +"%Y%m%d_%H")
    

先ほどのクオーテーションの理屈で言えばどちらも同じだと思うんですが、find行の方はなぜか +"%Y%m%d"で受け付けてくれませんでした(~~)。詳しい方教えてください。

[追記] この上の現象、やっぱり$()で囲むと+"%Y%m%d"ではなくて"+%Y%m%d"と書かなければいけないようでした。なんで〜。"とか 'とか$()とかには注意ですね。よくわからんわ。