【Fly.io】ゼロスケール可能なminecraftサーバーを立てる

# 概要
minecraftを友人とやることになり、せっかくなら自前でサーバーを建てようという事になりました。

昔に比べてminecraftのマルチサーバーを立てることのハードルは下がっているのを感じます。様々な企業がminecraft向けのサーバーレンタルプランを提供するようになっていますし、Realmもあります。

そこで借りてみようとするわけです。

大体８人ぐらいで安定して動かすためにメモリは８GB必要です。
レンタルすると**８GBで月3000-7000円。**

高くないですか？

常に動かしているわけではないですし、そこまでのスペックをフルで１ヶ月使い切るわけではないハズです。

また、先払いなのでとりあえずサーバーを立ててみようぜってのがやりにくいわけです。

ので、今回は従量課金のfly.ioでオートスケールしてくれるminecraftサーバーを立てます。

### 環境
- windows 10
- minecraft 1.19.4
### 必要なもの
- fly.io のアカウント
- flyctlのインストール
    - https://fly.io/docs/hands-on/install-flyctl/
- terraformのインストール
    - https://docs.uipath.com/installation-and-upgrade/lang-ja/docs/installing-terraform
- flyctlとterraformがCLIで操作できる

# 方法
今回は、terraformで設定を書いて、fly.ioのサーバーでminecraft imageを動かします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611678/68b79a03-f96f-69bb-ed11-fe59c916fe98.png)

::: note info 
**terraformって何**
いわゆるIacツール。クラウドとかのインフラの構成をソースコードで書ける。
- サーバー内で動くプログラムについての設定はできない。
- サーバーを構築する時点でのパラメータをソースコードで書いていける。
::: 

## 流れ
作業はこんな感じの流れでやっていきます。２つのpowershellを利用するのでちょっとわかりにくいかも

- ``flyctl auth token`` でトークンを得る
- ``flyctl machine api-proxy`` で　プロキシを開く
- ``main.tf``を書く
- ``terraform init`` で初期化
- ``terraform apply``で立ち上げる

一つづつ見ていきましょう。

### fly.ioのTOKENをゲット
PowerShellを開き、作業ディレクトリに移動したら
``` bash 
flyctl auth token
```
を実行します。
そうするとブラウザで認証画面が開くので、認証する。
```powershell
PS C:\Users\Documents\minecraft_server> flyctl auth token
TOKENTOKENTOKENTOEKENTOEK
```
隠してあるところにトークンが出てきたら成功です。
### プロキシを開く
```bash
flyctl machine api-proxy
```
これでプロキシが開けます。これを開いておかないとterraformで失敗するので注意。

```powershell
PS C:\Users\Documents\minecraft_server> flyctl machine api-proxy
automatically selected personal organization: yourmail.com
Proxying local port 4280 to remote [_api.internal]:4280
```

::: note warn
プロキシを開いた状態のまま、このウィンドウは閉じないでください。
次からの作業は別のpowershellを開いて実行します。
:::

### 設定ファイルを書く
別のshellを開き、作業ディレクトリに移動。
そしたら``main.tf``を作成します。
適当にエディタでもいいしなんでもいいので作りましょう。
terraformは現在ディレクトリの``main.tf`` ファイルを参照して設定を行います。
```terraform
terraform {
  required_providers {
    fly = {
      source = "fly-apps/fly"
      version = "0.0.16"
    }
  }
}
provider "fly" {fly_api_token = $(FLY_API_TOKEN)}
```
プロバイダがfly.ioで、そのversion 0.0.16を使用しますよと指定しています。
$(FLY_API_TOKEN)は先程取得したfly.ioのトークンを入れておいてください。

## 初期設定
```powershell
terraform init
```
これで初期設定が行われます。
以下のようになればOKです。
```powershell
PS C:\Users\Documents\minecraft_server> terraform init

Initializing the backend...

Initializing provider plugins...
- Reusing previous version of fly-apps/fly from the dependency lock file
- Using previously-installed fly-apps/fly v0.0.16

Terraform has been successfully initialized!
```
## main.tfに詳細を追加
問題がなければ、以下のように``main.tf``に**追記**していきます。
```terraform
resource "fly_app" "minecraft" {
    name = "flymcraftserver"
    org = "personal"
}

resource "fly_volume" "mcVolume" {
    app = "flymcraftserver"
    name = "mcVolume"
    size =15
    region = "nrt"
    depends_on = [
      fly_app.minecraft
    ]
}
resource "fly_ip" "mcIP" {
    app = "flymcraftserver"
    type ="v4"
    depends_on = [
      fly_app.minecraft
    ]
}
resource "fly_machine" "mcServer" {
    name = "mc-server"
    region = "nrt" 
    app = "flymcraftserver"
    image = "itzg/minecraft-server:latest"
    env = {
      EULA = "TRUE"
      ENABLE_AUTOSTOP = "TRUE"
      AUTOSTOP_TIMEOUT_EST = 120
      AUTOSTOP_TIMEOUT_INIT = 120
      MEMORY ="7G"
      AUTOSTOP_PKILL_USE_SUDO = "TRUE"
    }
    services = [
      {
        ports = [
            {
                port = 25565
            }
        ]
        protocol = "tcp"
        internal_port = 25565
      }
    ]
    mounts = [
      {
        path = "/data"
        volume = fly_volume.mcVolume.id
      }
    ]
    cpus = 4
    memorymb = 8192
    depends_on = [
      fly_volume.mcVolume,fly_app.minecraft
    ]
}
```
リソースの設定がつらつらと並んでいます。
fly_machine のenvブロック内がスケーリングの設定をしています。

```powershell
terraform apply
```
　terraform applyでついにサーバーが用意されます。祈りましょう。
```powershell
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
```
色々出ますが、こんな感じでcomplete!とでてたら完成です。一応fly.ioのDashboardを確認してみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611678/7f1271ee-f216-dd79-4dc6-fdff11888985.png)
できていました！ﾔｯﾀﾈ

ではminecraftで実際に入ってみましょう！
ダッシュボードからIPadressは確認できます。
![2023-03-17_14.11.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611678/80d7a67f-6421-7849-5e90-eab72720c74f.png)
接続できました！！
あとはちゃんと切断して２分後ぐらいにサーバーが休止しているか確認しましょう！

# 運用
最初の目的は8GBメモリで月3000円もかからずにサーバーを立てるということでした。

現在3人で一日12時間ぐらい接続して**一日あたり$0.5**です。
このペースで一ヶ月で計算すると$15ぐらいですね。

企業でサーバーを借りるのに比べると相当安くで済んでいるのではないでしょうか？
また、minecraftに飽きてこのサーバーをほったらかしにしてもその間はお金が発生しないので安心です。

# まとめ
今のペースで月に2000円ぐらいなら、サーバーを借りるよりやすいような気がします。

常に24時間8人ぐらいで稼働しているのを想定するなら定額サーバーを借りたほうが安いかもしれませんが、とりあえずやるならこれぐらいでよさそうです。

それでは良いminecraft生活を！

![2023-03-17_20.40.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611678/f47abfb2-5e4b-3bd4-72bf-d2b50db07ec4.png)




# 参考
https://fly.io/blog/scale-to-zero-minecraft/

https://qiita.com/souhei-etou/items/7876767f041543321006