GCPでMinecraftサーバー

# はじめに

Minecraftのサーバーを、GCP(Google Cloud Platform)上にDockerで簡単に立てられないかってことで調べました。
最後に書くけど、Minecraftのライセンスがどうなっているのかよくわからないので、わかる方がいたらそっと教えてください。m(_ _)m

前提として、下記の知識がちょっと必要。

- GCPの設定画面とかがちょっとわかる
- linux(ubuntu)がちょっとわかる
- dockerがちょっとわかる

GCE使うので、無料期間が終わっている人はGCEのお金がかかりますので、ご注意ください。無料期間中でも選択によってはかかるかも。

あとゲームが終わったらVM停止。ぜったい。

# 1.GCEの準備

GCE(Google Compute Engine)とは、GCPで提供するクラウド上の仮想マシン。GCP上ではVM インスタンスと書かれている。VMはバーチャルマシン。

## 1.1. インスタンスの作成

ほぼデフォルトのままで大丈夫だけど、3点変更。

１つ目が、マシンタイプを `e2-medium (vCPU x2、メモリ 4GB)` 以上にすること。
最初ケチって、`e2-micro(vCPU x2、メモリ 1GB)`にしたら、JavaのThreadがどうこう、ヒープメモリがどうこうというエラーが出ていた。（詳しくは割愛）
単純に大きくすることで解消。ただし4GBでも多少カクつく！余裕があればそれ以上もお試してください。私は余裕が・・・

２つ目は、気を付けるというかブートディスクのオペレーティング システムを `Ubuntu` にしました。ほかでもいいと思うけど試してません。

３つ目は、ネットワーキングのネットワーク タグ。`minecraft-server` とかにしておく。
これは、この次の手順でファイアウォールの穴を開けるときに指示します。

起動すると、VM インスタンスのページに作ったのが一覧表示（１件だけかもしれないけど）され、音楽の再生ボタンみたいな右向き三角が出てればOK。
そこの外部IPのところに表示されているIPアドレスが、外から接続する際のIPアドレス。少し発展的な内容ですが、このIPアドレスは、デフォルトでは エフェメラル という起動のたびに変わる設定です。固定にしたい場合は、ネットワーキングのネットワークインタフェースの外部 IPを `エフェメラル` から `IPアドレスを生成` へ変更します。（たぶんちょっと追加料金かかる）

## 1.2. ファイアウォールに穴開け

GCE上のMinecraftのサーバーと、クライアントのデータやり取りは、ポート番号25565を使ってやる。なので、GCPのファイアウォールの25565番を開けてやる必要がある。
GCPのメニューの`VPC ネットワーク`＞`ファイアウォール`＞`ファイアウォール ルールを作成`。
名前は適当でよくて、変更点は2点。

１つ目は、ターゲットを `minecraft-server` へ。1.1.の３つ目で指定したやつです。

２つ目は、ソースIPの範囲を `0.0.0.0/0` へ。誰でも接続できますよっていうこと。接続できるIPアドレスを制限したい人はここで厳密に設定してください。

# 2. Dockerをインストール
作ったVM インスタンスに、Dockerをインストールします。
説明はざっくりとさせていただきます。

まずGCEのVM インスタンスの一覧から、`SSH`って書いてあるプルダウンの中の`ブラウザ ウィンドウで開く`で黒い画面=SSH接続のコンソール画面を出します。そこから先はUbuntuで下記。

```bash
# Dockerインストール用のシェルをダウンロード
$ curl -fsSL get.docker.com -o get-docker.sh

# 実行
$ sudo sh get-docker.sh

# ユーザーをdockerグループに追加
$ sudo usermod -aG docker (ユーザー名)
```
最後のは、dockerコマンドを打つたびに `sudo docker ～`と入力するのが面倒なので、ユーザーをdockerグループに入れるという呪文です。SSH接続の再起動が必要なので、黒い画面を開きなおします。
`docker version` でバージョンが出たら、ここまで成功。

# 3.Minecraftをインストールと起動

インストールというか、Dockerコンテナを作るっていう話です。上記の続きから。

```bash
# データ用のフォルダを作って、権限を設定しておく
$ sudo mkdir /var/mc_data/
$ sudo chmod 777 /var/mc_data/

# MinecraftサーバーのDockerイメージを取得
$ docker pull itzg/minecraft-server

# Minecraftサーバー起動！
$ docker run -d -e EULA=TRUE -p 25565:25565 -v /var/mc_data:/data --name minecraft --restart always itzg/minecraft-server
```

これでサーバーの起動まで終了。
黒い画面は、右上のバツボタンで閉じていいです。


# 4. クライアントから接続

Minecraftのマルチプレイのダイレクト接続で、VMインスタンスの外部IPアドレスを指定することで入れます。

# 5. 終了（必須）

GCEは起動している時間に応じて課金されるので、週末遊んでその次の週末までやらない場合とか、やってない間は止めたいです。というか必須！その止め方。

GCEのVMインスタンスの一覧で、チェックボックスで選択して、音楽の停止ボタンみたいなので停止。
VMインスタンスの停止 という画面が出ます。パソコンでいうと、電源落とすという意味。

# 6. 再起動

また次の週末に起動する方法。

GCEのVMインスタンスの一覧で、チェックボックスで選択して、音楽の再生ボタンみたいなので起動。
パソコンでいうと電源オン。

VMの起動の後、Minecraftサーバーの時間にちょっと時間がかかります。３０秒とか１分とかそれくらい。
待たずに起動すると、Minecraftの画面に下記のエラーが出ました。

```
サーバーへの接続に失敗しました。
io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no further information:
```

ちょっとわかる人だと、VM起動とともにDockerコンテナも動き出すのか心配になりますが、起動します。大丈夫。


# 7.補足と疑問

## 7.1. Minecraft内の時間
サーバーが起動しててログインしてない間、Minecraft内の時間は進むのか、止まるのか。
かまどに木を1スタック突っ込んで燃やし、Minecraftは終了してみました。1個10秒かかるので64個は640秒で約10分です。無駄に誰もログインしていない状態で10分放置しました。

結果は、止まってた。誰も入ってないと時間が止まるのか。
うーん、無駄な時間を過ごしてしまった。けど知っておくべきことを知れてよかった。

よく考えてみると、マルチプレイでログインしてる別の人が離れたところにいる場合でも止まりそう。つまり、プレイヤーがいる周りだけ更新されていくということか。当たり前だったか。
（スポーンチャンクはどうなのか。非常に気になるけど未検証。）

## 7.2. RCON
実はまだよくわかっていないのですが、Minecraftサーバー用のコンソール機能がRCONと言われるもののようです。
ログインしている人のリストとか、キックとか、アイテムを与えるとか、ブロックを作るとか、神様みたいな感じです。チートな状態だと、入力できるコマンドかも。[Minecraft console commands and cheats](https://www.pcgamesn.com/minecraft/minecraft-console-commands-and-cheats)

サーバーを起動した状態（＝Dockerが起動している状態）で実行可能です。
まずVM インスタンスのSSHの黒い画面を起動。
次に下記を入力で、指示できる状態に入ります。
（抜け方はわからないので、いつもCtrl+Cで抜けてます。）

```bash
$ docker exec -it minecraft rcon-cli
```

起動しているDockerコンテナの中に入って、rcon-cliというモジュールを実行するというもの。
下記のように、後ろにコマンド（例ではlistコマンド）を入れると、そのコマンドだけ実行して終わる。

```bash
$ docker exec -it minecraft rcon-cli list
```

上記を連続的に呼び出すようにshellを組めば、複数のコマンドをまとめたものとか、大きな建築物とかプログラムでできそうな感じですね。

## 7.3. Minecraftの料金
サーバーのexeを実行すると、サーバーの人だけは料金はかかり、そこへ接続する人はかからないという話をどこかで聞いた。（やってない）

今回の手順の場合はどうなんだろうか。ID/パスワードをどこかで聞かれるかなと思ってたけど、最終的に聞かれなかった。私はクライアントのMinecraftのライセンスを持っていて、普通に接続できていることがそれゆえなのか、なくてもできるのか、結局わからずじまいのままです。すみません。