このページは筆者の構築手順を元にgpt-5.2で生成しました。
このページは、Ubuntu 24.04 上で itzg/minecraft-server(Vanilla) を Docker Compose で動かし、ログを journald(journalctl) に残しつつ、ワールドを 無停止で restic バックアップするための手順をまとめたものです。
0. プレースホルダ
このWiki内の以下は、各自の環境に合わせて読み替えます。
-
<COMPOSE_DIR>:docker-compose.ymlを置くディレクトリ
例:/home/<USER>/minecraft -
<VOLUME_NAME>:Minecraftデータが入っている Docker ボリュームの「実名」
例:minecraft_minecraft_volume(環境により異なる) -
<RESTIC_REPO_DIR>:resticリポジトリの保存先 -
<RESTIC_PW_FILE>:resticパスワードファイル
1. Docker Compose(Minecraft + journald)
1.1 docker-compose.yml
<COMPOSE_DIR>/docker-compose.yml
services:
minecraft:
image: itzg/minecraft-server:latest
pull_policy: daily
ports:
- "25565:25565"
environment:
EULA: "TRUE"
# 2GB RAM マシン向けの目安(必要に応じて調整)
MEMORY: "1200M"
volumes:
- minecraft_volume:/data
# コンテナログをjournaldへ
logging:
driver: journald
volumes:
minecraft_volume:
1.2 起動
$ cd <COMPOSE_DIR>
$ sudo docker compose up -d
1.3 ログ確認
Docker経由:
$ sudo docker compose logs -f
journald経由:
$ journalctl -f CONTAINER_IMAGE=itzg/minecraft-server:latest
2. swap(Ubuntu 24.04)
メモリが小さいマシンでは OOM 回避のため swap を用意します(例:2GB)。
2.1 現状確認
$ free -h
$ swapon --show
2.2 swapfile作成
$ sudo fallocate -l 2G /swapfile
$ sudo chmod 600 /swapfile
$ sudo mkswap /swapfile
$ sudo swapon /swapfile
2.3 永続化(再起動後も有効)
$ echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
3. restic(無停止バックアップ・1時間おき・保持30日)
3.1 resticリポジトリとパスワードファイル
$ sudo install -d -m 0700 <RESTIC_REPO_DIR>
$ sudo install -d -m 0700 $(dirname <RESTIC_PW_FILE>)
$ sudo sh -c 'umask 077; printf "%s\n" "<CHOOSE_A_STRONG_PASSWORD>" > <RESTIC_PW_FILE>'
初回のみ init:
$ sudo docker run --rm \
-v <RESTIC_REPO_DIR>:/repo \
-v "$(dirname <RESTIC_PW_FILE>)":/pw:ro \
-e RESTIC_REPOSITORY=/repo \
-e RESTIC_PASSWORD_FILE=/pw/$(basename <RESTIC_PW_FILE>) \
restic/restic:latest init
3.2 バックアップ対象ボリューム(実名)を確認(重要)
Composeの named volume は、環境により「プロジェクト名付き」になることがあります。
$ cd <COMPOSE_DIR>
$ cid=$(sudo docker compose ps -q minecraft)
$ sudo docker inspect "$cid" --format '{{range .Mounts}}{{println .Name "->" .Destination}}{{end}}'
出力例:
<VOLUME_NAME> -> /data
この <VOLUME_NAME> を次のスクリプトに設定します。
3.3 バックアップスクリプト
/usr/local/sbin/minecraft-restic-backup.sh
#!/usr/bin/env bash
set -euo pipefail
COMPOSE_DIR="<COMPOSE_DIR>"
SERVICE_NAME="minecraft"
VOLUME_NAME="<VOLUME_NAME>"
RESTIC_REPOSITORY="<RESTIC_REPO_DIR>"
RESTIC_PASSWORD_FILE="<RESTIC_PW_FILE>"
RESTIC_IMAGE="restic/restic:latest"
TAG="minecraft"
cd "$COMPOSE_DIR"
# Minecraftに対して無停止で整合性を取る
sudo docker compose exec -T "$SERVICE_NAME" rcon-cli save-off || true
sudo docker compose exec -T "$SERVICE_NAME" rcon-cli save-all flush || true
# バックアップ(volumeをread-onlyでマウント)
sudo docker run --rm \
-v "${VOLUME_NAME}:/data:ro" \
-v "${RESTIC_REPOSITORY}:/repo" \
-v "$(dirname "$RESTIC_PASSWORD_FILE"):/pw:ro" \
-e RESTIC_REPOSITORY="/repo" \
-e RESTIC_PASSWORD_FILE="/pw/$(basename "$RESTIC_PASSWORD_FILE")" \
"$RESTIC_IMAGE" backup /data --tag "$TAG" --host "$TAG"
# 保持:直近30日だけ残す(古いスナップショットを削除しprune)
sudo docker run --rm \
-v "${RESTIC_REPOSITORY}:/repo" \
-v "$(dirname "$RESTIC_PASSWORD_FILE"):/pw:ro" \
-e RESTIC_REPOSITORY="/repo" \
-e RESTIC_PASSWORD_FILE="/pw/$(basename "$RESTIC_PASSWORD_FILE")" \
"$RESTIC_IMAGE" forget --tag "$TAG" --keep-within 30d --prune
# 書き込み再開
sudo docker compose exec -T "$SERVICE_NAME" rcon-cli save-on || true
実行権限:
$ sudo chmod +x /usr/local/sbin/minecraft-restic-backup.sh
4. systemd timer(1時間おきで自動実行)
4.1 systemd service
/etc/systemd/system/minecraft-restic-backup.service
[Unit]
Description=Minecraft restic backup (hourly, online)
Wants=network-online.target
After=network-online.target docker.service
Requires=docker.service
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/minecraft-restic-backup.sh
4.2 systemd timer
/etc/systemd/system/minecraft-restic-backup.timer
[Unit]
Description=Run Minecraft restic backup every hour
[Timer]
OnCalendar=hourly
Persistent=true
RandomizedDelaySec=5m
[Install]
WantedBy=timers.target
有効化:
$ sudo systemctl daemon-reload
$ sudo systemctl enable --now minecraft-restic-backup.timer
動作確認:
$ systemctl list-timers --all | grep minecraft-restic
$ sudo systemctl start minecraft-restic-backup.service
$ journalctl -u minecraft-restic-backup.service -f
5. トラブルシュート
5.1 バックアップが小さすぎる(0 files)/ 0B になる
/data に実データが見えていない(ボリューム名違い)の可能性が高いです。
$ sudo docker compose exec -T minecraft ls -lah /data
$ cid=$(sudo docker compose ps -q minecraft)
$ sudo docker inspect "$cid" --format '{{range .Mounts}}{{println .Type .Name .Source "->" .Destination}}{{end}}'
/data に world/ や server.properties が無い場合は、<VOLUME_NAME> の見直しを行います。