LoginSignup
4
4

MinecraftのMODサーバをDockerコンテナを利用して構築する

Posted at

久しぶりにマルチサーバを立てて友人と遊びたくなったので
今回はサーバをContainer化して構築してみました

開発環境

  • OS
    • Ubuntu 22.04
  • Middleware
    • Docker 20.10.23

ホストマシンスペック

下記スペックにてGoogleCloud ComputeEngineで起動

  • OS
    • Debian 11 bullseye
  • Spec
    • e2-medium
      • vCPU : 2
      • mem : 4GB
  • Disk
    • pd-balanced
      • 10GB
  • Middleware
    • Podman 3.0.1

Podman installまで

コンテナランタイムはPodmanを利用します

# apt-get update
# apt-get install -y podman
# podman -v
podman version 3.0.1

Dockerイメージ作成

※ここから開発サーバ(PC)での作業
Minecraftサーバ本体となるコンテナイメージを作成します

Dockerfile作成

$ vi Dockerfile
  • 要件
    • openjdk, v20 : javaが実行できる必要があるため (最新の22だと逆に動かないので20を利用)
    • curl : fabricからランチャー/ローダーをダウンロードするため
    • mods : modsディレクトリの中身はあらかじめ開発PCで用意しておいてCOPYでコンテナに配置する
    • world : /root/worldをVOLUMEとしてマウントし,ホストマシンと共有する →データの永続化が可能になる
    • port : EXPOSEで25565を開放する
    • command : ENTRYPOINTでminecraftサーバの起動コマンドを指定する
# This is the Dockerfile for Fabric(Mod enabled) Minecraft. version 1.20.1
FROM openjdk:20-slim-bullseye

LABEL maintainer="cokemaniaIIDX cokemaniaiidx@gmail.com"

RUN apt-get update && \
    apt-get install -y curl && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

WORKDIR /root/

RUN curl -OJ https://meta.fabricmc.net/v2/versions/loader/1.20.1/0.14.22/0.11.2/server/jar && \
    java -jar fabric-server-mc.1.20.1-loader.0.14.22-launcher.0.11.2.jar nogui
RUN sed -i -e 's/difficulty=easy/difficulty=hard/g' server.properties && \
    sed -i -e 's/false/true/g' eula.txt

COPY files/mods/ /root/mods
VOLUME /root/world

EXPOSE 25565

ENTRYPOINT [ "java", "-jar", "-Xms3G", "-Xmx3G", "fabric-server-mc.1.20.1-loader.0.14.22-launcher.0.11.2.jar", "nogui" ]

build用ファイル配置

$ mkdir -p files/mods
$ cd files/mods
$ gsutil cp gs://BUCKET_MODS_SAVED/* ./  # Storageに保存しておいたものを持ってくる

※ 筆者はDiggus Maximusという一括破壊MODを入れました

build & push

$ gcloud auth loginでArtifactRegistryへpush権限のあるユーザ(サービスアカウント)にログインしてから実施

$ docker build -t asia-northeast1-docker.pkg.dev/<MY_PROJECT_ID>/<ARTIFACT_RESISTORY_REPO>/fabric-minecraft:latest .
$ docker push asia-northeast1-docker.pkg.dev/<MY_PROJECT_ID>/<ARTIFACT_RESISTORY_REPO>/fabric-minecraft:latest

コンテナ起動

※ ここからはホストマシンでの作業

  • イメージプル
// まずログイン
# gcloud auth print-access-token | podman login -u oauth2accesstoken --password-stdin asia-northeast1-docker.pkg.dev

// 作ったイメージをpull
# podman pull asia-northeast1-docker.pkg.dev/<MY_PROJECT_ID>/<ARTIFACT_RESISTORY_REPO>/fabric-minecraft:latest
  • 起動
# podman run -d -p 25565:25565 --volume=/mnt/world:/root/world --name minecraft asia-northeast1-docker.pkg.dev/<MY_PROJECT_ID>/<ARTIFACT_RESISTORY_REPO>/fabric-minecraft:latest

→ Minecraftクライアントを起動して、サーバにアクセスできればOK!

自動起動設定

  • systemdファイル生成 & 登録
# podman generate systemd --new --files --name minecraft

# cp -Z container-minecraft.service /etc/systemd/system

# systemctl daemon-reload
# systemctl enable container-minecraft.service
  • 再起動後、確認
# podman ps
CONTAINER ID  IMAGE                                                                             COMMAND  CREATED             STATUS                 PORTS                     NAMES
df5105884766  asia-northeast1-docker.pkg.dev/<MY_PROJECT_ID>/<ARTIFACT_RESISTORY_REPO>/fabric-minecraft:latest           About a minute ago  Up About a minute ago  0.0.0.0:25565->25565/tcp  minecraft

# systemctl status container-minecraft.service
● container-minecraft.service - Podman container-minecraft.service
     Loaded: loaded (/etc/systemd/system/container-minecraft.service; enabled; vendor preset: enabled)
     Active: active (running) since Sun 2023-09-24 08:04:30 UTC; 1min 21s ago
       Docs: man:podman-generate-systemd(1)
    Process: 546 ExecStartPre=/bin/rm -f /run/container-minecraft.pid /run/container-minecraft.ctr-id (code=exited, status=0/SUCCESS)
    Process: 555 ExecStart=/usr/bin/podman run --conmon-pidfile /run/container-minecraft.pid --cidfile /run/container-minecraft.ctr-id --cgroups=no-conmon --replace -d -p 25565:25565 --volum>
   Main PID: 1176 (conmon)
      Tasks: 2 (limit: 19184)
     Memory: 28.4M
        CPU: 432ms
     CGroup: /system.slice/container-minecraft.service
             └─1176 /usr/bin/conmon --api-version 1 -c df5105884766198d78daed04e5f2a8f7eb8c61f89366b1ad829b11b89b6a842a -u df5105884766198d78daed04e5f2a8f7eb8c61f89366b1ad829b11b89b6a842a -r>

Sep 24 08:04:29 minecraft-server01 systemd[1]: Starting Podman container-minecraft.service...
Sep 24 08:04:30 minecraft-server01 podman[555]: 2023-09-24 08:04:30.030078134 +0000 UTC m=+0.656216844 container remove 36565fdf04c65d01ef5e9b1db5ca0e9ef79ba348b043b4ee47eae97c6d3cbf44 (image=asia->
Sep 24 08:04:30 minecraft-server01 podman[555]: 36565fdf04c65d01ef5e9b1db5ca0e9ef79ba348b043b4ee47eae97c6d3cbf44
Sep 24 08:04:30 minecraft-server01 podman[555]: 2023-09-24 08:04:30.070354064 +0000 UTC m=+0.696492751 container create df5105884766198d78daed04e5f2a8f7eb8c61f89366b1ad829b11b89b6a842a (image=asia->
Sep 24 08:04:30 minecraft-server01 podman[555]: 2023-09-24 08:04:30.523714846 +0000 UTC m=+1.149853570 container init df5105884766198d78daed04e5f2a8f7eb8c61f89366b1ad829b11b89b6a842a (image=asia-no>
Sep 24 08:04:30 minecraft-server01 podman[555]: 2023-09-24 08:04:30.529661827 +0000 UTC m=+1.155800514 container start df5105884766198d78daed04e5f2a8f7eb8c61f89366b1ad829b11b89b6a842a (image=asia-n>
Sep 24 08:04:30 minecraft-server01 podman[555]: df5105884766198d78daed04e5f2a8f7eb8c61f89366b1ad829b11b89b6a842a
Sep 24 08:04:30 minecraft-server01 systemd[1]: Started Podman container-minecraft.service.

→ ゲーム側でもアクセスできることを確認
問題なさそう!

バックアップスクリプト作成

ホストサーバのcronにバックアップスクリプトを登録します。

  • 5分毎にサーバのストレージ内にバックアップを作成するスクリプト
/usr/local/bin/backup_world.sh
#!/bin/bash

## ファイル数管理
while [ $(ls /mnt/backups | wc -l) -gt 12 ]
do
  rm $(ls /mnt/backups | head -1)
done

## バックアップ実行
tar -czf /mnt/backups/world_$(date "+%Y-%m-%d-%H-%M").tar.gz /mnt/world
  • 1時間ごとにバックアップをCloudStorageにエクスポートするスクリプト
/usr/local/bin/export_backup.sh
#!/bin/bash

## 変数
BUCKET_NAME="backup-bucket"
VERSION="v1_20_1"
FILE=$(ls /mnt/backups | tail -1)


## バックアップ実行
gsutil cp /mnt/backups/$FILE gs://$BUCKET_NAME/world_$VERSION/world.tar.gz

※ バックアップを上書きしたくない場合はworld.tar.gzと指定せずにディレクトリまで指定すればOK

  • cronに登録
# crontab -e
*/5 * * * * /usr/local/bin/backup_world.sh > /dev/null 2>&1
0 */1 * * * /usr/local/bin/export_backup.sh > /dev/null 2>&1

終わり

コンテナのディスク永続化の基本を理解して
Minecraftサーバ構築を通じてうまく応用できたと思います

あとPodmanのsystemdファイル出力機能はとても便利ですね
本業でもapacheコンテナ起動などで利用しております

以上です
次記事を作るとしたら 今度はKubernetesで動かしてみた! とかになるんでしょうか(笑)

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4