Watchtowerを使ってDockerコンテナの更新を自動化する方法
Watchtowerは、新しいイメージがリリースされたときに、実行中のDockerコンテナを更新する方法の一般的な問題を解決します。Watchtowerは自動的にコンテナを「監視」し、定期的にそのイメージの新しいバージョンをポーリングし、再起動させて最新のリリースを実行させます。
この記事では、Watchtowerを使用してコンテナフリートの管理を簡素化する方法を示します。また、Watchtowerの動作をカスタマイズするために使用できる高度なオプションについても見ていきます。
ウォッチタワーの展開
最初のステップは、独自のDockerコンテナ内でWatchtowerインスタンスを開始することです。次のコマンドを実行してWatchtowerイメージをダウンロードし、コンテナを作成します:
docker run -d --name watchtower \
-v /var/run/docker.sock:/var/run/docker.sock \
containrrr/watchtower
ホストのDockerソケットがWatchtowerコンテナに-vフラグでマウントされています。これにより、WatchtowerはホストのDockerデーモンインスタンスと対話することができます。これが必要なのは、Watchtowerがコンテナを列挙し、起動できるようにするためです。
リモートDockerホストでWatchtowerを使用することは可能です。そのホストのDockerデーモンをTCPポートで公開し、ソケットバインドの代わりにDOCKER_HOST環境変数を使用してWatchtowerを起動してください:
docker run -d --name watchtower \
-e DOCKER_HOST="tcp://192.168.0.1:2375" \
containrrr/watchtower
DockerホストがTLSで保護されている場合は、Watchtowerの--tlsverifyフラグを使用し、証明書をコンテナの/etc/ssl/dockerディレクトリにマウントしてください:
docker run -d --name watchtower \
-e DOCKER_HOST="tcp://192.168.0.1:2375" \
-e DOCKER_CERT_PATH=/etc/ssl/docker
-v ./certs:/etc/ssl/docker
containrrr/watchtower --tlsverify
Watchtowerは、Dockerホストごとに1回実行されるように設計されています。新しいWatchtowerインスタンスが起動すると、既に存在する他のWatchtowerコンテナをクリーンアップします。各インスタンスにユニークなスコープを割り当てることで複数のインスタンスを実行できますが、ほとんどのデプロイメントでは通常必要ありません。
ウォッチタワーを使用する
あなたのWatchtowerコンテナは、すぐにDockerホスト上の他のコンテナの監視を開始します。24時間ごとにイメージの更新をポーリングし、変更があった場合にはコンテナを再起動します。
新しいコンテナは、元のコンテナと同じオプションを保持します。ポートバインド、ボリュームマウント、環境変数、およびその他の設定はすべて、置き換え時にそのまま保持されます。
Watchtowerは依存関係を把握しており、コンテナがリンクされている場合、Watchtowerは論理的な順序でそれらを停止し、再起動します。特定のコンテナに依存するサービスは、そのコンテナが更新される前に停止され、置き換えが利用可能になった後に再起動されます。これにより、アプリケーションが依存関係の更新中にエラーに遭遇することがありません。
Watchtowerは、更新のためにコンテナを停止させる必要があるときに、SIGTERM信号をコンテナに送ります。この信号を変更するには、コンテナにラベルを設定します。SIGTERMの代わりにSIGHUPに切り替える方法は次のとおりです:
docker run -d --label=com.centurylinklabs.watchtower.stop-signal=SIGHUP my-imageコンテナの除外と含むこと
Watchtowerのコマンド引数と個々のコンテナにDockerラベルを組み合わせることで、監視されるコンテナをカスタマイズできます。以下は、ラベルを使用してWatchtowerの更新から除外されたコンテナを起動する例です。
docker run -d --label=com.centurylinklabs.watchtower.enable=false my-image更新すべきコンテナをホワイトリストに登録することも可能で、更新しないものを除外することはありません。この動作を有効にするには、--label-enableフラグを付けてWatchtowerを起動してください:
docker run -d --name watchtower \
-v /var/run/docker.sock:/var/run/docker.sock \
containrrr/watchtower --label-enable
今、ラベルを使用して、いくつかのコンテナを更新を受け取る資格があると指定します:
docker run -d --label=com.centurylinklabs.watchtower.enable=true my-imageライフサイクルフック
Watchtowerは特定のイベントが発生したときに、オプションでコンテナ内でスクリプトを実行できます。利用可能なフックは4つあります:
プレチェック- ウォッチタワーがコンテナの更新が利用可能かどうかを確認する前に。更新前- 更新が見つかった後、コンテナが再起動される前。アップデート後- アップデートが完了した後。ポストチェック- コンテナの更新確認が完了した後。
フックはコンテナラベルを使用して構成されます。ラベルの値は、コンテナイメージ内の実行可能ファイルへのパスである必要があります。フックが発火するたびにこれが呼び出されます。
こちらが pre-update フックを使用する例です:
docker run -d --label=com.centurylinklabs.watchtower.lifecycle.pre-update="/backup.sh --create" my-image他のフックは、それぞれの名前をラベルに置き換えることで同様に設定されています。
通知と監視
Watchtowerは、コンテナの更新が利用可能になると、メール、Slack、Microsoft Teams、Gotify、Shoutrrrを通じて通知を送信できます。これらの配信メカニズムは、それぞれのWatchtowerコンテナ内の環境変数を設定することで個別に構成する必要があります。
ここにGmailを使用した基本的な例があります。
docker run -d --name watchtower \
-e WATCHTOWER_NOTIFICATIONS=email
-e WATCHTOWER_NOTIFICATION_EMAIL_FROM=you@gmail.com
-e WATCHTOWER_NOTIFICATION_EMAIL_TO=you@gmail.com
-e WATCHTOWER_NOTIFICATION_EMAIL_SERVER=smtp.gmail.com
-e WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PORT=587
-e WATCHTOWER_NOTIFICATION_EMAIL_SERVER_USER=you@gmail.com
-e WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD=your_gmail_app_password
-v /var/run/docker.sock:/var/run/docker.sock \
containrrr/watchtower
Watchtowerは、更新を適用せずにコンテナの更新をチェックする動作モードもサポートしています。これを使用して、更新が利用可能なときに通知を受け取り、その後、自分の都合の良い時にコンテナを再起動することができます。
--monitor-only フラグを使ってこのモードをアクティブにします:
docker run -d --name watchtower \
-v /var/run/docker.sock:/var/run/docker.sock \
containrrr/watchtower --monitor-only
個別のコンテナにモニタリングモードを選択するために設定できるラベルもあります。
docker run -d --label=com.centurylinklabs.watchtower.monitor-only=true my-image更新ポーリング間隔の変更
ウォッチタワーは24時間ごとに新しい画像をチェックします。この間隔は、--intervalフラグまたはWATCHTOWER_POLL_INTERVAL環境変数を使用して変更できます。秒単位の値を受け入れます。
Update every hour
docker run -d --name watchtower \
-e WATCHTOWER_POLL_INTERVAL=3600
-v /var/run/docker.sock:/var/run/docker.sock \
containrrr/watchtower
あるいは、cron構文を使用して固定のポーリングスケジュールを定義することもできます。これは、--scheduleフラグまたはWATCHTOWER_SCHEDULE環境変数として受け入れられます。
Update every five minutes
docker run -d --name watchtower \
-e WATCHTOWER_SCHEDULE="*/5 * * * *"
-v /var/run/docker.sock:/var/run/docker.sock \
containrrr/watchtower
古い画像を整理する
Watchtowerは、新しいコンテナイメージがプルされた後、ホスト上に古いバージョンのイメージを残します。--cleanupフラグまたはWATCHTOWER_CLEANUP環境変数を設定することで、アップデート後に古いイメージを削除します。これにより、時間が経つにつれてディスクスペースを大幅に空けることができます。
docker run -d --name watchtower \
-e WATCHTOWER_CLEANUP=true
-v /var/run/docker.sock:/var/run/docker.sock \
containrrr/watchtower
オンデマンドでのランニング
Watchtowerは、コンテナの更新を継続的に監視する長寿命のデーモンとして実行されるように設計されています。時には、新しいイメージを手動でオンデマンドで確認したい場合もあります。その場合は、--run-onceコマンドフラグを使用してこれを行うことができます:
docker run --rm \
-v /var/run/docker.sock:/var/run/docker.sock \
containrrr/watchtower --run-once
これにより、すべての実行中のコンテナに対して単一の更新試行が行われます。その後、Watchtowerコンテナは停止して削除されます。
プライベートレジストリの使用
Watchtowerは、プライベートレジストリにある画像の更新を確認するために認証情報が必要です。それを供給する方法の一つは、Dockerのconfig.jsonファイルをWatchtowerコンテナ内の/config.jsonにマウントすることです:
docker run -d --name watchtower \
-v $HOME:/.docker/config.json:/config.json
-v /var/run/docker.sock:/var/run/docker.sock \
containrrr/watchtower
このアプローチには一つの注意点があります:ホスト上のconfig.jsonへの更新は、必ずしもコンテナ内に反映されるわけではありません。docker loginのようなコマンドは、実際にはファイルを直接編集するのではなく、ファイルを置き換えます。これにより新しいinodeが作成され、Dockerバインドマウントが壊れます。
Watchtowerにレジストリの資格情報を提供する別の方法は、REPO_USERとREPO_PASS変数です。これにより、画像をプルする前に定義されたユーザーとしてログインします。
docker run -d --name watchtower \
-e REPO_USER=demo-user
-e REPO_PASS=users-password
-v /var/run/docker.sock:/var/run/docker.sock \
containrrr/watchtower
結論
Watchtowerは、新しいイメージがレジストリにプッシュされると、Dockerコンテナの更新を自動化することができます。これは、コンテナのブラックリストとホワイトリストをサポートし、cron構文による高度なスケジューリングや、複数の人気プロバイダーに送信される通知など、高度にカスタマイズ可能なシステムです。
オプションの構成パラメーターは、ロールバック再起動、再起動したコンテナや停止したコンテナの更新、更新作業を視覚化する別の方法を提供するメトリクスの公開のサポートなど、さらなる機能を公開します。これにより、Watchtowerは忙しいプロダクションのDockerコンテナの管理に適した選択肢となります。
