深夜の出来事:なぜコンテナの手動更新をやめたのか
午前2時、Telegramボットがサーバーのダウンを知らせました。慌てて起きて確認すると、午後に軽い気持ちで podman pull したNginxイメージの設定にミスがあり、サーバー再起動後にコンテナが起動できなくなっていました。手動でpullコマンドを打ち続ける運用は、いつか必ず限界が来ます。
Fedoraを開発機として2年使って気づいたのは、Watchtowerのようなサードパーティ製ツールをわざわざ導入する必要はないということです。FedoraとPodmanには、systemdに直接統合されたAuto-update機能が標準で備わっています。このソリューションは、Watchtowerを動かすのに比べてRAMを20〜50MBほど節約できます。何より重要なのは、新しい更新に問題があった場合に即座に旧バージョンへロールバックできる点です。
クイックスタート:5分でAuto-updateを設定する
Podmanが更新が必要なコンテナを認識できるようにするには、作成時に label を付与するだけです。以下の手順に従ってください。
ステップ1:識別用ラベルを付けてコンテナを実行する
注意:Podmanがダイジェストを正確にチェックできるように、レジストリを含む完全なイメージ名を使用することが必須です。
podman run -d --name my-web-app \
--label "io.containers.autoupdate=image" \
docker.io/library/nginx:latest
ラベル io.containers.autoupdate=image は「フラグ」のような役割を果たします。これにより、Podmanに対してDocker Hub上の新しいバージョンを定期的に確認するよう指示します。
ステップ2:コンテナ管理用のsystemdファイルを作成する
Podmanはデーモンレス(daemonless)モデルで動作するため、ライフサイクル管理にはsystemdが必要です。次のコマンドでsystemdファイルを作成します。
mkdir -p ~/.config/systemd/user/
cd ~/.config/systemd/user/
podman generate systemd --name my-web-app --files --new
パラメータ --new は必須です。これにより、Podmanは古いコンテナを再利用しようとするのではなく、ダウンロードしたばかりの新しいイメージからコンテナを新規作成できるようになります。
ステップ3:サービスとタイマーを有効化する
それでは、systemdの設定をリロードしてサービスを有効化しましょう。
systemctl --user daemon-reload
systemctl --user enable --now container-my-web-app.service
準備が整ったか確認するために、シミュレーションコマンドを実行できます。
podman auto-update --dry-run --format "{{.Image}} {{.Updated}}"
動作の仕組み:コピペで終わらせず、理解を深める
podman auto-update コマンドが実行されると、システムは以下の4つのステップを実行します。
io.containers.autoupdateラベルを持つ実行中のコンテナをスキャンします。- レジストリ(Docker Hub, Quay.ioなど)にリクエストを送り、イメージのハッシュ値(digest)を取得します。
- ダイジェストを比較します。レジストリ上のものが新しい場合、Podmanはイメージをプルします。
- systemdサービスを再起動し、プルした新しいイメージからコンテナを起動します。
Fedoraのデフォルトでは、podman-auto-update.timer というタイマーが毎日00:00に実行されます。実行スケジュールは以下のコマンドで確認できます。
systemctl --user status podman-auto-update.timer
ロールバックの極意:安眠のための保険
Podmanの最大の魅力は自己修復能力にあります。新しくプルしたイメージが「Running」状態であっても、実際には内部のサービスがエラーを吐いていることがよくあります。Podmanはこれをヘルスチェック(Health Check)で解決します。
ヘルスチェックを設定しておくと、Podmanは古いイメージを予備として保持します。新しいコンテナがヘルスチェックに合格しなかった場合、自動的に旧バージョンにロールバックします。
podman run -d --name secure-app \
--label "io.containers.autoupdate=image" \
--health-cmd="curl http://localhost/ || exit 1" \
--health-interval=5s \
--health-retries=3 \
--health-on-failure=rollback \
docker.io/library/nginx:latest
--health-on-failure=rollback フラグがあれば、安心して眠りにつけます。アップデートに失敗しても、システムが自動的に「一歩下がって」Webサイトの稼働を維持してくれます。
管理とデバッグ
システムが何を行ったかを確認するには、systemdのログをチェックします。
journalctl --user -u podman-auto-update.service
注意:SSHからログアウトすると、ユーザーサービスが停止することがあります。「linger」モードを有効にして、コンテナがバックグラウンドで走り続けるようにしましょう。
sudo loginctl enable-linger $USER
実践的なアドバイス:陥りやすい失敗
これまでの失敗から学んだ、自動更新を利用する際の3つの教訓を紹介します。
- データベースには絶対に :latest タグを使わない: Postgresが勝手に13から16に上がり、データ構造が壊れてしまうような事態は避けたいはずです。
:13のように具体的なタグを使用しましょう。 - ゴミイメージの処理: 更新のたびに古いイメージ(dangling image)が残ります。週に一度
podman image prune -fを実行するcronジョブを追加して、ストレージを掃除しましょう。 - プライベートレジストリ: ログイン済みであること、そして
auth.jsonファイルが正しい場所にあり、ログインしていない状態でもsystemdがアクセスできる権限を持っていることを確認してください。
この方法は、毎日手動でpullコマンドを打つのよりもプロフェッショナルで、SysAdminらしいやり方です。セットアップの成功を祈っています!

