
Dozzle 常见问题排查完全指南从启动失败到性能优化与多主机架构【免费下载链接】dozzleRealtime log viewer for containers. Supports Docker, Swarm and K8s.项目地址: https://gitcode.com/GitHub_Trending/do/dozzleDozzle 是一个轻量级的 Docker 日志实时查看器支持 Docker、Swarm 和 Kubernetes 三种运行环境。本文基于官方 FAQ 文档结合仓库源码internal/container/host_id.go、internal/docker/stats_collector.go、internal/support/web/sse.go等逐条解析 Dozzle 部署与使用中最常见的问题——从容器启动失败、日志加载缓慢到多主机 ID 冲突、内存统计缺失和 Swarm 集群超时并给出可直接落地的修复方案读完即可独立排障。一、Dozzle 启动失败client version 1.x is too new问题现象Dozzle 启动时直接退出并伴随如下报错failed to create docker client: ... client version 1.54 is too new. Maximum supported API version is 1.38原因与解决方案Dozzle 依赖底层的 Docker SDK 与 Docker Engine 通信因此要求Docker Engine 19.03 或更新版本API 版本 1.40。较旧的守护进程例如 Docker 18.06API 版本 1.38不在 SDK 支持范围内启动时就会抛出上述错误。推荐做法将 Docker Engine 升级到受支持的版本临时规避将 Dozzle 固定到v10.5.2或更早的版本这一版本的 Docker SDK 仍会向下协商到更老的 API 版本。二、如何升级 DozzleDozzle 遵循标准的 Docker 镜像实践升级即拉取新镜像并重建容器docker pull amir20/dozzle:latest docker compose up -d dozzle升级有两个关键注意点保持/data卷挂载不变用户设置、通知规则以及其他状态都存储在/data中详见下一节升级过程中该卷必须持续挂载否则状态会丢失生产环境固定具体版本号建议使用amir20/dozzle:v10.9.2这类具体标签而非latest让升级是有意识的行为而不是意外的行为。回滚也非常简单——重新部署旧标签即可。从源码看Dockerfile 同时构建了scratch和alpine两个基础镜像阶段并最终以scratch阶段作为默认构建目标发布标签遵循v版本与v版本-alpine的对应关系。三、容器启动报no such file or directoryEntrypoint 被平台包装问题现象容器以类似下面的错误退出exec /opt/unraid/tailscale: no such file or directory原因与解决方案默认镜像基于FROM scratch构建只包含 Dozzle 二进制没有任何 shell 或解释器。部分平台如 Unraid 的逐容器 Tailscale 开关、部分 Sidecar 和 Init 注入器会在容器 Entrypoint 上 bind-mount 一个#!/bin/sh包装脚本再重新执行原始入口。由于镜像中没有/bin/sh包装脚本无法运行容器报错时点名的是包装脚本而非缺失的 shell。针对这类平台请改用alpine变体——同一份二进制构建在 Alpine 基础镜像之上自带 shelldocker run \ --volume/var/run/docker.sock:/var/run/docker.sock \ -p 8080:8080 \ amir20/dozzle:alpine带版本号的标签遵循同样规律如amir20/dozzle:v10.9.2-alpine。其余场景仍推荐基于 scratch 的latest镜像因为它体积明显更小且无需维护发行版补丁。这一结论在 Dockerfile 中有直接印证alpine阶段明确注释为为会 bind-mount shell 包装器的平台发布的可选变体。四、/data目录里存了什么如何备份/data是 Dozzle 持久化一切需要跨容器重启存活数据的地方包括内容说明users.yml/users.yaml简单认证Simple Auth的用户文件如果创建了的话通知规则、目标与投递状态通知notifications的完整配置与状态按用户的 UI 设置仅多用户模式下持久化到磁盘单用户模式设置存放在浏览器 localStorage少量内部文件例如已关闭dismissed公告的状态从源码可以确认相关路径internal/notification/persist.go 中定义了./data/notifications.yml通知配置与./data/cloud.ymlCloud 配置internal/web/user_ref.go 中定义了./data/.user-ref-secretinternal/auth 下的用户认证逻辑同样围绕users.yml展开。该目录体积很小通常远低于 10 MB用一个简单的tar或rsync即可完成挂载卷的备份。升级或迁移到新主机时搬走整个/data卷即可带走全部设置。五、日志加载缓慢或永远不加载反向代理缓冲问题原理Dozzle 基于 SSE 推送日志Dozzle 使用Server Sent EventsSSE通过一条不关闭的 HTTP 流与服务端保持连接。如果中间的反向代理试图缓冲这条连接Dozzle 永远收不到数据会一直干等代理刷新缓冲区。从1.23.0版本起Dozzle 会发送X-Accel-Buffering: no响应头来阻止反向代理缓冲。这一行为有清晰的源码证据internal/support/web/sse.go 中的NewSSEWriter在设置Content-Type: text/event-stream的同时设置了X-Accel-Buffering: nointernal/web/cloud_chat.go 对 Cloud Chat 的流式接口也做了同样的处理。不过部分代理会忽略这个响应头此时必须显式关闭缓冲。nginx关闭proxy_bufferingserver { ... location / { proxy_pass http://dozzle.container.ip.address:8080; } location /api { proxy_pass http://dozzle.container.ip.address:8080; proxy_buffering off; proxy_cache off; } }traefik从压缩中间件中排除text/event-streamTraefik 通过 Middlewares 提供压缩能力常规配置如下http: middlewares: middlewares-compress: compress: {}启用该压缩后通过 traefik 访问 Dozzle例如dozzle.mydomain.com时部分容器会不再显示日志而同一实例直接访问例如localhost:8080却正常。已观察到出现该现象的容器包括dozzle、homepage、glances、filebrowser非完整列表。解决办法是把text/event-stream从压缩中间件的排除列表中排除http: middlewares: middlewares-compress: compress: excludedContentTypes: - text/event-stream六、如何通过容器名称获得直达链接如果你有工具需要在创建新容器后把用户直接带到对应容器的日志页Dozzle 提供了专用的/show路由按名称搜索容器并转发到该容器。例如容器名为foo.bar、ID 为abc123可以把用户导向/show?namefoo.bar它会自动转发到/container/abc123其实现位于前端路由页面 assets/pages/show.vue监听容器列表变化后通过route.query.name可选的route.query.host过滤容器按startedAt降序取最新匹配项再通过router.push跳转到/container/[id]如果没有匹配项则回退跳转到首页。七、ARM 设备上内存占用不显示该问题仅影响 ARM 设备。Dozzle 通过 Docker API 收集容器的内存占用信息。如果内存占用不显示大概率是 Docker API 没有返回内存数据。验证方法执行docker info如果看到以下警告说明宿主机的 cgroup 内存限制支持未开启WARNING: No memory limit support WARNING: No swap limit support解决办法在/boot/cmdline.txt中加入以下内核参数并重启设备cgroup_enablecpuset cgroup_enablememory cgroup_memory1八、日志中出现重复 Host 错误问题现象日志中出现time2024-07-10T13:35:53Z levelwarning msgduplicate host ID: *********, Endpoint: 1.1.1.1:7007 found, skipping原因与解决方案Dozzle 通过 Docker API 收集主机信息每个 Host 必须有唯一 ID该 ID 用于在界面中标识主机Swarm 模式下使用docker system info返回的Node ID作为 Host ID非 Swarm 模式使用docker system info返回的System ID作为 Host ID。从源码看Host ID 的解析集中实现在 internal/container/host_id.goDerivedHostID.Resolve按优先级取SwarmNodeID→ Podman 派生 ID →EngineID→ 调用方传入的Fallback。常见触发场景是从备份恢复的虚拟机带有相同的 Host IDDozzle 会认为该主机已存在而跳过添加。修复方式删除/var/lib/docker/engine-id文件——该文件包含 Host ID由 Docker 守护进程启动时生成删除后 Docker 会在下次启动时重新生成。九、日志中出现Host not found错误Podman 特殊问题问题现象该问题主要是 Podman 用户遇到。Podman无守护进程、不维护引擎身份其 Docker 兼容的/info端点每次调用都会返回一个全新的随机 UUID。Dozzle 在连接时读取一次该 ID 并用它标识主机于是每次重启都会产生一个不同的主机而主服务器仍在向一个无人应答的旧 ID 路由。解决方案Dozzle 现在会从主机名hostname和容器存储路径storage path派生出稳定的 ID因此只要服务器和 Agent 都更新到新版本问题会自动修复。如果仍然出现该错误重启主 Dozzle 服务器以让新 ID 生效。[!WARNING] 早期版本的本页文档曾建议创建/var/lib/docker/engine-id文件。这在 Podman 下从未生效因为 Podman 不会读取任何此类文件可以放心删除。如果使用的是 Docker 而非 Podman请检查/var/lib/docker/engine-id是否存在、内含 UUID 且对 Docker 守护进程可读。源码印证在 internal/container/host_id.go 的podmanHostID中仅当Runtime podman时才会参与派生它使用固定命名空间cb6c32a9-acb9-454b-8427-014fe9bc073c对Hostname \x00 StorageRoot计算 SHA1 UUID从而保证同一台机器上跨重启、跨版本稳定。两个 Podman 主机仍然冲突怎么办如果两台 Podman 主机同时共享主机名和存储路径例如克隆的 VM或从未设置过主机名的机器它们仍会得到相同的派生 ID。此时可在其中一台上设置DOZZLE_HOST_ID来打破平局podman run -e DOZZLE_HOST_IDweb-01 ...DOZZLE_HOST_ID在 internal/support/cli/args.go 中定义对应命令行参数--host-idinternal/container/host_id.go 中的NewHostIDResolver会在设置了 override 时返回StaticHostID直接以该值作为主机 ID。完整的 Podman 部署说明见 Podman 指南。十、为什么只看到运行中的容器如何查看已停止容器默认情况下 Dozzle只显示运行中的容器。要查看已停止的容器需要在设置中启用Show Stopped Containers选项。该选项默认关闭目的是减少界面中显示的容器数量。十一、能否在多台 Dozzle 实例间同步设置单用户模式设置保存在浏览器的localStorage中只能在那一个浏览器里生效多用户模式Dozzle 使用用户名将设置写入磁盘/data目录并在多实例间同步。因为 Dozzle 需要知道用户是谁才能按用户区分设置。因此要跨实例同步设置需要启用多用户模式见 认证指南并提供用户名。十二、为什么 Dozzle 不直接支持 Slack、Discord、Telegram、邮件等通知这是刻意设计Dozzle 对告警去向保持无立场。与其内置针对特定平台的集成Dozzle 提供Webhook 可定制的 Payload 模板可以把告警发送到任何接受 HTTP 请求的服务——Slack、Discord、Telegram、ntfy、PagerDuty、Opsgenie 或你自己的内部工具无需等待 Dozzle 增加显式支持。采用这种方案的原因通用性Webhook 几乎适用于所有通知平台厂商专属集成只能覆盖用户需求的一小部分而 Webhook 覆盖全部可维护性每个厂商集成都带有各自的 API 特性、认证流程、速率限制和破坏性变更支持它们意味着 Dozzle 维护者要替第三方服务排障——这超出了日志查看器的职责范围简洁性Dozzle 是查看 Docker 日志的轻量聚焦工具通用的通知层能让代码库保持小巧、项目可持续。如果你需要更定制化的体验如 Web Push 通知、ntfy 操作按钮Dozzle Cloud 正是为此设计。设置 Webhook 的完整指南见 告警与 Webhook——其中内置了 Slack、Discord 和 ntfy 的现成 Payload 模板可直接使用或按需修改。仓库中 assets/components/notifications/payloadTemplates.ts 定义了slack、discord、ntfy、custom四种 Payload 格式并内置了对应的 JSON 模板。十三、没有浏览器连接时为什么 dockerd 和 containerd 仍有轻度 CPU 占用这是有意为之的行为最后一个浏览器断开后Dozzle 仍会继续推送容器统计信息最长 6 小时Kubernetes 环境下为 2 小时之后自动关闭统计采集器。统计持续推送是为了让你重新打开界面时能看到此前的 CPU 与内存历史曲线而不是一张空白图表。如果关闭标签页的瞬间就停止推送历史数据就不存在了。代价是 dockerd 和 containerd 会有少量、平稳的 CPU 占用因为 Docker 的 stats API 基于轮询polling。重启 Dozzle 容器会立即重置计时器主机随即回到空闲状态。该行为刻意设计为不可配置——过短的超时会破坏依赖持续统计的功能也就失去了统计历史的意义。源码证据internal/docker/stats_collector.go 中定义了var timeToStop 6 * time.HourStop()方法在订阅数归零时通过time.AfterFunc(timeToStop, ...)安排延迟关闭internal/k8s/stats_collector.go 中对应为var timeToStop 2 * time.Hour。同时internal/docker/stats_collector.go 的streamStats会对中断的 stats 流以指数退避1 秒起步、30 秒封顶自动重连避免单个瞬时错误导致某个容器永久消失于统计窗口。十四、Swarm 模式下实例超时或负载均衡器看不到所有节点在 Swarm 模式下Dozzle 实例可能需要独立的 overlay 网络。如果发现连接不同 Dozzle 节点时行为不一致可以创建一个只包含 Dozzle 实例的独立 overlay 网络如下所示services: logs: ... networks: [ traefik, dozzle ] ... networks: dozzle: driver: overlay traefik: external: true其中外部网络traefik是负载均衡器服务发现所用的 overlay 网络新建的dozzleoverlay 网络则让各 Dozzle 节点之间能够相互通信。小结一份快速排障速查表症状根因修复client version 1.x is too newDocker Engine 过旧API 1.40升级 Docker Engine临时固定v10.5.2及更早版本no such file or directoryscratch 镜像无 shellEntrypoint 被包装改用amir20/dozzle:alpine日志缓慢/不加载反向代理缓冲 SSE 流关 nginxproxy_bufferingtraefik 排除text/event-stream内存占用不显示ARMcgroup 内存支持未开启在/boot/cmdline.txt添加cgroup_enablememory等参数并重启duplicate host ID多个主机共享同一 Host ID删除/var/lib/docker/engine-id后重启 Dockerhost not foundPodmanPodman/info每次返回随机 UUID升级到新版本自动派生稳定 ID冲突时设置DOZZLE_HOST_ID看不到已停止容器默认只显示运行中容器设置中启用Show Stopped Containers设置无法跨实例同步单用户模式存于 localStorage启用多用户模式设置按用户名存至/datadockerd/containerd CPU 偏高stats 持续采集最长 6 小时K8s 2 小时无需处理属设计行为重启容器可立即复位Swarm 超时/看不到节点Dozzle 节点间缺少专用网络为 Dozzle 实例创建独立 overlay 网络【免费下载链接】dozzleRealtime log viewer for containers. Supports Docker, Swarm and K8s.项目地址: https://gitcode.com/GitHub_Trending/do/dozzle创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考