ConvertX 命令运维:服务管理、格式转换与备份恢复

ConvertX v0.19.0 运维实战:systemctl/journalctl 服务管理、sqlite3 巡检、五大后端 CLI 直测(ffmpeg/pandoc/calibre/libreoffice/imagemagick)、curl 全流程转换与下载、在线备份与库丢失恢复演练,含 SQLite 静默重建排障实录。

ConvertX文件转换终端工具2026/10/28

ConvertX 命令运维:服务管理、格式转换与备份恢复

实测基线:ConvertX v0.19.0 + Ubuntu 22.04.5 LTS + systemd,2026-10-28 真机逐条执行。示例账号 admin@example.com / q1w2e3r4。前置阅读:《ConvertX 安装:Ubuntu 22.04 源码直装与 systemd 服务化》、《ConvertX 配置:环境变量全参数详解与逐项生效验证》。

ConvertX 是 Web 服务,自身不带 CLI 子命令;运维工作由三部分构成:systemd 服务管理、各转换后端的命令行直用(它们本身就是标准 CLI 工具),以及基于"SQLite 单库 + 单数据目录"的备份恢复。本文按日常运维动线组织,全部命令与回显来自真机。

一、服务管理(systemd)

1.1 状态、启停与自启

systemctl status convertx --no-pager -l | head -10
● convertx.service - ConvertX - Self-hosted online file converter
     Loaded: loaded (/etc/systemd/system/convertx.service; enabled; vendor preset: enabled)
     Active: active (running) since Wed 2026-10-28 04:32:46 UTC; 6s ago
   Main PID: 10426 (bun)
      Tasks: 24 (limit: 2932)
     Memory: 54.8M
        CPU: 351ms
     CGroup: /system.slice/convertx.service
             └─10426 /usr/local/bin/bun run dist/src/index.js

日常启停与重载配置:

systemctl start convertx      # 启动
systemctl stop convertx       # 停止(转换中的任务会被中断)
systemctl restart convertx    # 重启,环境变量/代码变更后必做
systemctl enable convertx     # 开机自启
systemctl disable convertx    # 取消自启

1.2 日志查看(journalctl)

journalctl -u convertx --no-pager -n 5
Oct 28 04:32:46 convertx systemd[1]: Started ConvertX - Self-hosted online file converter.
Oct 28 04:32:46 convertx bun[10426]: ConvertX v0.19.0
Oct 28 04:32:46 convertx bun[10426]: 🦊 Elysia is running at http://localhost:8149
Oct 28 04:34:51 convertx bun[10426]: jobId set to: 1

三条最常用的日志姿势:

journalctl -u convertx -f                              # 实时跟随
journalctl -u convertx --since '10 minutes ago'        # 最近 10 分钟
journalctl -u convertx --no-pager | grep -i failed     # 检索失败记录

排障时重点关注两类行:Failed to convert ...(转换失败,附引擎原始 stderr)与 404: GET ...(路由/子路径错误)。追踪转换过程时,Calibre 等引擎会把进度输出到日志(如 "67% Running EPUB Output plugin"),日志量会随转换任务明显上涨,可配合 SystemMaxUse 限流 journal 磁盘占用。

1.3 探活

curl -s http://127.0.0.1:8149/healthcheck
{"status":"ok"}

该端点免认证,适合接入拨测/监控。注意它只反映进程与 HTTP 栈健康,不校验数据库——数据层故障要靠登录动作或 sqlite3 巡检暴露(见 6.2 节实录)。

二、数据结构巡检(sqlite3)

全部状态在 /opt/convertx/data/mydb.sqlite(WAL 模式,旁边有 -wal/-shm 文件):

sqlite3 /opt/convertx/data/mydb.sqlite '.tables'
jobs  users
sqlite3 /opt/convertx/data/mydb.sqlite \
  'SELECT id, email FROM users; SELECT COUNT(*) AS jobs FROM jobs;'
1|admin@example.com
24

巡检常用:按用户统计任务、找出大输出目录:

du -sh /opt/convertx/data/output/*/* 2>/dev/null | sort -rh | head -5

三、转换后端命令行直用

ConvertX 的每个引擎都是独立 CLI,绕开 Web 界面直接调用它们做批量/脚本化转换,与界面产物一致:

# 图像:ImageMagick 查看与转换
identify /tmp/test.png
/tmp/test.png PNG 200x100 200x100+0+0 16-bit sRGB 954B 0.000u 0:00.000
# 视频:FFmpeg 截帧动图
ffmpeg -y -loglevel error -i /tmp/clip.mp4 -t 1 -vf fps=2,scale=80:-1 /tmp/cli.gif
ls -la /tmp/cli.gif
-rw-r--r-- 1 root root 3103 Oct 28 04:49 /tmp/cli.gif
# 文档:Pandoc Markdown 转 HTML / PDF(转 PDF 需 XeLaTeX)
pandoc /tmp/doc.md -o /tmp/cli.html
head -c 120 /tmp/cli.html; echo
<h1 id="hello-convertx">Hello ConvertX</h1>
<p>This is a <strong>markdown</strong> test file.</p>
<ul>
<li>item 1</li>
# 电子书:Calibre txt 转 epub
ebook-convert /tmp/book.txt /tmp/cli.epub 2>&1 | tail -1
Output saved to   /tmp/cli.epub
# 办公文档:LibreOffice 无头模式转 PDF
soffice --headless --convert-to pdf --outdir /tmp /tmp/book.txt 2>&1 | tail -1
ls -la /tmp/book.pdf
convert /tmp/book.txt -> /tmp/book.pdf using filter : writer_pdf_Export
-rw-r--r-- 1 root root 9564 Oct 28 04:49 /tmp/book.pdf

直装环境注意:ConvertX 的 ImageMagick 适配层调用 magick 命令(Ubuntu 22.04 需 ln -sf /usr/bin/convert /usr/local/bin/magick 补齐),人工直用时用 convert 即可;Pandoc 转 PDF 硬编码 --pdf-engine=xelatex。两条排障的完整实录见安装篇第六节。

四、Web 转换接口的命令行调用(curl)

Web 界面的每个动作都有等价 curl 写法,适合自动化集成。全流程四步:登录 → 建任务 → 上传 → 转换,最后下载。

4.1 登录并建立任务上下文

rm -f /tmp/cx.jar
curl -s -c /tmp/cx.jar -o /dev/null -X POST \
  -d 'email=admin@example.com&password=q1w2e3r4' \
  http://127.0.0.1:8149/login
curl -s -b /tmp/cx.jar -c /tmp/cx.jar -o /dev/null \
  -w 'home: %{http_code}\n' http://127.0.0.1:8149/
home: 200

第二步请求首页会在 Cookie 中签发 jobId(服务端同步在 jobs 表落一条记录),后续上传/转换都挂在这个任务下。

4.2 上传与触发转换

curl -s -b /tmp/cx.jar -c /tmp/cx.jar -o /dev/null -w 'upload: %{http_code}\n' \
  -F 'file=@/tmp/test.png' http://127.0.0.1:8149/upload
curl -s -b /tmp/cx.jar -c /tmp/cx.jar -o /dev/null \
  -w 'convert: %{http_code} -> %{redirect_url}\n' \
  -d 'convert_to=jpg,imagemagick' \
  --data-urlencode 'file_names=["test.png"]' \
  http://127.0.0.1:8149/convert
upload: 200
convert: 302 -> http://127.0.0.1:8149/results/3

convert_to 取值格式为"目标格式,引擎名"(引擎名对照:imagemagick/graphicsmagick/ffmpeg/pandoc/calibre/libreoffice/vips 等,源码 converters 注册表里为小写键名)。

两个实测踩坑,值得记住:

  1. file_names 必须走 urlencoded 表单传 JSON 字符串。若用 multipart(-F)提交,Web 框架会把 [ 开头的值解析成数组,服务端再 JSON.parse 时直接 500,报 JSON Parse error: Unexpected identifier "test";
  2. curl 的 -d 与 -F 不能混用于同一请求(curl: (26) ... 类错误),convert_to 与 file_names 要么都用 -d/--data-urlencode,要么都用 -F。

4.3 结果下载与整包归档

单文件下载(路径含用户 ID / 任务 ID / 文件名):

curl -s -b /tmp/cx.jar -o /tmp/dl.jpg \
  -w 'download: %{http_code} type=%{content_type} size=%{size_download}\n' \
  http://127.0.0.1:8149/download/1/3/test.jpg
python3 -c "print(open('/tmp/dl.jpg','rb').read(3))"
download: 200 type=image/jpeg size=1513
b'\xff\xd8\xff'

(文件头 \xff\xd8\xff 即 JPEG 魔数,验证内容完整。)

整任务打包(tar 归档):

curl -s -b /tmp/cx.jar -o /tmp/dl.tar \
  -w 'archive: %{http_code} size=%{size_download}\n' \
  http://127.0.0.1:8149/archive/6
tar -tf /tmp/dl.tar
archive: 200 size=132608
./
./book.epub

五、备份

状态就三样:SQLite 库、上传目录、输出目录,全部在 /opt/convertx/data/ 下。

5.1 在线备份(不停止服务)

sqlite3 /opt/convertx/data/mydb.sqlite ".backup '/tmp/mydb-backup.sqlite'"
tar -czf /tmp/convertx-data-backup.tar.gz -C /opt/convertx data
ls -la /tmp/mydb-backup.sqlite /tmp/convertx-data-backup.tar.gz
-rw-r--r-- 1 root root 20480 Oct 28 04:49 /tmp/mydb-backup.sqlite
-rw-r--r-- 1 root root 33465 Oct 28 04:49 /tmp/convertx-data-backup.tar.gz

sqlite3 .backup 在线快照能保证库一致性(直接 cp 正在写的库可能截断 WAL 事务);tar 包则把输出/上传目录一并带上。备份校验:

sqlite3 /tmp/mydb-backup.sqlite 'SELECT COUNT(*) FROM users; SELECT COUNT(*) FROM jobs;'
1
24

5.2 定时备份(systemd timer)

/etc/systemd/system/convertx-backup.service:

[Unit]
Description=ConvertX daily backup

[Service]
Type=oneshot
ExecStart=/bin/sh -c 'sqlite3 /opt/convertx/data/mydb.sqlite ".backup /var/backups/convertx-mydb.sqlite" && tar -czf /var/backups/convertx-data-$(date +%%F).tar.gz -C /opt/convertx data'

/etc/systemd/system/convertx-backup.timer:

[Unit]
Description=Run convertx backup daily

[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true

[Install]
WantedBy=timers.target
systemctl daemon-reload && systemctl enable --now convertx-backup.timer
systemctl list-timers convertx-backup.timer --no-pager | head -3

六、恢复演练

6.1 故障注入:库文件丢失

停服后把主库文件移走,再启动,观察服务行为:

systemctl stop convertx
mv /opt/convertx/data/mydb.sqlite /tmp/broken.sqlite
systemctl start convertx && sleep 2
systemctl is-active convertx
curl -s -m 3 -o /dev/null -w 'healthcheck: %{http_code}\n' http://127.0.0.1:8149/healthcheck
active
healthcheck: 200

重要发现:库文件丢失后服务照常 active、healthcheck 照常 200——运行时会静默新建一个空库。这意味着健康检查探不到数据层故障,账号与历史"凭空消失"的唯一线索是用户报障。所以数据库巡检必须显式做:

sqlite3 /opt/convertx/data/mydb.sqlite 'SELECT COUNT(*) FROM users;'

返回 0 即为"库被重建"事故,应立即停服恢复备份。

6.2 恢复流程

systemctl stop convertx
cp /tmp/mydb-backup.sqlite /opt/convertx/data/mydb.sqlite
tar -xzf /tmp/convertx-data-backup.tar.gz -C /opt/convertx
chown -R convertx:convertx /opt/convertx/data
systemctl start convertx && sleep 2
systemctl is-active convertx
curl -s -m 3 -w '\nhealthcheck: %{http_code}\n' http://127.0.0.1:8149/healthcheck
active
{"status":"ok"}
healthcheck: 200

恢复后用既有账号验证登录态(账号与历史随备份回来):

rm -f /tmp/r.jar
curl -s -c /tmp/r.jar -o /dev/null -X POST \
  -d 'email=admin@example.com&password=q1w2e3r4' \
  http://127.0.0.1:8149/login
curl -s -b /tmp/r.jar -o /dev/null \
  -w 'login+home after restore: %{http_code}\n' http://127.0.0.1:8149/
login+home after restore: 200

6.3 恢复检查清单

  1. systemctl is-active convertx 为 active;
  2. healthcheck 返回 ok,且 sqlite3 ... 'SELECT COUNT(*) FROM users' 与备份一致;
  3. 既有账号可登录,历史页任务列表完整;
  4. 任取一个历史任务下载产物,核对文件魔数与大小。

七、日常巡检命令速查

动线命令
服务健康systemctl is-active convertx && curl -s http://127.0.0.1:8149/healthcheck
失败转换排查journalctl -u convertx --no-pager | grep -i failed | tail
数据层巡检sqlite3 /opt/convertx/data/mydb.sqlite 'SELECT COUNT(*) FROM users;'
磁盘占用du -sh /opt/convertx/data/*
转换产物直查find /opt/convertx/data/output -type f -mtime -1
配置核对systemctl show convertx -p Environment

八、小结

ConvertX 的运维面很窄:一个 systemd 单元、一个 SQLite 库、两个文件目录。把"healthcheck 不查库"与"库文件可被静默重建"这两个特性纳入监控设计(拨测加登录动作或库行数巡检),再把 .backup + tar 的组合纳入 timer,就构成了它完整的运维闭环。产品定位与 22 个转换引擎的全景对照,见《ConvertX 认知选型:自托管万能文件转换器的定位、引擎与替代方案》。