diff --git a/.env.example b/.env.example index bd299f0..635cfa2 100644 --- a/.env.example +++ b/.env.example @@ -42,6 +42,11 @@ GPTMAIL_API_KEY=gpt-test # 注意:若填写此处,docker-compose.yml 中 watchtower 服务会自动同步读取同一变量 WATCHTOWER_HTTP_API_TOKEN= +# Watchtower Docker API 版本覆盖项。 +# 默认留空,让 Watchtower/Docker SDK 自动协商 API 版本。 +# 仅当 Docker 29.0-29.2 报 client version too old 时取消注释并设为 1.44。 +# WATCHTOWER_DOCKER_API_VERSION=1.44 + # Docker API 自更新(可选,高级功能) # ⚠️ 警告:启用后容器可通过 Docker API 控制宿主机其他容器,存在安全风险 # 需同时取消 docker-compose.yml 中 docker.sock 挂载的注释 diff --git a/README.en.md b/README.en.md index b0f3d94..a86a72f 100644 --- a/README.en.md +++ b/README.en.md @@ -183,6 +183,9 @@ services: - WATCHTOWER_HTTP_API_TOKEN=${WATCHTOWER_HTTP_API_TOKEN:-outlook-mail-plus-watchtower-default} - WATCHTOWER_HTTP_API_UPDATE=true - WATCHTOWER_CLEANUP=true + # Optional: set WATCHTOWER_DOCKER_API_VERSION=1.44 in .env if Docker 29.0-29.2 reports client version too old + # Empty by default to keep Docker API negotiation and avoid forcing too-new API versions on older engines + - DOCKER_API_VERSION=${WATCHTOWER_DOCKER_API_VERSION:-} - WATCHTOWER_HTTP_API_PERIODIC_POLLS=false command: --http-api-update --label-enable labels: @@ -209,12 +212,12 @@ Notes: 3. Switch "Update Method" to "Docker API" in Settings 4. ⚠️ Please fully understand the security implications before enabling -> ⚠️ **Troubleshooting**: If you see `client version 1.25 is too old. Minimum supported API version is 1.44` in Watchtower logs, your local Watchtower image cache is stale (the embedded Docker client API is too old). Fix: +> ⚠️ **Troubleshooting**: If you see `client version 1.25 is too old. Minimum supported API version is 1.44` in Watchtower logs, Docker Engine requires a newer Docker API version than Watchtower's default client API. To avoid breaking older Docker Engines, `docker-compose.yml` keeps the override empty by default. Set `WATCHTOWER_DOCKER_API_VERSION=1.44` in `.env`, then run: > ```bash -> docker compose pull watchtower # Pull the latest image -> docker compose up -d watchtower # Recreate the container +> docker compose pull watchtower # Pull the image +> docker compose up -d watchtower # Recreate with the new config > ``` -> The `docker-compose.yml` in this repo has pinned Watchtower to `1.7.1` to prevent this issue. +> If you are still on Docker 24 or older, do not set this override, or set it to an API version supported by that engine. #### ClawCloud / Reverse Proxy Deployment Notes @@ -275,6 +278,8 @@ python -m unittest discover -s tests -v Watchtower API auth token. **Can be left empty** — both app and watchtower automatically use the same built-in default, making it work out of the box; for production, use a random strong password - `WATCHTOWER_API_URL` Watchtower API address, default `http://watchtower:8080` (Docker internal network, usually no need to change) +- `WATCHTOWER_DOCKER_API_VERSION` + Optional Docker API version override for Watchtower. Default: empty, preserving API negotiation; set to `1.44` only if Docker 29.0-29.2 reports `client version too old` - `DOCKER_SELF_UPDATE_ALLOW` Whether to enable Docker API self-update, default `false`. ⚠️ Grants container Docker API access when enabled - `DOCKER_IMAGE` diff --git a/README.md b/README.md index 62475b2..d011184 100644 --- a/README.md +++ b/README.md @@ -188,6 +188,9 @@ services: - WATCHTOWER_HTTP_API_TOKEN=${WATCHTOWER_HTTP_API_TOKEN:-outlook-mail-plus-watchtower-default} - WATCHTOWER_HTTP_API_UPDATE=true - WATCHTOWER_CLEANUP=true + # 可选:Docker 29.0-29.2 若报 client version too old,可在 .env 设置 WATCHTOWER_DOCKER_API_VERSION=1.44 + # 默认留空以保留 Docker API 自动协商,避免旧 Docker Engine 被强制使用过高 API 版本 + - DOCKER_API_VERSION=${WATCHTOWER_DOCKER_API_VERSION:-} - WATCHTOWER_HTTP_API_PERIODIC_POLLS=false command: --http-api-update --label-enable labels: @@ -214,12 +217,12 @@ networks: 3. 在设置页选择"更新方式"为"Docker API" 4. ⚠️ 请充分了解安全风险后再启用 -> ⚠️ **常见问题**:如果 Watchtower 容器日志中出现 `client version 1.25 is too old. Minimum supported API version is 1.44` 错误,说明你本地缓存了旧版 Watchtower 镜像(内嵌的 Docker 客户端 API 版本过旧)。解决方法: +> ⚠️ **常见问题**:如果 Watchtower 容器日志中出现 `client version 1.25 is too old. Minimum supported API version is 1.44` 错误,说明当前 Docker Engine 要求更高的 Docker API 版本,而 Watchtower 的默认客户端 API 版本偏低。为避免影响旧版 Docker Engine,`docker-compose.yml` 默认保留自动协商;遇到该错误时可在 `.env` 中设置 `WATCHTOWER_DOCKER_API_VERSION=1.44`,然后执行: > ```bash -> docker compose pull watchtower # 拉取最新镜像 -> docker compose up -d watchtower # 重建容器 +> docker compose pull watchtower # 拉取镜像 +> docker compose up -d watchtower # 用新配置重建容器 > ``` -> 本项目 `docker-compose.yml` 已固定 Watchtower 版本为 `1.7.1`,可避免此类问题。 +> 如果仍使用 Docker 24 或更早版本,请不要设置此覆盖项,或设置为该 Docker Engine 支持的 API 版本。 #### ClawCloud / 反向代理部署注意事项 @@ -284,6 +287,8 @@ python -m unittest discover -s tests -v Watchtower API 鉴权令牌。**可留空**,留空时 app 和 watchtower 两边自动使用同一内置默认值,开箱即用;生产环境建议设置随机强密码 - `WATCHTOWER_API_URL` Watchtower API 地址,默认 `http://watchtower:8080`(Docker 内部网络,通常无需修改) +- `WATCHTOWER_DOCKER_API_VERSION` + Watchtower Docker API 版本覆盖项。默认留空,保留 API 自动协商;仅当 Docker 29.0-29.2 出现 `client version too old` 时建议设为 `1.44` - `DOCKER_SELF_UPDATE_ALLOW` 是否启用 Docker API 自更新功能,默认 `false`。⚠️ 启用后容器可访问 Docker API,存在安全风险 - `DOCKER_IMAGE` diff --git a/docker-compose.yml b/docker-compose.yml index ed1b655..09d3475 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -85,6 +85,9 @@ services: - WATCHTOWER_HTTP_API_TOKEN=${WATCHTOWER_HTTP_API_TOKEN:-outlook-mail-plus-watchtower-default} - WATCHTOWER_HTTP_API_UPDATE=true - WATCHTOWER_CLEANUP=true + # 可选:Docker 29.0-29.2 若报 client version too old,可在 .env 设置 WATCHTOWER_DOCKER_API_VERSION=1.44 + # 默认留空以保留 Docker API 自动协商,避免旧 Docker Engine 被强制使用过高 API 版本 + - DOCKER_API_VERSION=${WATCHTOWER_DOCKER_API_VERSION:-} # 禁用定时轮询,仅通过界面触发更新 - WATCHTOWER_HTTP_API_PERIODIC_POLLS=false command: --http-api-update --label-enable diff --git a/tests/test_watchtower_compose_contract.py b/tests/test_watchtower_compose_contract.py new file mode 100644 index 0000000..e397eb8 --- /dev/null +++ b/tests/test_watchtower_compose_contract.py @@ -0,0 +1,31 @@ +"""Watchtower compose contract tests.""" + +from __future__ import annotations + +import unittest +from pathlib import Path + +REPO_ROOT = Path(__file__).resolve().parents[1] + + +class WatchtowerComposeContractTests(unittest.TestCase): + def test_compose_keeps_watchtower_docker_api_override_optional(self): + content = (REPO_ROOT / "docker-compose.yml").read_text(encoding="utf-8") + self.assertIn("DOCKER_API_VERSION=${WATCHTOWER_DOCKER_API_VERSION:-}", content) + self.assertNotIn("DOCKER_API_VERSION=${WATCHTOWER_DOCKER_API_VERSION:-1.44}", content) + + def test_readme_snippets_keep_watchtower_docker_api_override_optional(self): + for path in ("README.md", "README.en.md"): + with self.subTest(path=path): + content = (REPO_ROOT / path).read_text(encoding="utf-8") + self.assertIn("DOCKER_API_VERSION=${WATCHTOWER_DOCKER_API_VERSION:-}", content) + self.assertNotIn("DOCKER_API_VERSION=${WATCHTOWER_DOCKER_API_VERSION:-1.44}", content) + + def test_env_example_documents_watchtower_docker_api_override(self): + content = (REPO_ROOT / ".env.example").read_text(encoding="utf-8") + self.assertIn("WATCHTOWER_DOCKER_API_VERSION=1.44", content) + self.assertIn("默认留空", content) + + +if __name__ == "__main__": + unittest.main()