Mafl 0.15.4 日常运维手册

Mafl v0.15.4 日常运维手册(D1 篇型按 CLI 面窄调整):巡检四件套与健康检查、config.yml 备份恢复实测、/api/health 外部监控接入、单实例资源占用实测(26MiB)、标签升级与回滚全链路、五大高频故障排查手册(500 无配置/tags 崩溃/热更新失效/状态灯误报/图标 404)。

MaflMaflDocker Compose运维自动化面板2026/11/03

Mafl 0.15.4 日常运维手册

目标:覆盖 Mafl v0.15.4 面板上线后的日常运维主线——巡检、备份恢复、监控告警、资源调整、升级回滚与故障排查,全部命令与回显已在 Docker Engine 29.9.2(Compose v5.6.1)环境实测通过。篇型说明:Mafl 没有业务 CLI(实例进程即 node /app/server/index.mjs,无管理命令、无子命令、无配置文件生成器),按 SKILL 决策树「有 CLI 才开 D1」调整为 D2 日常运维手册,运维命令面收敛为「Compose 生命周期命令 + HTTP API + config.yml 文件操作」三类,在第二章工具总览逐项实测。

一、环境信息

  • 操作系统:Ubuntu 22.04(x86_64),Docker Engine 29.9.2(Compose v5.6.1)
  • Mafl 版本:v0.15.4(镜像 hywax/mafl:v0.15.4)
  • 编排目录:/opt/mafl/(示例路径),Compose 项目名 mafl-v0154-stack
  • 访问形态:http://127.0.0.1:8132/(宿主 8132 → 实例 3000)
  • 配置与数据:/opt/mafl/mafl/config.yml(唯一状态文件,实例内 /app/data/config.yml)
  • 健康检查:镜像内置,每 10 秒 GET localhost:3000/api/health

二、运维工具总览

工具面命令/端点用途
Compose 生命周期docker compose ps / logs / restart / up -d / down启停、状态、升级
HTTP 健康端点GET /api/health存活探测(200 空响应体)
HTTP 配置回读GET /api/settings生效配置核对 + error 字段排障
HTTP 服务探测GET /api/services/base?id=<uuid>状态灯数据独立核对
文件操作cp / vi /opt/mafl/mafl/config.yml配置备份与修改
WebSocketws://<host>:3000/api/websocket页面在线时配置热更新通道

💡 说明:/api/settings 与 /api/services/* 无鉴权——面板本体无认证体系,这些端点随面板一起暴露,公网部署必须在反代层封禁 /api/* 或整体加认证(见部署篇 FAQ 5)。

三、日常巡检

巡检目标:进程活着、配置无错、端口可达。四件套逐条实测:

3.1 实例状态与健康

cd /opt/mafl && docker compose ps
NAME             IMAGE                COMMAND                  SERVICE   CREATED          STATUS                    PORTS
mafl-v0154-web   hywax/mafl:v0.15.4   "docker-entrypoint.s…"   mafl      37 seconds ago   Up 17 seconds (healthy)   0.0.0.0:8132->3000/tcp, [::]:8132->3000/tcp

STATUS 中 (healthy) 即镜像内置健康检查通过(间隔 10 秒、超时 5 秒、启动宽限 10 秒,实测健康检查定义:["CMD","node","/app/extra/healthcheck.mjs"])。

3.2 存活端点

curl -s http://127.0.0.1:8132/api/health -o /dev/null -w "health HTTP %{http_code}\n"
health HTTP 200

3.3 配置加载状态(关键巡检项)

Mafl 配置坏掉时进程不退出、健康检查照样过,只有 /api/settings 的 error 字段能暴露问题:

curl -s http://127.0.0.1:8132/api/settings | python3 -c "import json,sys; d=json.load(sys.stdin); print('config error:', d.get('error','none'))"
config error: none

非 none 时(实测会输出如 config error: tags.reduce is not a function)立即按第八章排障。

3.4 启动日志基线

docker compose logs --tail=5
mafl-v0154-web  | Listening on http://[::]:3000
mafl-v0154-web  | Set "main" config

健康基线就这两行:Listening = 端口就绪,Set "main" config = 配置加载成功;出现 Error:/TypeError: 行即异常。

四、备份与恢复

Mafl 无数据库,备份 = 拷走 config.yml 一个文件。

4.1 备份

cp /opt/mafl/mafl/config.yml /opt/mafl/mafl/config.yml.bak-$(date +%Y%m%d%H%M%S)
ls -la /opt/mafl/mafl/
total 16
drwxr-xr-x 2 root root 4096 Nov  3 02:16 .
drwxr-xr-x 4 root root 4096 Nov  3 02:15 ..
-rw-r--r-- 1 root root 1189 Nov  3 02:11 config.yml
-rw-r--r-- 1 root root 1189 Nov  3 02:16 config.yml.bak-20261103021605

4.2 误改配置后的恢复

实测故障注入:把 title 改成错误值并重启后面板渲染异常配置:

sed -i 's/title: Quzuo Home Page/title: Broken Temp/' /opt/mafl/mafl/config.yml
docker compose restart
curl -s http://127.0.0.1:8132/ | grep -oE "<title>[^<]*</title>"
<title>Broken Temp</title>

用备份文件覆盖恢复:

cp /opt/mafl/mafl/config.yml.bak-20261103021605 /opt/mafl/mafl/config.yml
docker compose restart
curl -s http://127.0.0.1:8132/ | grep -oE "<title>[^<]*</title>"
<title>Quzuo Home Page</title>

4.3 全量重建

配置即全部状态,换机/重建只需带走 config.yml:

cd /opt/mafl && docker compose down
docker compose up -d
 Container mafl-v0154-web Stopping 
 Container mafl-v0154-web Stopped 
 Container mafl-v0154-web Removing 
 Container mafl-v0154-web Removed 
 Network mafl-v0154-stack_mafl-net Removing 
 Network mafl-v0154-stack_mafl-net Removed 
 Network mafl-v0154-stack_mafl-net Creating 
 Network mafl-v0154-stack_mafl-net Created 
 Container mafl-v0154-web Creating 
 Container mafl-v0154-web Created 
 Container mafl-v0154-web Starting 
 Container mafl-v0154-web Started

⚠️ 注意:docker compose down 不删除 bind mount 的宿主文件(config.yml 安全),但若误用 down -v 且改用了命名卷方案会丢配置——推荐保持 bind mount 形态。

五、监控与告警

  1. 存活监控:外部监控系统直接探 GET /api/health(200 即存活,空响应体)。cron 粗筛示例(非 200 输出告警行):
* * * * * curl -s -o /dev/null -w "%{http_code}" --max-time 5 http://127.0.0.1:8132/api/health | grep -q '^200$' || logger "mafl health fail"
  1. 配置错误监控:3.3 的 error 字段检查可同样入 cron——健康但配置坏是 Mafl 特有的监控盲区,必须单独覆盖;
  2. 面板内状态灯:仅作人眼粗筛(TCP 探测精度边界见配置篇第八章),不要把状态灯当作告警数据源;
  3. 版本提示:checkUpdates: true 时页面底部横幅提示新版本,属信息展示、不产生日志与外呼告警,生产建议关闭(配置篇 5.4)。

六、扩缩容与资源调整

架构定性:Mafl 为单进程无状态服务(PID 1 即 node /app/server/index.mjs,实测进程表),没有集群模式;「扩容」只有两种含义——

  1. 多实例并存(不同端口/不同配置文件服务不同人群),各实例完全独立、互不感知;
  2. 资源限额调整:实测空载面板仅占 26.75MiB 内存 / 11 进程:
docker stats --no-stream mafl-v0154-web
CONTAINER ID   NAME             CPU %     MEM USAGE / LIMIT     MEM %     NET I/O           BLOCK I/O   PIDS
7bcd109b63da   mafl-v0154-web   5.34%     26.75MiB / 15.57GiB   0.17%     11.6kB / 2.83MB   0B / 0B     11
docker exec mafl-v0154-web ps aux
PID   USER     TIME  COMMAND
    1 root      0:00 node /app/server/index.mjs

给 compose 加资源护栏(128MB 上限对面板绰绰有余,防 Node 异常膨胀):

services:
  mafl:
    deploy:
      resources:
        limits:
          memory: 128M

七、升级与回滚

版本基线:v0.15.4(2024-07-13)为官方最新 Release(2026-11-02 实查 releases.atom),升级操作以「未来新版本」与「回滚到 v0.15.3」为例实测。

7.1 升级

sed -i 's/image: hywax\/mafl:v0.15.3/image: hywax\/mafl:v0.15.4/' /opt/mafl/docker-compose.yml
docker compose up -d
 Container mafl-v0154-web Recreate 
 Container mafl-v0154-web Recreated 
 Container mafl-v0154-web Starting 
 Container mafl-v0154-web Started
docker compose ps --format '{{.Name}} {{.Image}} {{.Status}}'
mafl-v0154-web hywax/mafl:v0.15.4 Up 4 seconds (health: starting)
curl -s http://127.0.0.1:8132/ | grep -oE "<title>[^<]*</title>"
<title>Quzuo Home Page</title>

配置目录跨版本原样复用(v0.15.3→v0.15.4 实测无损),升级后必做:3.3 配置错误检查 + 状态灯抽查。

7.2 回滚(实测降级链路)

sed -i 's/image: hywax\/mafl:v0.15.4/image: hywax\/mafl:v0.15.3/' /opt/mafl/docker-compose.yml
docker compose up -d
 Container mafl-v0154-web Recreate 
 Container mafl-v0154-web Recreated 
 Container mafl-v0154-web Starting 
 Container mafl-v0154-web Started
docker compose ps --format '{{.Name}} {{.Image}} {{.Status}}'
mafl-v0154-web hywax/mafl:v0.15.3 Up 4 seconds (health: starting)
curl -s -o /dev/null -w "HTTP %{http_code}\n" http://127.0.0.1:8132/
HTTP 200

回滚秒级完成、无数据迁移。若新版本引入了旧版不认识的配置字段(如 v0.14+ 的 layout),回滚前先把 config.yml 恢复到升级前备份(第四章)。

7.3 自动化升级(官方建议渠道)

官方文档推荐 watchtower 托管自动更新;引入前注意:Mafl 更新频率极低(28 个月无 Release),自动化的收益有限、回滚成本反而升高,建议手动标签管理(7.1/7.2)。

八、故障排查手册

8.1 全站 500 但健康检查通过

现象:docker compose ps 显示 Up (healthy),curl 页面返回 500。 定位:日志出现 Error: Config not found(实测完整堆栈见部署篇 4.2)→ config.yml 未挂载到位。 解决:核对 compose volumes 映射与文件存在性:docker compose exec mafl ls /app/data。

8.2 启动即 TypeError 崩溃日志

现象:日志 TypeError: tags.reduce is not a function。 定位:config.yml 的 tags 写成了字符串/映射而非数组(实测 tags: work 复现;/api/settings 返回缺省配置 + error 字段)。 解决:改为数组形态后 docker compose restart:

tags:
  - name: Infra
    color: green

8.3 配置改了不生效

现象:编辑 config.yml 保存后页面不变、日志无 Set "main" config。 定位:热更新监听仅在浏览器页面在线(WebSocket peer 存在)时激活——实测无 peer 时改动 10 秒不生效;有 peer 时秒级生效并推送 {"event":"config:update"}(完整链路实测见配置篇 3.3)。 解决:无人在线的场景统一走 docker compose restart;批量运维可写「改配置 → restart → 3.3 校验」三步脚本。

8.4 状态灯恒离线(HTTPS 服务)

现象:服务明明存活,卡片状态灯显示离线。 定位:TCP 探测对不带端口的链接默认打 80 端口(配置篇第八章),https://host/ 探 80 不通。 解决:link 显式写端口:https://host:8443/;实测带端口链接探测响应 {"ping":{"status":true,...}}。

8.5 本地图标不显示(挂载 404)

现象:icon.url 指向挂载的 /app/public/icons/xxx.svg,浏览器 404。 定位:v0.15.4 实测 Nitro 静态路由表构建期固化,运行时新增文件不注册路由(实测回显与机制见配置篇 9.4)。 解决:改用 Iconify 图标名 / Emoji / 外部 URL;坚持本地图标则把文件放进自建镜像层重新构建。

8.6 卡片莫名空白

现象:某卡片渲染为无标题空块,无任何报错。 定位:字段名拼写错误被静默透传(实测 titel: typo 不报错,配置篇 9.3)。 解决:curl -s http://127.0.0.1:8132/api/settings 回读该卡片 JSON 与文件比对,修正拼写后重启。

九、常见问题(FAQ)

Q1: 面板被公网扫到怎么办? A: Mafl 无认证且 /api/settings 会泄露服务清单(内网地址、服务名)。公网暴露必须:反代 + Basic Auth(账号 root / 密码 q1w2e3r4 示例见部署篇 FAQ 5)+ 对公网路径封禁 /api/settings、/api/services/*。

Q2: checkUpdates 横幅出现新版本,能一键升级吗? A: 不能,横幅仅提示;按 7.1 手动换标签。

Q3: Node 进程内存持续增长? A: 实测空载 26.75MiB 稳定;若异常膨胀先查状态检查 interval 是否被调得过小(官方警告:服务多时高频 TCP 探测压垮系统),并给实例加 128MB 限额(第六章)观察是否触发重启自愈。

Q4: 能否用 docker compose restart 代替改配置后的重载? A: 可以且推荐——restart 不重建实例、秒级完成,日志重现 Set "main" config 即生效(实测见 8.3)。

十、参考链接

Mafl 0.15.4 日常运维手册 - Quzuo