久しぶりにマルチサーバを立てて友人と遊びたくなったので
今回はサーバをContainer化して構築してみました
開発環境
- OS
- Ubuntu 22.04
- Middleware
- Docker 20.10.23
ホストマシンスペック
下記スペックにてGoogleCloud ComputeEngineで起動
- OS
- Debian 11 bullseye
- Spec
- e2-medium
- vCPU : 2
- mem : 4GB
- e2-medium
- Disk
- pd-balanced
- 10GB
- pd-balanced
- 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分毎にサーバのストレージ内にバックアップを作成するスクリプト
#!/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にエクスポートするスクリプト
#!/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で動かしてみた! とかになるんでしょうか(笑)