自動でDockerコンテナをアップデートする「watchtower」を試す
GitHubレポジトリ
Watchtower
Dockerコンテナのベースイメージ更新を自動化するプロセス。
Quick Start
watchtower を使うと、Docker Hub や 独自のイメージレジストリに新しいイメージをプッシュするだけで、コンテナ化されたアプリの実行中バージョンを更新できます。
Watchtower は新しいイメージをプルし、既存のコンテナを優雅にシャットダウンし、最初にデプロイした際と同じオプションで再起動します。以下のコマンドで watchtower コンテナを実行してください。
$ docker run --detach \ --name watchtower \ --volume /var/run/docker.sock:/var/run/docker.sock \ containrrr/watchtower
Watchtower はホームラボ、メディアセンター、ローカル開発環境などでの使用を想定しています。商用または本番環境での使用は推奨していません。その場合は Kubernetes の利用をご検討ください。Kubernetes が大きすぎると感じる場合は、MicroK8s や k3s のような、Kubernetes クラスター運用の手間を大幅に軽減するソリューションをご覧ください。
公式ドキュメント
事前準備(自作コンテナの作成)
なにはともあれ、まずFastAPIを使った自作APIサーバのDockerイメージを作ってDockerHubにpushする。
uvで仮想環境作成
uv init -p 3.12 hello-time && cd $_
パッケージ追加
uv add fastapi uvicorn[standard]
ファイルを用意
__version__ = "0.0.1"
from fastapi import FastAPI
import datetime
from version import __version__ as VERSION
app = FastAPI()
@app.get("/")
async def root():
now = datetime.datetime.now().isoformat()
return {
"message": "hello world",
"version": VERSION,
"time": now
}
FROM python:3.12-slim
COPY /uv /bin/uv
COPY . /app
WORKDIR /app
RUN uv sync --frozen --nocache
EXPOSE 8080
CMD ["/app/.venv/bin/uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8080"]
こんな感じになっているはず。
tree
.
├── Dockerfile
├── README.md
├── main.py
├── pyproject.toml
├── uv.lock
└── version.py
1 directory, 6 files
ビルド
docker build -t hello-time:0.0.1 .
軽く起動しておく
docker run -rm --name hello-time -p 8080:8080 hello-time:0.0.1
確認
curl -s http://localhost:8080| jq -r .
{
"message": "hello world",
"version": "0.0.1",
"time": "2025-07-07T11:33:30.207601"
}
ではこれをDockerHubにpush。latestタグも付けている。
docker tag hello-time:0.0.1 kun432/hello-time:0.0.1
docker tag hello-time:0.0.1 kun432/hello-time:latest
docker push kun432/hello-time:0.0.1
docker push kun432/hello-time:latest
pushされた
コンテナの起動とwatchtowerのインストール
これをpullして起動する。ややこしいので、ビルドした端末とは別のDockerサーバを使う。
docker run -d --name hello-time -p 8080:8080 kun432/hello-time:latest
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0b66c9c3b196 kun432/hello-time:0.0.1 "/app/.venv/bin/uvic…" 17 seconds ago Up 3 seconds 0.0.0.0:8080->8080/tcp, [::]:8080->8080/tcp hello-time
動作確認もOK
curl -s http://localhost:8080| jq -r .
{
"message": "hello world",
"version": "0.0.1",
"time": "2025-07-07T11:47:06.138905"
}
ではwatchtowerのコンテナを起動する。デフォルトだと24時間間隔でチェックするみたい。今回はテストとして1分に1回チェックするようにしてみる。
docker run -d \
--name watchtower \
-v /var/run/docker.sock:/var/run/docker.sock \
containrrr/watchtower --interval 60
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4318c4775813 containrrr/watchtower "/watchtower --inter…" 16 seconds ago Up 15 seconds (health: starting) 8080/tcp watchtower
3b35f9e8b545 kun432/hello-time:latest "/app/.venv/bin/uvic…" 6 minutes ago Up 5 minutes 0.0.0.0:8080->8080/tcp, [::]:8080->8080/tcp hello-time
ログを見てみると、1分に1回起動しているのがわかる。
docker logs -f watchtower
time="2025-07-07T12:33:08Z" level=info msg="Watchtower 1.7.1"
time="2025-07-07T12:33:08Z" level=info msg="Using no notifications"
time="2025-07-07T12:33:08Z" level=info msg="Checking all containers (except explicitly disabled with label)"
time="2025-07-07T12:33:08Z" level=info msg="Scheduling first run: 2025-07-07 12:34:08 +0000 UTC"
time="2025-07-07T12:33:08Z" level=info msg="Note that the first check will be performed in 59 seconds"
time="2025-07-07T12:34:11Z" level=info msg="Session done" Failed=0 Scanned=2 Updated=0 notify=no
time="2025-07-07T12:35:11Z" level=info msg="Session done" Failed=0 Scanned=2 Updated=0 notify=no
コンテナのバージョンアップ
自作のコンテナをバージョンアップする。
ファイルを修正
__version__ = "0.0.2"
0.0.2
としてビルド
docker build -t hello-time:0.0.2 .
DockerHubにpush
docker tag hello-time:0.0.2 kun432/hello-time:0.0.2
docker tag hello-time:0.0.2 kun432/hello-time:latest
docker push kun432/hello-time:0.0.2
docker push kun432/hello-time:latest
で、定期的にdocker ps
を見ていると・・・
これはまだ何も起きていない
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4318c4775813 containrrr/watchtower "/watchtower --inter…" 4 minutes ago Up 4 minutes (healthy) 8080/tcp watchtower
3b35f9e8b545 d7d344783013 "/app/.venv/bin/uvic…" 10 minutes ago Up 9 minutes 0.0.0.0:8080->8080/tcp, [::]:8080->8080/tcp hello-time
hello-timeのコンテナがいなくなった!
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4318c4775813 containrrr/watchtower "/watchtower --inter…" 4 minutes ago Up 4 minutes (healthy) 8080/tcp watchtower
新しいコンテナが立ち上がっている
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3607c4790eed kun432/hello-time:latest "/app/.venv/bin/uvic…" 4 seconds ago Up 2 seconds 0.0.0.0:8080->8080/tcp, [::]:8080->8080/tcp hello-time
4318c4775813 containrrr/watchtower "/watchtower --inter…" 4 minutes ago Up 4 minutes (healthy) 8080/tcp watchtower
curlで確認すると、新しいバージョンになっているのがわかる。
curl -s http://localhost:8080| jq -r .
{
"message": "hello world",
"version": "0.0.2",
"time": "2025-07-07T12:39:17.107434"
}
watchtowerのログを見ると、途中でコンテナが再作成されているのがわかる。
time="2025-07-07T12:34:11Z" level=info msg="Session done" Failed=0 Scanned=2 Updated=0 notify=no
time="2025-07-07T12:35:11Z" level=info msg="Session done" Failed=0 Scanned=2 Updated=0 notify=no
time="2025-07-07T12:36:11Z" level=info msg="Session done" Failed=0 Scanned=2 Updated=0 notify=no
time="2025-07-07T12:37:23Z" level=info msg="Found new kun432/hello-time:latest image (9c36a2ee109c)"
time="2025-07-07T12:37:23Z" level=info msg="Stopping /hello-time (3b35f9e8b545) with SIGTERM"
time="2025-07-07T12:37:27Z" level=info msg="Creating /hello-time"
time="2025-07-07T12:37:28Z" level=info msg="Session done" Failed=0 Scanned=2 Updated=1 notify=no
time="2025-07-07T12:38:11Z" level=info msg="Session done" Failed=0 Scanned=2 Updated=0 notify=no
time="2025-07-07T12:39:11Z" level=info msg="Session done" Failed=0 Scanned=2 Updated=0 notify=no
で、いちいちlatestタグを付けていたのは、watchtowerのアップデートの判断は任意のタグでイメージのハッシュが変更されたら、、、、という感じになっているみたいで、残念ながらセマンティックバージョニングに対応しているわけではないみたい。
そこが使いにくくて、アップデートするツール自作してる人もいたりして、まあ確かにちょっと微妙かもなあ。
READMEにもあるけど、
Watchtower はホームラボ、メディアセンター、ローカル開発環境などでの使用を想定しています。商用または本番環境での使用は推奨していません。その場合は Kubernetes の利用をご検討ください。Kubernetes が大きすぎると感じる場合は、MicroK8s や k3s のような、Kubernetes クラスター運用の手間を大幅に軽減するソリューションをご覧ください。
このあたりも含めて、ちょっと商用できちんと管理したいみたいなニーズを考えて作られているいるわけではなさそう。まあだからといってK8Sを入れようとは個人的には思わないけど。
いつもにも増して今回は内容薄めなので、ドキュメント参照を推奨
似たようなものでこういうのもある・・・・
のだが、メンテ終了してる様子・・・
⚠️⚠️⚠️ ouroboros は開発が終了しました。その役割は(ほぼ)果たしており、開発者は現実の生活に屈服しました!フォークして自由にメンテナンスしていただいて構いません。過去1年間のご支援に感謝申し上げます :)。コミュニティからのサポートを受けて、依存関係との整合性を保つため、自動バージョンアップは継続されます。⚠️⚠️⚠️