ITADN
shukiv/jabali-panel
shukiv/jabali-panel · 文件 下载 ZIP
文件最后提交记录最后更新时间
README.md
以下内容由 AI 翻译,如有问题请点此提交 issue 反馈
Jabali Panel

Jabali Panel

一个用于 WordPress 和 PHP 托管的现代托管控制面板,使用 Go 和 React 构建。

网站  |  在线演示  |  安装  |  架构  |  CLI

Release candidate Go 1.25 React 19 Ant Design 5 MariaDB 11 Debian 13 AGPL-3.0

多租户隔离。根安全自动化。数据库驱动的协调。 单个面板二进制文件同时提供 API 和嵌入式 SPA,而特权主机 操作则委托给一个由 root 拥有的 Unix 套接字代理执行。

[!NOTE] Jabali Panel 目前处于发布候选阶段。在 1.0 版本之前,请预期快速迭代和 破坏性变更。

演示与网站

演示模式(由构建标签控制,位于 main

位于 https://demo.jabali-panel.com 的公共演示运行 演示模式。截至 JAB-159,它位于 main,在编译时从生产构建产物中排除 (参见 ADR-0160)。它不是运行时切换 开关,也没有 feat/demo-mode 分支可供变基。

演示模式添加的内容(仅存在于演示构建中):

  • 写入拦截中间件 — 每个非幂等 /api/v1/* 请求 (POST/PUT/PATCH/DELETE) 返回 403 {"error":"demo_mode"},因此访客可以 浏览所有读取端点,而永远不会触及代理或数据库写入;
  • 一个 /info 端点,用于公开预置的演示凭据
  • 固定的 DEMO 横幅 + “以管理员身份进入 / 以用户身份进入” 按钮。

为什么这在 main 上是安全的。 演示 Go 代码带有 //go:build demo,并且 演示 UI 受 import.meta.env.VITE_DEMO === "1" 保护,因此生产构建 不包含任何这些内容 — 写入拦截、暴露凭据的 /info 以及 横幅/登录覆盖在非演示二进制文件和 SPA 包中物理上不存在。 CI 在每个 PR 上证明这一点(make demo-guard + demo-guard / ui-unit 作业 断言生产构建没有 demo_mode / jabali-demo-banner 标记,而 演示构建则有)。这严格强于旧的“将其保留在分支上并 希望没有人翻转标志”的模型。

运行演示: 使用 echo demo > /etc/jabali/deploy-profile 标记主机。 install.sh 和每个 jabali update 随后使用 -tags demo 构建面板,并使用 VITE_DEMO=1 自动构建 SPA —— 演示跟踪 main 且无需变基。 生产主机保持该文件不存在(默认状态),且从不包含演示代码。

安装

在全新的 Debian 13 系统上一行安装 —— 默认启动 TUI 安装程序 (选择部署配置文件 + 可选模块,然后查看实时进度 窗格):

curl -fsSL https://get.jabali-panel.com | sudo bash

get.jabali-panel.com 提供 bootstrap.sh:它下载最新的经 sha256 校验的发布 tarball,解压预构建的 jabali-installer 二进制文件 + install.sh,并在真实终端上运行安装程序(即使通过 curl | bash 管道传输也能正常工作)。在 -s -- 后添加参数,例如 --dry-run

经典 / 脚本化安装(无 TUI —— 直接运行经过验证的 bash 安装程序):

curl -fsSL https://raw.githubusercontent.com/shukiv/jabali-panel/main/install.sh | sudo bash

两者运行相同的引擎。install.sh 获取 Go 1.25,构建面板 + 代理二进制文件,使用 Vite 构建 SPA,写入 systemd 单元,配置 MariaDB + Redis + PowerDNS + Stalwart + Bulwark + CrowdSec(根据所选模块),并对 /health 进行冒烟测试。幂等——重新运行以升级。设置 JABALI_MODULES=…(逗号分隔列表)或保留 TUI 以构建最小化 / 模块化安装。

可选标志:

  • --debug 显示完整输出而非旋转指示器
  • --hostname <fqdn> 覆盖自动检测的主机名
  • JABALI_HOSTNAME=<fqdn> 用于无人值守安装的环境变量等效项

卸载(回滚系统软件包,可选保留 /home):

curl -fsSL https://get.jabali-panel.com | sudo bash -s -- --uninstall

安装完成后:

  • 管理面板:https://your-host:8443/jabali-admin
  • 用户面板:https://your-host:8443/jabali-panel
  • Webmail:https://mail.your-domain/

面板 API 监听 Unix socket;nginx 在 :8443 上终止 TLS 并 代理上游。如果 nginx 宕机,面板和 agent 保持运行,因此 运维人员可以通过 jabali CLI 进行恢复,而不会丢失进行中的状态。

亮点

  • 每用户 Linux 账户,配备每用户 PHP-FPM 主进程 + cgroup v2 + POSIX 配额
  • 通过 nspawn 容器提供 SSH shell 访问,支持自动启动和空闲超时
  • 用于 SSL、邮件、DNS、备份、迁移的 Root agent —— 前端为基于 /run/jabali-agent/agent.sock 的类型化 NDJSON RPC 契约(面板不执行 shell 命令)
  • 以数据库为真相源模型:60 秒协调器读取面板数据库,并收敛 nginx vhosts、PHP 池、邮箱、DKIM、DNS、SSL、mta-sts 以及每用户限制
  • cPanel 和 WHM 迁移(分析 → 修复权限 → 验证 → 恢复),保留 MySQL 用户 + 密码哈希
  • 用于从外部服务器迁移邮件的 IMAP 同步
  • Stalwart Mail Server,支持浏览器信任的 IMAPS/465/587(LE 证书推送到 Stalwart 证书对象)以及自删除 SSO 文件(Installatron 模式),实现一键 Webmail
  • 每邮箱转发器、自动回复、共享文件夹、免责声明
  • Bulwark(Next.js JMAP)Webmail,支持同源每租户路由(nginx sub_filter 将面板主机名重写为 $host,使 SPA 在 mail.<tenant> 上保持同源)
  • PowerDNS 权威服务器 + 递归解析器,支持原生 DNSSEC(每域名开关)
  • 每域名监听 IP 绑定(M24 IP 管理器),针对 MariaDB 11.x 进行保留字安全迁移
  • 每域名可选的 nginx FastCGI 微缓存,针对购物车 / 管理 / 认证 Cookie 提供安全绕过
  • Restic 备份(account_full + system_backup),支持加密、去重、SFTP / S3 目标,计划任务 + 按需执行
  • WordPress 一键安装 / 删除 / 克隆 (M10) — 15 个应用目录 (M19) 包括 Moodle / Joomla / NextCloud / OpenCart / Mautic / Drupal
  • 每用户资源限制:cgroups v2 slice drop-in, nginx limit_req, POSIX quota — 管理员可切换,由 reconciler 收敛
  • 集成安全套件:CrowdSec parsers + AppSec WAF + 每用户 出站防火墙 (nftables + cgroupv2-vmap) + ModSecurity 被 CrowdSec AppSec 取代 (ADR-0060) + LMD + ClamAV-on-demand + YARA + Tetragon 用于恶意软件检测 + jabali 隔离 + M14 通知分发
  • 6 通道通知:Discord, ntfy, Web Push (VAPID), SMS, Email, Webhook, Slack, 应用内铃铛 — 4 个事件源包括证书续期, 磁盘已满, 服务宕机, CrowdSec 峰值
  • 一次性登录令牌 (CLI + 仪表盘) 带有 IP 绑定
  • 面板与 webmail 之间无魔法链接的 SSO (无 Hydra / OIDC 开销 — ADR-0040 取代了 M16 Hydra 回滚)
  • 审计日志, 账户活动流, 加密诊断日志共享至 支持, 应用内更新 + 支持选项卡

功能地图

管理面板

  • 仪表盘,包含统计信息、健康状态、最近活动、通知铃铛
  • 用户管理,支持暂停、套餐、配额、身份模拟
  • 服务器设置(主机名、名称服务器、公网 IP、面板证书)
  • systemd 服务的服务管理器 + 启动/停止/重启
  • PHP 版本及每用户池管理(服务器级扩展选项卡)
  • DNS 区域、模板、DNSSEC、辅助 NS
  • SSL 签发与续期(面板证书 + 每域名)
  • IP 地址分配(托管 IP 池、每域名绑定)
  • 备份:account_full + system_backup,本地 + 远程(SFTP/S3), 计划任务,加密目标
  • 迁移(cPanel 恢复、WHM 下载、IMAP 同步)
  • 安全:CrowdSec 白名单 / 警报 / 控制台 / 验证码 + UFW + AppSec 地理封锁 + 每用户出站防火墙 + 恶意软件隔离
  • 更新 + 支持选项卡:实时 jabali update 配合临时 systemd 单元, 向 webmaster 共享封装加密的诊断信息
  • 服务器状态(CPU / 内存 / 磁盘 / 队列 / 5 秒轮询)
  • 数据库管理操作(精选调优器、root 密码、processlist、 pmaAdmin SSO)
  • 邮件队列、限流、MTA-STS、出站报告
  • 审计日志、通知分发器、jabali-isolator 事件
  • 通知渠道管理(测试发送、作用域、限流)

用户面板

  • 域名、重定向、自定义 nginx 规则、监听 IP、FastCGI 微缓存
  • DNS 记录编辑器,具备冲突检测(依据 RFC 1034 §3.6.2 的 CNAME 排他性)和去重功能
  • 邮件:域名、邮箱、转发器、自动回复、全捕获(catch-all)、 免责声明(HTML)、共享文件夹、邮件日志
  • IMAP 同步(单个 + 批量)
  • Webmail SSO(Bulwark, Next.js JMAP)
  • WordPress(安装、更新、扫描、SSO)+ 其他 14 个一键应用
  • 文件管理器(AntD 原生)+ SFTP + SSH 密钥
  • 通过 nspawn 容器访问 SSH shell(空闲超时)
  • 数据库(标签页视图中的 MariaDB + Postgres),支持 phpMyAdmin SSO
  • 按账户配置 PHP 设置
  • SSL 管理
  • Cron 任务(systemd-user 定时器 + 允许列表)
  • 备份 + 恢复(account_full)
  • 日志、统计、带宽使用情况(每日 nginx 日志同步)
  • 支持访问链接生成器(一次性 IP 绑定令牌)
  • 通知偏好设置(Discord, ntfy, Web Push, SMS, Email)

平台

  • 根级代理(panel-agent),带有类型化的 NDJSON RPC 处理器注册表
  • 协调器(60 秒周期)收敛 domain.create / SSL / DKIM / vhosts / PHP 池 / nginx 速率限制 / 邮箱 / mtasts / ssh 密钥 / cron
  • 作业队列:异步备份 + 迁移步骤 + WordPress 安装
  • 健康监控器,在服务宕机 / 证书即将 过期 / 磁盘已满 / CrowdSec 激增 / 队列深度时触发通知分发
  • Redis(Unix 套接字,ACL 作用域)用于缓存、会话、通知 分发器流
  • 每域名可选的 FastCGI 微缓存 + 手动清除
  • 多语言 UI(默认 en;i18n 框架已就绪)

架构

  • 控制平面: Go 二进制文件 panel-api (Gin) 监听 /run/jabali-panel/api.sock。嵌入 SPA 并从 / 提供服务
  • 数据平面: 以 root 身份运行的 Go 二进制文件 panel-agent,监听 /run/jabali-agent/agent.sock (0660, 组 jabali)。类型化 NDJSON RPC 注册表 — 每个特权操作 (nginx reload, certbot, systemctl, mysql DDL, 文件操作) 都是面板按名称调用的命名处理器。面板本身 不执行 shell 命令
  • 状态平面: MariaDB jabali_panel (单数据库, 单写入者 = panel- api)。协调器每 60 秒读取数据库并收敛主机状态
  • 任务平面: Redis Streams 调度器 (通知, 备份, 邮件 扫描)
  • 前端: React 19 + Ant Design 5 + TanStack Query, 由 Vite 构建, 从 Go 二进制文件的嵌入式文件系统提供服务 — 单一部署单元, 主机上无 Node 运行时
  • Webmail: Bulwark (Next.js JMAP) 位于 /opt/jabali-webmail, 通过 nginx → Unix socket 按域名在 mail.<tenant> 提供服务
  • SSH shell: nspawn 容器 (debian-13-v1 镜像) 用于 SSH 访问 隔离; jabali-isolator 处理容器生命周期
  • 安全: CrowdSec 解析器 + AppSec (nginx-bouncer Lua, WAF) + 每用户出口防火墙 (nftables + cgroupv2-vmap, ADR-0084) + LMD + ClamAV-on-demand + YARA + Tetragon
  • 日志: 通过 slog 输出结构化 JSON; nginx 访问日志馈送 CrowdSec
  • 服务器指标: 实时 /proc 读取, 无 Prometheus exporter 依赖

服务栈 (单节点默认):

  • panel-api (Go, Unix socket, 嵌入式 SPA)
  • panel-agent (Go, Unix socket, root)
  • nginx (在 :8443 上作为 TLS 终结点,用户 vhosts 在 :80/:443, 每域邮件 vhost 在 :443,共享 FastCGI 缓存 keyzone,AppSec bouncer Lua)
  • MariaDB (仅 Unix socket — skip-networking)
  • Redis (Unix socket, 模式 0660, 组 jabali-sockets)
  • PowerDNS authoritative (分端口 :5300, MySQL 后端) + pdns-recursor (回环 :53, 解析器链)
  • Stalwart Mail Server (SMTP / IMAP / 465 / 587 / 993 / JMAP / ManageSieve, LE 证书推送到 Certificate 对象)
  • Bulwark (Next.js JMAP 网页邮件, Unix socket, 按租户提供服务)
  • Kratos (Unix socket 管理 + 公共, 唯一认证源 — M20)
  • CrowdSec (LAPI socket + AppSec :7422 + nginx-bouncer Lua)
  • Restic (加密, 去重, 备份目标)
  • jabali-isolator (nspawn 容器生命周期)
  • systemd-user (作为用户范围定时器的 cron 任务)

需求

  • 全新的 Debian 13 安装(无预装的 Web 或邮件栈)
  • 最低 2 GB 内存,推荐 4 GB — 与 cPanel 相同的指导原则(在 ≤4 GB 的主机上,安装程序会增加交换空间并限制本地 SPA/Go 构建内存,以防止 OOM;在 2 GB 上构建较慢但能完成)
  • 用于面板 + 邮件的域名(如果托管 DNS 则需包含胶水记录)
  • 邮件主机名的 PTR(反向 DNS)
  • 开放端口:22, 80, 443, 8443, 25, 465, 587, 993, 995, 53

安全加固

参见 docs/adr/ 获取完整的架构决策记录 (涵盖所有关键设计决策的 110+ 个 ADR)。要点如下:

环境变量

变量用途默认值
JABALI_HOSTNAME在安装期间覆盖自动检测的面板主机名(auto)
JABALI_PANEL_BIND覆盖 panel-api 监听套接字/run/jabali-panel/api.sock
JABALI_AGENT_SOCKET覆盖 agent RPC 套接字/run/jabali-agent/agent.sock
JABALI_TEST_DATABASE_URL用于集成测试的真实 MariaDB DSN(unset)
JABALI_LOG_LEVELSlog 级别 (debug / info / warn / error)info
TLS_CERT / TLS_KEY更新时从 panel.env 中清理 — nginx 终止(auto-cleaned)

关键安全特性

  • Panel 绝不以 root 身份运行。每个特权操作都通过 agent Unix 套接字作为类型化 RPC 调用进行;agent 通过 SO_PEERCRED 验证调用者
  • Shell 参数按处理器进行验证 + 转义(无 sh -c $arg 模式);域名根据 validateDomainNameForShell 进行验证
  • DKIM 私钥 + SSO 令牌 + 邮箱明文在静态时 通过 AES-GCM 使用每主机 SSO 密钥进行加密(/etc/jabali-panel/sso.key
  • 一次性管理员 SSO 令牌为 256 位,单次使用,5 分钟 TTL, 由 systemd 定时器每 30 秒清理一次(ADR-0040 webmail SSO 文件模式)
  • Stalwart Certificate 对象从 LE 续期的证书在每次 certbot deploy-hook 时推送 — IMAPS / 465 / 587 始终提供浏览器信任的 证书(无 rcgen 自签名回退)
  • CrowdSec AppSec WAF + 每用户出口防火墙(cgroupv2-vmap, ADR-0084)
  • 自愈协调器 — 磁盘上的配置漂移在下一个 tick 时回滚;操作员对 nginx vhosts 的手动编辑按设计丢失
  • CSP, HSTS, SameSite cookies, X-Forwarded-Proto 由 nginx 处理
  • 迁移仅涉及模式(没有由 SQL 填充的应用数据表)
  • 每次管理员写入 + 模拟开始/停止时记录审计日志
  • Pre-commit + CI 门禁:go vet, go test -race ./..., npx tsc -b, bash -n install.sh, Playwright E2E, AppSec geoblock 黄金测试

更新

更新面板(代码、依赖项、数据库迁移、基础设施):

jabali update

此操作会拉取最新代码,重新构建面板 + 代理二进制文件,重新构建 SPA,应用 golang-migrate 迁移,同步 nginx vhosts + systemd 单元 + PHP 配置 + CrowdSec acquis,并重启面板 + 代理。 在运行中的服务器上执行是安全的——协调器能够容忍短暂的面板 重启,并在下一个周期收敛状态。

自愈损坏的安装(7 个检测器,--diagnose 默认, --auto 安全,--all --yes 破坏性):

jabali repair --diagnose       # report only
jabali repair --auto           # fix safe issues
jabali repair --all --yes      # destructive recovery

CLI

jabali 命令采用名词:动词模式。所有命令均支持 --json 以获取机器可读的输出,以及 --yes 以跳过确认。

jabali user        list|create|delete|show|password|suspend|unsuspend|admin
jabali domain      list|create|delete|show|enable|disable|email-enable|email-disable
jabali db          list|create|delete|users|user-create|user-delete|tune|root-password
jabali mailbox     list|create|delete|passwd|set-quota|forwarder|autoresponder|shares
jabali ssl         list|status|check|issue|renew|panel|panel-issue
jabali dns         list|records|add|delete-record|sync|dnssec-enable|dnssec-disable
jabali backup      list|create|delete|info|restore|password|destinations|schedules
jabali cron        list|create|delete|toggle|run
jabali php         list|install|uninstall|default|extensions
jabali service     list|status|start|stop|restart|enable|disable
jabali system      info|status|disk|memory|hostname|kill
jabali wp          list|install|delete|update|scan|import
jabali agent       ping|status|restart|log
jabali cpanel      analyze|restore|fix-permissions
jabali login       token [--user=] [--ttl=15] [--panel=]
jabali logs        share [--raw] [--ttl=86400]
jabali ufw         migrate-ip-bans            # M43 CrowdSec single IP-trust
jabali repair      --diagnose|--auto|--all
jabali panel-primary set|show                 # ADR-0048 primary mail domain
jabali nspawn      list|build|update|delete
jabali malware-purge                          # M33 retention sweep
jabali update      [--force]

参见 docs/CONVENTIONS.md 了解全仓库范围的 模式(路由族、SearchableTable、Drawer-for-CRUD、列表信封、 速率限制)以及 docs/adr/ 了解所有关键决策。

开发

make build              # compile panel-api + panel-agent
make run                # run panel-api (dev, embedded SPA)
make test               # all Go tests, race detector on
make test-coverage      # coverage report (internal packages)
make test-integration   # needs JABALI_TEST_DATABASE_URL + real MariaDB
make coverage-check     # fail if combined coverage < 80%
make lint               # golangci-lint v2
make fmt                # go fmt + vet

前端开发(来自 panel-ui/):

npm install
npm run dev             # Vite on http://localhost:5173
                        # proxies /api and /health to 127.0.0.1:8443

E2E(来自 panel-ui/):

npm run test:e2e        # Playwright against the dev server

参见 docs/CONTRIBUTING.md 了解完整的特性 开发工作流(研究 → 计划 → TDD → 审查 → 发布)。

版本控制

版本字符串位于 VERSION(在构建时读取并通过 /health 暴露)。当安装程序为全新安装克隆仓库时, 它会读取 VERSION 以显示已安装的版本。始终在包含相应 install.sh 更改的 同一提交中更新 VERSION —— 偏差 会表现为页脚和安装程序横幅不匹配。

翻译

Translation status

面板 UI 的翻译托管在我们自建的 Weblate 上, 地址为 https://translate.jabali-panel.com/。英语是源语言;所有 其他语言版本均由那里的翻译者编写,并合并回此仓库。

已发布的语言:英语(源语言)、阿拉伯语、简体中文、法语、德语、 希伯来语、意大利语、日语、巴西葡萄牙语、俄语、西班牙语、土耳其语和 乌克兰语。阿拉伯语和希伯来语从右向左显示。

致翻译者

translate.jabali-panel.com 注册并开始翻译——无需编程、无需 git、无需本地环境配置。请先阅读该项目的 翻译说明;简而言之:

  • 不要翻译产品或协议名称(nginxMariaDBStalwartPHP-FPMDNSSSL、...)或 backticks 中的任何内容。
  • 保持占位符(如 {{count}})原样不变。你可以为了适应语序而移动 它们,但绝不能重命名或删除。
  • 保持字符串简短。大多数是按钮、菜单项、表头和表单 标签,过长的翻译会破坏布局。
  • 希伯来语和阿拉伯语从右向左显示。如果界面看起来损坏,请报告问题, 而不是通过缩短文本来规避。
  • 如果某个英文字符串含糊不清或错误,请添加评论而不是 猜测——它会在源端一次性修复,适用于所有语言。

缺少你的语言?请提交一个 issue,我们会添加它。

致开发者

  • panel-ui/src/locales/en/common.json 是唯一手动编辑的目录。 Weblate 拥有所有其他语言文件;在那里的手动编辑将被覆盖。
  • 面向用户的文本通过 t("some.key")react-i18next)处理,绝不使用 硬编码的字面量。在引入该键的同一提交中,将键及其英文文本添加到 en/common.json
  • panel-ui/src/i18n.ts 包含语言列表以及 AntD 和 dayjs 语言 映射和 RTL 集合。添加一种语言意味着需要修改这三处。
  • 尚未翻译的键会回退到英文源文本,因此部分 翻译的语言环境永远不会渲染出空白标签。

仓库布局

jabali-panel/
├── panel-api/          # Go HTTP server (Gin) + reconciler + agent RPC client
│   ├── cmd/server/     # main entry
│   ├── internal/       # api/, auth/, repository/, reconciler/, config/, ...
│   └── migrations/     # golang-migrate SQL (000xxx_*.up/.down.sql)
├── panel-agent/        # Go binary running as root; typed NDJSON RPC handlers
│   ├── cmd/jabali-agent/
│   └── internal/commands/
├── panel-ui/           # React SPA (AntD + TanStack Query)
│   ├── src/            # shells/, components/, theme/, pages/, ...
│   └── public/
├── agentwire/          # NDJSON RPC types shared by panel-api + panel-agent
├── internal/           # shared Go libs (cronvalidate, dbtuning, phpext, ...)
├── install/            # install.sh assets (nginx tmpl, stalwart plan,
│                       # letsencrypt deploy hooks, bulwark env, ...)
├── docs/               # CONVENTIONS, BLUEPRINT, adr/, runbooks/, KNOWN_ISSUES
├── plans/              # per-milestone implementation blueprints
├── .github/workflows/  # CI (Go + vitest + E2E)
├── install.sh          # single-supported install path (curl | sudo bash)
├── config.example.toml # reference config (copied to /etc/jabali-panel/)
├── Makefile            # build / test / lint targets
└── go.mod              # Go workspace root

许可证

AGPL-3.0 — 参见 LICENSE.

邮件子域名

在浏览器中访问 mail.<your-domain> 会通过每域名的 nginx vhost 路由到 webmail (Bulwark)。该 vhost 安装了一个 nginx sub_filter, 它会将面板主机名重写为 Bulwark 的 /api/config 和 Stalwart 的 /.well-known/jmap 响应中请求的 $host,从而确保 SPA 在 mail.<tenant> 上保持同源,且 Stalwart 的 JMAP Session URL 不会泄露面板主机名。

autodiscover / autoconfig 路径被排除,以便邮件客户端 自动发现(Thunderbird、Outlook)继续正常工作。

文档

参见 docs/ 目录以获取详细指南:

  • Conventions — 仓库范围内的模式(路由族、 SearchableTable、用于创建+编辑的 Drawer、图标 shim、列表信封、速率 限制)+ 以惨痛教训学到的反模式
  • Blueprint — 完整功能地图 + 里程碑路线图
  • ADRs — 所有关键的架构决策(110+)
  • Plans — 每个里程碑的实现蓝图
  • Runbooks — SSL、邮件、M16 回滚、 M22 SSO 重构、M27 CrowdSec 扩展、M30/M30.1 备份的运维指南
  • Known Issues — 注意事项 + 变通方案
  • Contributing — 功能开发工作流
  • Translations — Weblate 实例;英文 是源目录(panel-ui/src/locales/en/common.json
  • Environment — 完整的环境变量参考