この記事は ドワンゴ Advent Calendar 2024 8日目の記事です。
はじめに
こんにちは! @azutake です。
普段はニコニコのサブスクを一画面で管理出来るようにする 定期お支払いの管理 というものに関わっていたり、カスタムキャストというアバター作成アプリの開発をしていたりします。
アドベントカレンダー4日目にも書いているので、興味があればそちらも読んでね!
さて今回は、MinecraftのMOD入りサーバをDockerで運用していると直面する課題の解決方法について紹介します。
サーバの永続化すべきファイルの管理、特にmodpackを使用する場合は変更されるファイルが多く、コンテナ化する上で管理コストが増大化しやすいです。この記事では、overlayfsを活用してこの課題を解決してみた話をします。
課題
Minecraftサーバをコンテナ化して運用していた際、以下のような課題に直面しました。
- 本来、バニラサーバであれば
world
ディレクトリのみを永続化すれば十分 - しかしForge等のMODサーバでは、多数のファイルやディレクトリがサーバ稼働中に動的に変更されていく
- 上記を解決するために、単純にすべてのディレクトリをボリュームマウントしてしまうと、せっかくイメージにmodpackを展開してもイメージとボリューム両方に同等のデータを保持することとなってしまう…
- modpackのアップデート時、何を上書きしても大丈夫なのか分からない…
以前dockerの内部構造について調べていた時、overlayfsというものがあるのを知り、もしかしてこれに応用できるのでは…?というのが今回の発端です。
overlayfsって???
Ref: https://docs.docker.jp/storage/storagedriver/overlayfs-driver.html
まずOverlayFSについて一言で説明すると、Dockerの内部でもデフォルトとして使われている、Linuxカーネルに搭載されているレイヤー型のファイルシステムの一つです
OverlayFSではレイヤー構造でファイル・ディレクトリの変更を管理することが出来るファイルシステムになっています。
- Upper Layer
- Read-Writeなレイヤー
- ここに最終レイヤーの変更内容が入る
- Lower Layer
- Read-Onlyなレイヤー
- ここでは複数のレイヤーが存在出来る
- Dockerでは、ここをイメージレイヤーとして使っている。
- Merged View
- Lower Layerを一つずつ重ねていき、最後にUpper Layerを重ねた状態。実際に見えるファイルシステムはこれ。
この構造のおかげで、Forge関連など基本的なファイルはdockerイメージに、それ以外のワールドデータやconfig、マップなどはボリュームに保存されるようになるわけです。わぁい!
実装例:modpack(ATM9)サーバの構築
FROM openjdk:17-slim
WORKDIR /minecraft
# 必要なパッケージを入れておく
RUN apt-get update && apt-get install -y \
curl wget unzip \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# ATM9 0.3.5をダウンロード&展開
RUN wget https://mediafilez.forgecdn.net/files/5900/31/Server-Files-0.3.5.zip \
&& unzip Server-Files-0.3.5.zip \
&& mkdir /minecraft/base \
&& mv Server-Files-0.3.5/* /minecraft/base/ \
&& rmdir Server-Files-0.3.5 \
&& rm Server-Files-0.3.5.zip \
&& chmod +x /minecraft/base/startserver.sh
WORKDIR /minecraft/base
# インストールのみモードでシェルを実行してforge等を展開しておく
RUN ATM9_INSTALL_ONLY=true ./startserver.sh
WORKDIR /minecraft
CMD ["./startserver.sh"]
services:
atm9:
build:
context: /opt/minecraft/atm9/build
ports:
- "25565:25565"
volumes:
- type: bind
source: /opt/minecraft/atm9/data
target: /minecraft/data
command: >
sh -c "mkdir -p /minecraft/data/changes &&
mkdir -p /minecraft/data/work &&
mkdir -p /minecraft/data/merged &&
mount -t overlay overlay -o lowerdir=/minecraft/base,upperdir=/minecraft/data/changes,workdir=/minecraft/data/work /minecraft/data/merged &&
cd /minecraft/data/merged &&
./startserver.sh"
cap_add:
- SYS_ADMIN
security_opt:
- apparmor:unconfined
restart: unless-stopped
stdin_open: true
tty: true
上記dockerfile, docker composeを実行すると
- /opt/minecraft/atm9/data/changes に 変更されたファイルのみが 格納されるようになる
- forgeやmods, librariesなどはdockerイメージ上でread-onlyとして保持される
ことが実現できます!
私が運用しているサーバでは、このおかげで、特にmodpackのアップデートの際、管理負荷を大幅に軽減することが出来ました。
おわりに
今回の記事は完全に趣味の話でしたが、普段は課金システムの部署に所属しており、一緒にニコニコの課金やサブスクなどのシステムを手伝ってくれる仲間を募集しております。
ぜひお気軽にご応募ください!