minecraft/Minecraft\357\274\210Vanilla\357\274\211Docker\346\247\213\347\257\211 + journald\343\203\255\343\202\260 + Restic\347\204\241\345\201\234\346\255\242\343\203\220\343\203\203\343\202\257\343\202\242\343\203\203\343\203\227\357\274\210Ubuntu 24.04 / systemd timer\357\274\211.md
... ...
@@ -1,240 +0,0 @@
1
-このページは筆者の構築手順を元にgpt-5.2で生成しました。
2
-
3
-このページは、Ubuntu 24.04 上で **`itzg/minecraft-server`(Vanilla)** を Docker Compose で動かし、ログを **journald(journalctl)** に残しつつ、ワールドを **無停止で restic バックアップ**するための手順をまとめたものです。
4
-
5
-
6
----
7
-
8
-## 0. プレースホルダ
9
-このWiki内の以下は、各自の環境に合わせて読み替えます。
10
-
11
-- `<COMPOSE_DIR>`:`docker-compose.yml` を置くディレクトリ
12
- 例:`/home/<USER>/minecraft`
13
-- `<VOLUME_NAME>`:Minecraftデータが入っている Docker ボリュームの「実名」
14
- 例:`minecraft_minecraft_volume`(環境により異なる)
15
-- `<RESTIC_REPO_DIR>`:resticリポジトリの保存先
16
-- `<RESTIC_PW_FILE>`:resticパスワードファイル
17
-
18
----
19
-
20
-## 1. Docker Compose(Minecraft + journald)
21
-
22
-### 1.1 docker-compose.yml
23
-`<COMPOSE_DIR>/docker-compose.yml`
24
-
25
-```yaml
26
-services:
27
- minecraft:
28
- image: itzg/minecraft-server:latest
29
- pull_policy: daily
30
- ports:
31
- - "25565:25565"
32
- environment:
33
- EULA: "TRUE"
34
-
35
- # 2GB RAM マシン向けの目安(必要に応じて調整)
36
- MEMORY: "1200M"
37
-
38
- volumes:
39
- - minecraft_volume:/data
40
-
41
- # コンテナログをjournaldへ
42
- logging:
43
- driver: journald
44
-
45
-volumes:
46
- minecraft_volume:
47
-```
48
-
49
-### 1.2 起動
50
-```bash
51
-$ cd <COMPOSE_DIR>
52
-$ sudo docker compose up -d
53
-```
54
-
55
-### 1.3 ログ確認
56
-Docker経由:
57
-```bash
58
-$ sudo docker compose logs -f
59
-```
60
-
61
-journald経由:
62
-```bash
63
-$ journalctl -f CONTAINER_IMAGE=itzg/minecraft-server:latest
64
-```
65
-
66
----
67
-
68
-## 2. swap(Ubuntu 24.04)
69
-メモリが小さいマシンでは OOM 回避のため swap を用意します(例:2GB)。
70
-
71
-### 2.1 現状確認
72
-```bash
73
-$ free -h
74
-$ swapon --show
75
-```
76
-
77
-### 2.2 swapfile作成
78
-```bash
79
-$ sudo fallocate -l 2G /swapfile
80
-$ sudo chmod 600 /swapfile
81
-$ sudo mkswap /swapfile
82
-$ sudo swapon /swapfile
83
-```
84
-
85
-### 2.3 永続化(再起動後も有効)
86
-```bash
87
-$ echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
88
-```
89
-
90
----
91
-
92
-## 3. restic(無停止バックアップ・1時間おき・保持30日)
93
-
94
-### 3.1 resticリポジトリとパスワードファイル
95
-
96
-```bash
97
-$ sudo install -d -m 0700 <RESTIC_REPO_DIR>
98
-$ sudo install -d -m 0700 $(dirname <RESTIC_PW_FILE>)
99
-$ sudo sh -c 'umask 077; printf "%s\n" "<CHOOSE_A_STRONG_PASSWORD>" > <RESTIC_PW_FILE>'
100
-```
101
-
102
-初回のみ `init`:
103
-```bash
104
-$ sudo docker run --rm \
105
- -v <RESTIC_REPO_DIR>:/repo \
106
- -v "$(dirname <RESTIC_PW_FILE>)":/pw:ro \
107
- -e RESTIC_REPOSITORY=/repo \
108
- -e RESTIC_PASSWORD_FILE=/pw/$(basename <RESTIC_PW_FILE>) \
109
- restic/restic:latest init
110
-```
111
-
112
----
113
-
114
-### 3.2 バックアップ対象ボリューム(実名)を確認(重要)
115
-Composeの named volume は、環境により「プロジェクト名付き」になることがあります。
116
-
117
-```bash
118
-$ cd <COMPOSE_DIR>
119
-$ cid=$(sudo docker compose ps -q minecraft)
120
-$ sudo docker inspect "$cid" --format '{{range .Mounts}}{{println .Name "->" .Destination}}{{end}}'
121
-```
122
-
123
-出力例:
124
-- `<VOLUME_NAME> -> /data`
125
-
126
-この `<VOLUME_NAME>` を次のスクリプトに設定します。
127
-
128
----
129
-
130
-### 3.3 バックアップスクリプト
131
-`/usr/local/sbin/minecraft-restic-backup.sh`
132
-
133
-```bash
134
-#!/usr/bin/env bash
135
-set -euo pipefail
136
-
137
-COMPOSE_DIR="<COMPOSE_DIR>"
138
-SERVICE_NAME="minecraft"
139
-
140
-VOLUME_NAME="<VOLUME_NAME>"
141
-
142
-RESTIC_REPOSITORY="<RESTIC_REPO_DIR>"
143
-RESTIC_PASSWORD_FILE="<RESTIC_PW_FILE>"
144
-RESTIC_IMAGE="restic/restic:latest"
145
-TAG="minecraft"
146
-
147
-cd "$COMPOSE_DIR"
148
-
149
-# Minecraftに対して無停止で整合性を取る
150
-sudo docker compose exec -T "$SERVICE_NAME" rcon-cli save-off || true
151
-sudo docker compose exec -T "$SERVICE_NAME" rcon-cli save-all flush || true
152
-
153
-# バックアップ(volumeをread-onlyでマウント)
154
-sudo docker run --rm \
155
- -v "${VOLUME_NAME}:/data:ro" \
156
- -v "${RESTIC_REPOSITORY}:/repo" \
157
- -v "$(dirname "$RESTIC_PASSWORD_FILE"):/pw:ro" \
158
- -e RESTIC_REPOSITORY="/repo" \
159
- -e RESTIC_PASSWORD_FILE="/pw/$(basename "$RESTIC_PASSWORD_FILE")" \
160
- "$RESTIC_IMAGE" backup /data --tag "$TAG" --host "$TAG"
161
-
162
-# 保持:直近30日だけ残す(古いスナップショットを削除しprune)
163
-sudo docker run --rm \
164
- -v "${RESTIC_REPOSITORY}:/repo" \
165
- -v "$(dirname "$RESTIC_PASSWORD_FILE"):/pw:ro" \
166
- -e RESTIC_REPOSITORY="/repo" \
167
- -e RESTIC_PASSWORD_FILE="/pw/$(basename "$RESTIC_PASSWORD_FILE")" \
168
- "$RESTIC_IMAGE" forget --tag "$TAG" --keep-within 30d --prune
169
-
170
-# 書き込み再開
171
-sudo docker compose exec -T "$SERVICE_NAME" rcon-cli save-on || true
172
-```
173
-
174
-実行権限:
175
-```bash
176
-$ sudo chmod +x /usr/local/sbin/minecraft-restic-backup.sh
177
-```
178
-
179
----
180
-
181
-## 4. systemd timer(1時間おきで自動実行)
182
-
183
-### 4.1 systemd service
184
-`/etc/systemd/system/minecraft-restic-backup.service`
185
-
186
-```ini
187
-[Unit]
188
-Description=Minecraft restic backup (hourly, online)
189
-Wants=network-online.target
190
-After=network-online.target docker.service
191
-Requires=docker.service
192
-
193
-[Service]
194
-Type=oneshot
195
-ExecStart=/usr/local/sbin/minecraft-restic-backup.sh
196
-```
197
-
198
-### 4.2 systemd timer
199
-`/etc/systemd/system/minecraft-restic-backup.timer`
200
-
201
-```ini
202
-[Unit]
203
-Description=Run Minecraft restic backup every hour
204
-
205
-[Timer]
206
-OnCalendar=hourly
207
-Persistent=true
208
-RandomizedDelaySec=5m
209
-
210
-[Install]
211
-WantedBy=timers.target
212
-```
213
-
214
-有効化:
215
-```bash
216
-$ sudo systemctl daemon-reload
217
-$ sudo systemctl enable --now minecraft-restic-backup.timer
218
-```
219
-
220
-動作確認:
221
-```bash
222
-$ systemctl list-timers --all | grep minecraft-restic
223
-$ sudo systemctl start minecraft-restic-backup.service
224
-$ journalctl -u minecraft-restic-backup.service -f
225
-```
226
-
227
----
228
-
229
-## 5. トラブルシュート
230
-
231
-### 5.1 バックアップが小さすぎる(`0 files`)/ 0B になる
232
-`/data` に実データが見えていない(ボリューム名違い)の可能性が高いです。
233
-
234
-```bash
235
-$ sudo docker compose exec -T minecraft ls -lah /data
236
-$ cid=$(sudo docker compose ps -q minecraft)
237
-$ sudo docker inspect "$cid" --format '{{range .Mounts}}{{println .Type .Name .Source "->" .Destination}}{{end}}'
238
-```
239
-
240
-`/data` に `world/` や `server.properties` が無い場合は、`<VOLUME_NAME>` の見直しを行います。