はじめに
これまでRaspberry Pi上でDockerを使い、Flask、Redis、Uptime Kuma、Caddyなどを組み合わせながらDocker環境を構築してきました。
前回はCPU・Memory制限、Log Rotation、Docker Networkの分離など、Containerをより安全に運用するための設定を試しました。
今回はDocker編の最終回として、
更新できる・戻せる・壊れても復旧できるDocker環境
を目指します。
具体的には、次の内容を実際に試します。
- Docker Imageの更新
- Image Versionの固定
- Containerの再作成
- RedisのVersion変更
- Rollback
- Healthcheckの改善
- Gitによる構成管理
- GitHubへの構成の退避
- Redis / Uptime Kuma / CaddyのBackup
- 別VolumeへのRestoreテスト
- SDカードが壊れた場合の復旧方法
今回特に重要だったのは、
Imageを戻すことと、データを戻すことは別
そして、
Backupは作っただけでは不十分。Restoreできることを確認して初めて復旧に使える
という点でした。
1. 現在のDocker環境
現在のRaspberry Piでは、大きく3つのDocker Compose Projectを動かしています。
docker-lab
├── Flask
└── Redis
uptime-kuma
└── Uptime Kuma
caddy
└── Caddy
通信経路は概ね次のようになっています。
Windows PC
│
│ HTTPS
▼
Caddy
│
├── HTTP ──→ Flask
│
└── HTTP ──→ Uptime Kuma
Flask
│
└── Redis
CaddyだけがHostの80/443番Portを公開しています。
Flask、Redis、Uptime KumaはDocker Network内部で通信します。
2. まず現在のImageを確認する
更新する前に、現在どのImageを使っているのか確認しました。
cd ~/docker-lab
sudo docker compose images
さらにContainerが実際に参照しているImageを確認します。
sudo docker inspect \
-f '{{.Name}} Image={{.Config.Image}} ImageID={{.Image}}' \
docker-lab-web-1 docker-lab-redis-1
Redisは当初、
image: redis:latest
としていました。
latestは便利ですが、
「次に取得したときも同じVersionになる」
とは限りません。
長期運用する環境では、Versionを明示した方が更新内容を把握しやすくなります。
3. docker compose pullを試す
Redisの最新Imageを取得してみます。
sudo docker compose pull redis
今回はすでに最新Imageを持っていたため、Image IDは変わりませんでした。
ここで分かったのは、
pullしたからといって、必ず新しいImageになるわけではない
ということです。
Registry側のImageとLocalのImageが同じなら、当然更新は発生しません。
4. RedisのVersionを固定する
現在動いているRedisのVersionを確認しました。
sudo docker compose exec redis redis-server --version
今回は、
Redis server v=8.10.1
でした。
そこで、
sudo docker pull redis:8.10.1
としてVersion指定のImageを取得しました。
確認すると、現在のlatestと8.10.1は同じImage IDでした。
そこでcompose.yamlを、
redis:
image: redis:8.10.1
へ変更しました。
これで、
redis:latest
ではなく、
redis:8.10.1
を使うことが明示されます。
5. あえてRedisを8.10.0へ変更する
Rollbackを体験するため、一つ前のVersionも取得しました。
sudo docker pull redis:8.10.0
そしてcompose.yamlを一時的に、
redis:
image: redis:8.10.0
へ変更しました。
Redisだけ再作成します。
sudo docker compose up -d redis
Versionを確認します。
sudo docker compose exec redis redis-server --version
結果は、
Redis server v=8.10.0
となりました。
さらに、
sudo docker compose ps
でRedisとFlaskのHealthcheckを確認しました。
どちらもhealthyになり、ブラウザからFlaskへも正常にアクセスできました。
6. Containerを変えてもVolumeのデータは残る
Redis Containerは8.10.1から8.10.0へ作り直されました。
しかしFlaskのアクセスカウンターは残っていました。
これはRedisのデータをNamed Volumeへ保存しているためです。
redis:
volumes:
- redis-data:/data
つまり、
Redis 8.10.1 Container
│
▼
Redis Volume
│
▼
Redis 8.10.0 Container
とContainerを変更しても、同じVolumeを使えばデータを引き継げます。
改めて、
Containerと永続データは別物
ということを確認できました。
7. Redisを8.10.1へRollbackする
次にcompose.yamlを、
redis:
image: redis:8.10.1
へ戻します。
そして、
sudo docker compose up -d redis
を実行しました。
確認すると、
Redis server v=8.10.1
へ戻り、RedisとFlaskもhealthyになりました。
これでImage VersionのRollbackを体験できました。
8. Rollback後、カウンターが少し戻った
ここで興味深い現象が起きました。
Rollback後にFlaskのカウンターを見ると、直前より少し小さい値になっていました。
Volumeは削除していません。
そこでRedisの永続化状態を確認しました。
sudo docker compose exec redis sh -c \
'redis-cli -a "$(cat /run/secrets/redis_password)" INFO persistence'
確認すると、
aof_enabled:0
となっていました。
今回のRedisはAOFではなくRDB Snapshotを利用しています。
つまり、
Memory上の最新データ
│
│ SAVEなど
▼
dump.rdb
という関係があります。
Volumeが残っていても、Container再作成直前のMemory上の変更がすべてdump.rdbへ書き込まれているとは限りません。
そのため、
Volumeがある = 最新の1件まで絶対に失わない
とは限りません。
これはDatabaseの永続化方式によって変わります。
9. Image RollbackとData Rollbackは別
ここで非常に重要な違いがあります。
今回行ったのは、
Redis 8.10.0
↓
Redis 8.10.1
というImageのRollbackです。
しかしRedis Volumeのデータ自体を過去へ戻したわけではありません。
つまり、
Image Rollback
→ 実行するProgramを戻す
Data Rollback
→ Databaseの内容をBackup時点へ戻す
は別の操作です。
さらにDatabaseによってはVersion Updateに伴ってData FormatやSchemaが変更される可能性があります。
その場合、
古いImageへ戻せば必ず元に戻る
とは限りません。
DatabaseをUpdateする場合は、事前Backupが重要だと分かりました。
10. SAVEでRDBへ書き込む
Redisへ明示的にRDB保存を実行しました。
sudo docker compose exec redis sh -c \
'redis-cli -a "$(cat /run/secrets/redis_password)" SAVE'
結果は、
OK
です。
そして、
sudo docker compose exec redis sh -c \
'redis-cli -a "$(cat /run/secrets/redis_password)" INFO persistence | grep rdb_changes_since_last_save'
を確認します。
ところが、別の問題が見つかりました。
11. Healthcheckがカウンターを増やしていた
Flaskでは/へアクセスするとRedisのhitsを増やしています。
@app.route("/")
def index():
count = r.incr("hits")
一方、当初DockerのHealthcheckでも、
http://localhost:5000/
へアクセスしていました。
つまり、
Docker Healthcheck
↓
GET /
↓
Redis INCR hits
↓
カウンターが増える
という状態でした。
HealthcheckそのものがApplicationの状態を変更していたわけです。
これは良くありません。
12. 副作用のない/healthを作る
そこでFlaskへHealthcheck専用Endpointを追加しました。
@app.route("/health")
def health():
r.ping()
return "OK", 200
このEndpointではカウンターを増やしません。
RedisへPINGすることで、
- Flaskが動いている
- Redisへ接続できる
ことだけを確認します。
Docker Compose側も、
healthcheck:
test:
- CMD
- python
- -c
- "import urllib.request; urllib.request.urlopen('http://localhost:5000/health')"
interval: 30s
timeout: 5s
retries: 3
start_period: 10s
へ変更しました。
再Buildします。
sudo docker compose up -d --build web
13. Uptime Kumaにも同じ問題があった
Docker Healthcheckを直したあとも、カウンターが少しずつ増えることに気付きました。
原因はUptime Kumaでした。
Uptime KumaのMonitor URLが、
http://web:5000/
になっていたためです。
Uptime Kumaも定期的に/へアクセスするため、そのたびにカウンターが増えていました。
そこでMonitor URLを、
http://web:5000/health
へ変更しました。
これで、
Docker Healthcheck
│
├──→ /health
│
Uptime Kuma
│
└──→ /health
となり、監視によってApplicationのカウンターが変化しなくなりました。
ここから、
Healthcheckや監視Endpointは副作用を持たせない
ことの重要性を学びました。
14. Uptime Kumaの内部監視はHTTPでよいのか
Uptime KumaからFlaskへの監視は、
http://web:5000/health
としています。
外部からFlaskへアクセスするときは、
Windows
│
│ HTTPS
▼
Caddy
│
│ HTTP
▼
Flask
です。
一方、Uptime KumaはDocker Network内からFlaskへ直接アクセスしています。
Uptime Kuma
│
│ HTTP
▼
web:5000/health
今回の自宅Docker環境では、Docker Network内部までHTTPS化するより、Caddyを外部HTTPS入口として利用する構成にしています。
15. 構成をGitで管理する
次は「SDカードが壊れたらどうするか」を考えました。
Docker Imageは再取得できます。
しかし、
Dockerfile
compose.yaml
app.py
requirements.txt
などを失うと、同じ環境を作るのが難しくなります。
そこでGitで構成を管理します。
まずdocker-labで、
cd ~/docker-lab
git init
git status
を実行しました。
Git管理対象は、
.dockerignore
.env.example
.gitignore
Dockerfile
app.py
compose.yaml
requirements.txt
です。
16. SecretをGitへ入れない
.gitignoreには、
.env
redis_password.txt
を登録しています。
そのため、
git add .
git status
としても、
.env
redis_password.txt
はStageされませんでした。
これは非常に重要です。
Git管理する
├── Dockerfile
├── compose.yaml
├── app.py
├── requirements.txt
└── .env.example
Git管理しない
├── .env
└── redis_password.txt
.env.exampleには設定例を置き、実際の値は.envへ置く、という分離ができます。
なお、.gitignoreは「すでにGitで追跡済みのSecretを履歴から消す仕組み」ではありません。
Secretを一度Commitしてしまった場合は、単に.gitignoreへ追加するだけでは不十分です。
17. 最初のCommitを作る
GitのUser NameとEmailを設定したあと、
git add .
git commit -m "Initial Docker lab configuration"
としました。
確認します。
git log --oneline
今回は、
e3715b6 Initial Docker lab configuration
という最初のCommitが作成されました。
ただし、この時点ではGit Repositoryも同じSDカード上です。
Raspberry Pi
└── SDカード
├── Docker環境
└── Git Repository
これではSDカードが壊れたらGit履歴も失います。
18. GitHubへpushする
そこでGitHubにPrivate Repositoryを作成しました。
Raspberry PiではSSH Keyを作成します。
ssh-keygen -t ed25519 -C "github-docker-pi"
作成されるのは、
~/.ssh/id_ed25519
~/.ssh/id_ed25519.pub
です。
id_ed25519は秘密鍵なので外部へ公開してはいけません。
GitHubへ登録するのは、
id_ed25519.pub
の公開鍵だけです。
SSH認証を確認しました。
ssh -T git@github.com
認証成功後、Remote Repositoryを登録します。
git remote add origin git@github.com:<GitHubユーザー名>/docker-lab.git
確認します。
git remote -v
そして、
git push -u origin master
でGitHubへpushしました。
最後に、
git status
を確認すると、
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean
となりました。
これで構成ファイルはPiとGitHubの両方に存在します。
19. CaddyとUptime Kumaの構成もGitHubへ保存する
docker-labだけでは自宅Docker環境全体を復旧できません。
そこで、
~/caddy
~/uptime-kuma
についてもGit Repositoryを作成しました。
Caddyでは、
Caddyfile
compose.yaml
をGit管理します。
今回ホスト側へコピーしていたroot.crtは生成物としてGit管理から除外しました。
Uptime Kumaでは、
compose.yaml
をGit管理しました。
最終的にGitHubには、
GitHub
├── docker-lab
├── caddy
└── uptime-kuma
という3つのPrivate Repositoryを用意しました。
20. GitはData Backupではない
ここで重要なのが、
GitHubへpushしたからBackupは完成
ではないことです。
GitHubにあるのは主に「構成」です。
GitHub
├── Dockerfile
├── compose.yaml
├── app.py
├── requirements.txt
└── Caddyfile
しかし、
Redisの実データ
Uptime KumaのMonitor設定
Caddyの内部CA
.env
redis_password.txt
などはGitHubにはありません。
そこで、
構成
→ Git / GitHub
永続データ
→ Backup
Secret
→ Gitとは別に安全に保管
と役割を分けます。
21. RedisをBackupする
まずRedisへSAVEを実行します。
cd ~/docker-lab
sudo docker compose exec redis sh -c \
'redis-cli -a "$(cat /run/secrets/redis_password)" SAVE'
結果は、
OK
でした。
次にContainerからdump.rdbをコピーします。
mkdir -p ~/docker-backup
sudo docker compose cp \
redis:/data/dump.rdb \
~/docker-backup/dump.rdb
確認します。
ls -lh ~/docker-backup/dump.rdb
ただし、
~/docker-backup
も同じSDカード上です。
これではSDカード故障には耐えられません。
そこでWindows PCへscpでコピーしました。
scp pi@<Raspberry PiのIP>:/home/pi/docker-backup/dump.rdb `
"$env:USERPROFILE\docker-backup\dump.rdb"
これでRedisのDataをPiの外へ退避できました。
22. SecretもPiの外へ退避する
.envとredis_password.txtはGitHubへ入れません。
しかし、SDカード故障時には必要です。
そこで学習環境ではWindows PCへ別途退避しました。
mkdir "$env:USERPROFILE\docker-backup\secrets"
scp pi@<Raspberry PiのIP>:/home/pi/docker-lab/.env `
"$env:USERPROFILE\docker-backup\secrets\.env"
scp pi@<Raspberry PiのIP>:/home/pi/docker-lab/redis_password.txt `
"$env:USERPROFILE\docker-backup\secrets\redis_password.txt"
実運用では、平文Passwordを単純に置くだけではなく、
- Password Manager
- Secret Manager
- 暗号化Backup
なども検討する必要があります。
23. Uptime KumaのVolumeを見る
Docker Volume一覧を確認しました。
sudo docker volume ls
Uptime Kumaでは、
uptime-kuma_uptime-kuma-data
というVolumeを使用しています。
一時的なBusyBox ContainerへRead Onlyでmountして中を確認しました。
sudo docker run --rm \
-v uptime-kuma_uptime-kuma-data:/backup:ro \
busybox \
ls -lah /backup
中には、
kuma.db
kuma.db-shm
kuma.db-wal
docker-tls/
screenshots/
upload/
などがありました。
つまりcompose.yamlだけではMonitor設定などは復旧できません。
24. Uptime Kumaを停止してBackupする
Uptime KumaではSQLiteが使われています。
稼働中のDatabaseファイルをそのままコピーするより、今回はContainerを停止してからVolume全体をBackupしました。
cd ~/uptime-kuma
sudo docker compose stop
そして、
sudo docker run --rm \
-v uptime-kuma_uptime-kuma-data:/source:ro \
-v ~/docker-backup:/backup \
busybox \
tar czf /backup/uptime-kuma-data.tar.gz -C /source .
Backup後、Uptime Kumaを戻します。
sudo docker compose up -d
sudo docker compose ps
ブラウザからMonitor設定が残っていることも確認しました。
その後uptime-kuma-data.tar.gzをWindows PCへscpで退避しました。
25. CaddyのVolumeには秘密鍵がある
CaddyのVolumeも確認しました。
sudo docker run --rm \
-v caddy_caddy-data:/source:ro \
busybox \
find /source -maxdepth 5 -type f
中には、
root.crt
root.key
intermediate.crt
intermediate.key
flask.home.arpa.crt
flask.home.arpa.key
kuma.home.arpa.crt
kuma.home.arpa.key
などがありました。
特に、
root.key
は内部CAの秘密鍵です。
これは絶対に公開してはいけません。
26. CaddyのPKIをBackupする
Caddyを停止します。
cd ~/caddy
sudo docker compose stop
Volume全体をBackupしました。
sudo docker run --rm \
-v caddy_caddy-data:/source:ro \
-v ~/docker-backup:/backup \
busybox \
tar czf /backup/caddy-data.tar.gz -C /source .
その後Caddyを起動します。
sudo docker compose up -d
ブラウザから、
https://flask.home.arpa/
https://kuma.home.arpa/
へアクセスし、証明書警告なしで正常に戻ったことを確認しました。
caddy-data.tar.gzもWindows PCへ退避しました。
27. CaddyのBackupが重要な理由
Caddyのcaddy-dataを失っても、新しいCaddyは新しい内部CAを生成できます。
しかし、
古いCaddy
↓
CA A
↓
WindowsがCA Aを信頼
という状態からCaddyを完全に作り直すと、
新しいCaddy
↓
CA B
となります。
WindowsはCA Bをまだ信頼していないため、新しいroot.crtをWindowsへ再登録する必要があります。
一方、caddy-dataを安全に復元できれば、同じ内部CAを継続できます。
ただし、
caddy-data.tar.gzはCA秘密鍵を含む非常に重要なSecret
です。
GitHubなどへ公開してはいけません。
28. BackupはRestoreできて初めて意味がある
ここまででBackupファイルは作成できました。
しかし、
Backupファイルが存在する
ことと、
そのBackupから本当に復旧できる
ことは別です。
そこで、本番Volumeを壊さずに一時VolumeへRestoreするテストを行いました。
29. Uptime Kumaを一時VolumeへRestoreする
テスト用Volumeを作ります。
sudo docker volume create uptime-kuma-restore-test
Backupを展開します。
sudo docker run --rm \
-v uptime-kuma-restore-test:/restore \
-v ~/docker-backup:/backup:ro \
busybox \
tar xzf /backup/uptime-kuma-data.tar.gz -C /restore
確認します。
sudo docker run --rm \
-v uptime-kuma-restore-test:/restore:ro \
busybox \
ls -lah /restore
結果として、
kuma.db
docker-tls/
screenshots/
upload/
などをRestoreできました。
テスト終了後は、
sudo docker volume rm uptime-kuma-restore-test
で削除しました。
本番Volumeには一切触れていません。
30. Caddyも一時VolumeへRestoreする
同じようにCaddyもテストしました。
sudo docker volume create caddy-restore-test
Backupを展開します。
sudo docker run --rm \
-v caddy-restore-test:/restore \
-v ~/docker-backup:/backup:ro \
busybox \
tar xzf /backup/caddy-data.tar.gz -C /restore
秘密鍵の中身は表示せず、ファイル名だけ確認します。
sudo docker run --rm \
-v caddy-restore-test:/restore:ro \
busybox \
find /restore -maxdepth 5 -type f
その結果、
/restore/caddy/pki/authorities/local/root.key
/restore/caddy/pki/authorities/local/root.crt
/restore/caddy/pki/authorities/local/intermediate.key
/restore/caddy/pki/authorities/local/intermediate.crt
などを確認できました。
つまり内部CAを含むCaddyのDataを、新しいVolumeへRestoreできることが確認できました。
テスト後はVolumeを削除しました。
sudo docker volume rm caddy-restore-test
31. Redisは実際に起動してRestoreを確認する
Redisではさらに一歩進めて、RestoreしたVolumeから実際にRedisを起動しました。
まずテスト用Volumeを作ります。
sudo docker volume create redis-restore-test
dump.rdbをコピーします。
sudo docker run --rm \
-v redis-restore-test:/data \
-v ~/docker-backup:/backup:ro \
busybox \
cp /backup/dump.rdb /data/dump.rdb
そして、このVolumeを使ってRedisを起動します。
sudo docker run -d \
--name redis-restore-test-container \
-v redis-restore-test:/data \
redis:8.10.1
Backupしたhitsを取得します。
sudo docker exec redis-restore-test-container redis-cli GET hits
結果は、
4678
でした。
つまり、
dump.rdb
↓
新しいVolume
↓
新しいRedis Container
↓
RedisがRDBを読み込む
↓
hits = 4678
まで確認できました。
これは単にファイルをコピーできたという確認ではなく、
新しいRedis ContainerがBackup Dataを実際に読み込めた
というRestoreテストです。
テスト後は、
sudo docker rm -f redis-restore-test-container
sudo docker volume rm redis-restore-test
で片付けました。
32. 最終的なBackup構成
今回、Piの外には次のような復旧材料を用意しました。
GitHub
├── docker-lab
│ └── Flask / Redisの構成
├── caddy
│ └── Caddyの構成
└── uptime-kuma
└── Uptime Kumaの構成
Windows PC側には、
docker-backup
├── dump.rdb
├── uptime-kuma-data.tar.gz
├── caddy-data.tar.gz
└── secrets
├── .env
└── redis_password.txt
を保存しました。
役割で分類すると、
| 種類 | 保存先 | 例 |
|---|---|---|
| Code / 構成 | GitHub | Dockerfile、compose.yaml、app.py |
| Redis Data | Backup | dump.rdb |
| Uptime Kuma Data | Backup | uptime-kuma-data.tar.gz |
| Caddy PKI | 機密Backup | caddy-data.tar.gz |
| 環境設定 | Git以外 | .env |
| Secret | Git以外 | redis_password.txt |
33. SDカードが完全に壊れたらどうするか
ここまでの内容を使えば、SDカードが完全に壊れた場合の復旧手順を考えられます。
新しいSDカード
↓
Raspberry Pi OSをInstall
↓
DockerをInstall
↓
GitHubからRepositoryをclone
↓
.env / Secretを戻す
↓
Docker Volumeを作る
↓
Backup DataをVolumeへRestore
↓
docker compose up -d
↓
Healthcheck確認
↓
ブラウザから動作確認
GitHubから構成を取得する例は、
git clone git@github.com:<GitHubユーザー名>/docker-lab.git
git clone git@github.com:<GitHubユーザー名>/caddy.git
git clone git@github.com:<GitHubユーザー名>/uptime-kuma.git
です。
ただし、新しいRaspberry PiではGitHub用SSH Keyの再設定なども必要になります。
34. Docker ImageそのものはBackupしていない
今回、Redis ImageやCaddy ImageそのものはBackupしていません。
例えばRedisは、
image: redis:8.10.1
としているため、Registryから再取得できます。
docker pull redis:8.10.1
Flask Imageについても、
Dockerfile
requirements.txt
app.py
がGitHubにあるため、再Buildできます。
docker compose build
つまり、
Image
→ 再取得 / 再Build
構成
→ GitHub
永続データ
→ Backup
Secret
→ 別管理
という役割分担になります。
35. VolumeはBackupではない
これまでの記事では、
Containerを削除してもVolumeは残る
ことを確認してきました。
しかし今回さらに、
Volumeが残ることとBackupがあることは別
だと分かりました。
例えば、
Container削除
↓
Volumeは残る
のであればVolumeは役立ちます。
しかし、
SDカード故障
↓
Docker Volumeも消える
となれば意味がありません。
そのため、
Container
↓
Volume
↓
Pi外部のBackup
まで考える必要があります。
36. Gitも同じSDカード上だけではBackupにならない
Gitも同様です。
git init
git commit
しただけでは、
SDカード
├── Docker Data
└── .git
なので、SDカードが壊れれば両方失います。
GitHubへpushすることで、
Raspberry Pi
│
│ git push
▼
GitHub
となり、Piとは別の場所へ構成と履歴を保存できます。
この違いも今回実際に試したことで理解しやすくなりました。
37. 最後にContainerの状態を確認する
Restoreテスト用ContainerとVolumeを削除したあと、
sudo docker ps
を確認しました。
最終的に、
Flask healthy
Redis healthy
Uptime Kuma healthy
Caddy Up
となり、元の環境へ戻っていることを確認しました。
38. 今回学んだこと
今回特に重要だったポイントをまとめます。
Image Versionを固定する
image: redis:8.10.1
とすることで、どのVersionを使うか明確にできます。
Image RollbackとData Rollbackは違う
Image Rollback
→ Programを戻す
Data Rollback
→ Databaseを過去の状態へ戻す
です。
Database UpdateではData互換性も考える必要があります。
Volumeがあっても最新Dataが必ず保存されるとは限らない
RedisのRDB方式では、Memory上の最新変更とdump.rdbの内容に差が出る可能性があります。
永続化方式を理解する必要があります。
Healthcheckには副作用を持たせない
今回、
GET /
→ hitsをINCR
するEndpointをHealthcheckに使っていたため、監視するだけでDataが変化していました。
そこで、
/health
という専用Endpointを作りました。
Uptime Kumaも同じEndpointを見るように変更しました。
GitとBackupは役割が違う
Git
→ Code・構成・変更履歴
Backup
→ Database・Volume・Secretなど
です。
どちらか一方だけでは完全復旧できません。
SecretをGitへ入れない
.env
redis_password.txt
root.key
などのSecretはGitHubへ公開しないようにします。
特にCaddyのCA秘密鍵を含むBackupは慎重に扱う必要があります。
BackupはRestoreテストする
今回最も印象に残ったのはこれです。
Backup作成
↓
別VolumeへRestore
↓
内容を確認
↓
Redisでは実際にContainerを起動
↓
Dataを読み取れることを確認
単にBackupファイルが存在するだけでは、復旧できる保証にはなりません。
39. Dockerを学んで見えてきたこと
Dockerを使い始めた頃は、
docker run
でContainerが動くだけでも新鮮でした。
しかし実際に環境を作っていくと、
Image
Container
Network
Volume
Dockerfile
Docker Compose
Healthcheck
Reverse Proxy
HTTPS
Secret
Resource Limit
Log
Backup
Git
Rollback
Restore
と、運用に必要な要素がつながってきました。
特に今回、
Containerを消しても困らない
だけではなく、
Raspberry Pi自体が壊れても復旧できるようにする
ところまで考えることで、Dockerの役割がかなり明確になりました。
40. それでもまだ手作業が残っている
今回、復旧材料はかなり揃いました。
しかしSDカードが壊れた場合、まだ次の作業を人間が行う必要があります。
Raspberry Pi OSをInstall
DockerをInstall
GitをInstall / 設定
Repositoryをclone
Secretを配置
Volumeを作成
BackupをRestore
Docker Composeを起動
つまり、
Docker環境はコード化できたが、Serverそのものの構築はまだ手作業
です。
ここで次の疑問が出てきます。
このRaspberry Piの構築作業そのものもコード化できないのか?
これが**Infrastructure as Code(IaC)**につながります。
まとめ
今回はDocker環境のUpdate、Rollback、Backup、Restoreを実際に試しました。
最終的に、
GitHub
→ Docker環境の設計図
Docker Registry
→ 再取得可能なImage
Windows Backup
→ Redis / Uptime Kuma / CaddyのData
Secret Backup
→ .env / Password / CA関連Data
という形に分けました。
そして、
新しいServer
+
Git Repository
+
Secret
+
Data Backup
↓
Docker環境を再構築
という復旧の考え方が見えてきました。
Dockerで重要なのは、Containerを大切に保存することではなく、
Containerがなくなっても再作成できるようにすること
だと感じました。
さらに一歩進めると、
Serverそのものがなくなっても再構築できるようにする
という考え方になります。
次回からはDocker編を離れ、IaC編としてAnsibleなどを使い、
手作業でServerを構築する
↓
構築手順をCodeにする
↓
同じ環境を自動で再現する
ことに挑戦していきます。