wud_zh 是 getwud/wud 的简体中文本地化分支: 全站中文界面、可一键切回英文,并在不破坏上游行为的前提下,补上了 监控清单、Docker Hub 多镜像源、跨机监控向导、阿里云 ACR 匿名鉴权。 换镜像名即可用,环境变量 / 触发器 / 卷映射 / REST API 与上游完全一致。
上游 WUD 的界面文案是硬编码在 17 个 Vue 文件里的英文串,没有任何 i18n 框架。
本分支引入了 vue-i18n v10,把散落的文案抽成两份键位对称的消息包,并接上了 Vuetify 的内置本地化。
两份消息包键位一一对应,改一处不会漏另一处。
| zh-CN.ts | 简体中文消息包 |
| en.ts | 英文消息包(值直接取自上游源码) |
| 命名空间 | 17 个(containers / watchlist / servers / config / hubMirrors …) |
| 叶子键 | 364 条(中英各 364) |
| index.ts | 默认语言、读写 wud-lang、同步 <html lang> |
已汉化的界面:
切回 English 看到的界面串,都是照着上游源码原文取的,不是"翻译回去的英文"(只把上游的模板插值改写成 {占位符})。下面是脚本逐条回查上游 9.2.0 源码的实测结果:
| 分类 | 条数 | 说明 |
|---|---|---|
| 上游已有界面 | 227 | 其中 211 条逐字一致(93%),差集 16 条见下 |
| 本分支新增界面 | 137 | 监控清单 54 / 服务器管理 55 / 镜像源 28 三个新增命名空间 |
| 合计 | 364 | 中英两份消息包各 364 条,键位完全对称 |
那 16 条差集已逐条核对:1 条是 HTML 实体写法差异(上游 &、消息包里 &,渲染等价),14 条是挂在既有页面上的新入口文案(监控清单入口、语言切换、已知未监控区块),1 条是真偏差——首页的复数句丢了上游的 s,已在仓库待办里记着。
汉化过程中还回修了 4 处偏差,例如登录按钮必须还原成上游的 Login、复制提示要保留 xxx copied to clipboard 的类别前缀。
上游的 6 个次要页面还没翻,功能完全正常,只是文案是英文:
日志 Logs 个人资料 Profile 镜像仓库 Registries 认证 Authentications 用户 Users 状态 State
补翻很便宜:两份消息包同时加键 → 在 .vue 里把硬编码串换成 $t('ns.key') → push 到 i18n-zh,CI 自动重建镜像。
界面默认简体中文,两处入口随时切回 English;选择记在 localStorage(wud-lang),刷新和重新登录都保持。
| 入口 | 说明 |
|---|---|
| 侧边栏底部 🌐 语言 | 已登录时的入口。侧栏收起显示为带悬浮提示的图标;展开显示为列表项,右侧标注当前语言(中文 / English) |
| 登录页卡片上方 | 未登录状态也能切换(中文 / English) |
| 联动项 | 自动同步文档 <html lang>,以及 Vuetify 内置文案(表格分页、空状态等)一并跟随切换 |
WUD 是那种"更新一多就得天天看"的工具 —— 容器列表、触发器状态、错误信息全在界面上。母语界面的价值不是好看,是看到 error 那一行的瞬间就能判断要不要动手。
汉化只是起点。下面这几条是上游当前版本没有、而中文用户几乎一定会撞上的问题 —— 尤其是国内出口访问不到 Docker Hub 这一条,会直接让 WUD 变成"全屏报错"。 所有改动都是纯增量:不改上游的环境变量、触发器与 REST API 行为。
跨机监控不再靠手拼环境变量。/configuration/watchers 升级为服务器列表(地址 / 端口 / 扫描计划 / 监控数 / 可达性),并带添加服务器三步向导:生成对端只读 socket 代理的 compose → 生成隧道账号与公钥 → 生成 wud.yaml 片段。删除也有对应引导。
上游的 Alibaba provider 只在配了凭据时才发 Basic,否则不带任何认证头、不走 Bearer 匿名流程 —— 而阿里云要求 Bearer,于是公开仓库也永远 401,检测不了更新。本分支自己实现 Bearer 握手:探测 /v2/ 取 realm → 换 token → 带 token 重放,兼容两种响应键;有凭据时仍转发 Basic 以支持私有仓库。
更新成功后自动回一封成功/失败邮件,含旧/新镜像 digest 与目标版本。并修掉了两个真实痛点:邮件正文里 digest 类更新会显示 (undefined) 的模板缺陷;以及"更新→重建→又更新"的自激循环(按容器名加冷却护栏 + 双判据成功检测)。
相对上游基线 9.2.0 的纯 fork 差异(git diff --stat 227ce2a2 i18n-zh,227ce2a2 即合入的 v9.2.0 提交)。
| 文件 | 作用 |
|---|---|
| ui/src/i18n/index.ts | i18n 入口:默认语言、读写 wud-lang、同步 <html lang> |
| ui/src/i18n/zh-CN.ts | 简体中文消息包 |
| ui/src/i18n/en.ts | 英文消息包(与中文键位对称) |
| ui/src/views/WatchlistView.vue | 监控清单页面(勾选 + 来源标识 + 待生效提示) |
| ui/src/components/HubMirrorsEditor.vue | 镜像源列表编辑器 |
| app/store/watchPreference.ts | 监控偏好读写层(三态语义 + fail-safe) |
| app/store/watchPreference.test.ts | 上述 store 的单元测试(11 用例) |
| app/store/hubMirror.ts | 镜像源列表的存储与探测 |
| ui/src/services/mock/data/discovered.ts | 监控清单演示数据(复刻三态语义) |
| .github/workflows/docker-image.yml | push i18n-zh 自动构建推送 GHCR |
| 文件 | 改动 |
|---|---|
| app/api/container.ts | 新增 discover 与 watch-preference 两个接口 |
| app/api/registry.ts | 镜像源列表的读取 / 保存 / 连通性探测 |
| app/watchers/…/docker/Docker.ts | 监控判定改为三优先级;新增 discoverContainers() |
| app/registries/…/hub/Hub.ts | Hub 的 url/authurl/service 可经环境变量覆盖 |
| app/registries/…/alibaba/Alibaba.ts | 实现匿名 Bearer 鉴权握手 |
| app/store/db/migrations.ts | 新增 watched_containers 表(迁移 id=5) |
| app/store/db/schema.ts | 对应 schema |
| app/store/watchPreference.ts | 监控偏好读写层(三态语义 + fail-safe) |
| app/store/hubMirror.ts | 镜像源列表的存储与探测 |
| 配套 .test.ts | 上述 store / registry / watcher 的单测 |
其余改动全在 ui/(汉化 + 语言切换 + 新页面)。
分支每次合并上游后都要手工补键:上游新增的界面文案不会自动出现在语言包里(上游没有 i18n 框架),所以每次同步都要把新串补进两份消息包。合并冲突集中在被翻译过的 .vue 文件;ui/src/i18n/* 基本不冲突。
| 已同步的上游版本 | 说明 |
|---|---|
| 9.1.0 | 合并提交,零 i18n 补键(上游未动 UI) |
| 9.2.0 | 当前基线,已并入 i18n-zh |
镜像公开托管在 GHCR,无需登录即可拉取。
docker run -d \
--name wud \
-p 3000:3000 \
-e WUD_AUTH_ADMIN_USER="admin" \
-e WUD_AUTH_ADMIN_PASSWORD="MySecurePassword123" \
-v /var/run/docker.sock:/var/run/docker.sock \
ghcr.io/dc1024/wud_zh:latest
services:
wud:
- image: getwud/wud:latest
+ image: ghcr.io/dc1024/wud_zh:latest
services:
wud:
image: ghcr.io/dc1024/wud_zh:latest
container_name: wud
ports:
- "3000:3000"
environment:
- WUD_AUTH_ADMIN_USER=admin
- WUD_AUTH_ADMIN_PASSWORD=MySecurePassword123
# --- Docker Hub 镜像:绕过出口封锁(匿名镜像站,无需 authurl)---
- WUD_REGISTRY_HUB_URL=https://docker.1panel.live
volumes:
- /var/run/docker.sock:/var/run/docker.sock
restart: unless-stopped
镜像站可换任意信任的公共 / 私有 OCI 代理,只要它完整实现 manifest 与 tags/list。(选 1panel 而非 daocloud,是因为后者禁用了 tags/list,会破坏 semver 版本发现。)
push 到 i18n-zh 后由 GitHub Actions 自动构建(约 1~3 分钟)并推送 GHCR,标签为 latest 与 sha-<commit>;也可在 Actions 页手动 Run workflow。
构建时把 WUD_VERSION 固定写入,界面显示为 wud_zh-beta1.4。规则:无新功能则维持,有实质更新则最后一位 +0.1(1.0 → 1.1 → 1.2 → 1.3 → 1.4)。
在 zh-CN.ts 和 en.ts 里同时加键(两份必须键位对称)→ 把 .vue 里的硬编码文案换成 $t('命名空间.键') → 提交推送,CI 自动重建镜像。约定:en.ts 的值必须与上游原文逐字一致;中文按语义自然表达,不逐字直译。