Kiwix 3.8.2 启动旗标与库管理参数详解
kiwix-serve 3.8.2 全部启动旗标与 kiwix-manage 库管理参数逐项实测:默认值与逐字回显、目录参数等与官方文档不一致点的实证、library.xml 字段级结构与相对路径解析规则,以及三档生产配置模板。
Kiwix 3.8.2 启动旗标与库管理参数详解
目标:把 kiwix-serve 3.8.2 的全部启动旗标与 kiwix-manage 库管理参数逐一讲透——每个参数给默认值、实测行为与逐字回显,并给出 library.xml 库文件的字段级结构与三条可直接落地的生产配置模板。全部结论来自同一版本镜像(
ghcr.io/kiwix/kiwix-serve:3.8.2)在真实服务器上的多实例实测。
一、环境信息
本文实测环境与依据(实测日期 2026-11-01):
- 操作系统:Ubuntu 26.04.1 LTS(x86_64),Docker 29.9.2 / Docker Compose v5.6.1
- 软件版本:kiwix-tools 3.8.2(2026-03-02 发布),镜像
ghcr.io/kiwix/kiwix-serve:3.8.2 - 实测载体:同一镜像跑两处——Compose 常驻栈(容器
kiwix-3-8-2-web,端口 8137,部署过程见本专栏 《Kiwix 3.8.2 Docker Compose 部署指南》)与探针容器(kiwix-3-8-2-probe,在容器内手工逐旗标拉起临时实例验证);临时实例监听 8081~8095 端口 - 测试内容:与部署篇相同的两个官方 ZIM——
wikibooks_zh_all_nopic_2026-10.zim(93 MB,8510 条目)与wikibooks_ur_all_nopic_2026-10.zim(3.0 MB,568 条目) - 参数权威口径:
kiwix-serve --help、kiwix-manage(无参数时打印用法)与官方文档 kiwix-tools.readthedocs.io,三者交叉核对;凡与官方文档不一致处均在文中显式标注
kiwix-serve --version 完整回显(版本线与依赖库一目了然):
$ kiwix-serve --version
kiwix-tools 3.8.2
libkiwix 14.2.0
+ libzim 9.5.0
+ libxapian 1.4.23
+ libcurl 8.4.0
+ libmicrohttpd 0.9.76
+ libz 1.3.1
+ libicu 73.2.0
+ libpugixml 1.15.0
libzim 9.5.0
+ libzstd 1.5.7
+ liblzma 5.2.6
+ libxapian 1.4.23
+ libicu 73.2.0
二、前置条件
- 二进制位置:三个工具都在镜像内
/usr/local/bin/(kiwix-serve / kiwix-manage / kiwix-search),无需额外安装;容器外调用用docker exec <容器名> <工具> ...,compose 栈内用docker compose exec kiwix-serve <工具> ...。 - ZIM 样本:至少一个 ZIM 文件即可完成本文绝大多数实验;涉及多书联合检索与库文件管理的实验需要两个及以上。
- 端口预算:本文实验在探针容器内并发拉起多个临时实例,逐个使用 8081~8095 端口并在实验结束后回收;复现时注意端口不与常驻服务冲突。
三、参数查看与修改方式
查看:kiwix-serve --help 打印全部旗标;kiwix-manage 不带参数即打印用法。这里有一个镜像特有的坑——直接 docker run <镜像> --help 时,参数会先经过镜像入口脚本 start.sh,被拼上 --port=8080,于是先报一行错再打印帮助(逐字回显,实测采集自镜像入口):
/usr/local/bin/kiwix-serve --port=8080 --help
Unexpected argument: --port=8080, --help
Deliver ZIM file(s) articles via HTTP
Usage:
kiwix-serve [options] ZIMPATH ...
kiwix-serve [options] (-l | --library) LIBRARYPATH
kiwix-serve -h | --help
kiwix-serve -V | --version
规避方式:绕过入口脚本直接执行二进制——docker exec <容器名> kiwix-serve --help(start.sh 只在容器启动时走,exec 直达二进制,回显干净)。
修改:容器场景下改 compose 的 command(或 docker run 的尾部参数),重新 docker compose up -d 生效。生效确认看启动日志第一行——start.sh 会把最终执行命令原样回显(echo $CMD),例如:
/usr/local/bin/kiwix-serve --port=8080 --library /data/library.xml --monitorLibrary
四、参数总览
kiwix-serve 3.8.2 全部旗标(名称/缩写/默认值/一句话作用,默认值取自 --help 实测回显):
| 旗标 | 缩写 | 默认值 | 作用 | 实测详见 |
|---|---|---|---|---|
--port=<port> | -p | 80(镜像内被 start.sh 改为 8080) | HTTP 监听端口 | 5.1 |
--address=<addr> | -i | all | 仅监听指定 IP;特殊值 ipv4/ipv6/all | 5.1 |
--urlRootLocation=<root> | -r | / | 整站挂到 URL 子路径前缀 | 5.1 |
--ipConnectionLimit=<n> | -L | 0(无限) | 单 IP 并发连接上限(官方建议 ≥6) | 5.1 |
--library | -l | 无 | 参数改为库文件(XML/OPDS)而非 ZIM 路径 | 5.2 |
--monitorLibrary | -M | 关 | 监视库文件变化自动重载 | 5.2 |
--skipInvalid | -k | 关 | 跳过损坏 ZIM 继续启动 | 5.2 |
--nodatealiases | -z | 关 | 为带日期命名的 ZIM 生成去日期 URL 别名 | 5.2 |
--customIndex=<path> | -c | 无 | 自定义 HTML 替换欢迎页 | 5.2 |
--catalogOnly | 无 | 关 | 只伺服书目目录(欢迎页+OPDS),不伺服内容 | 5.2 |
--contentServerURL=<url> | 无 | 无 | catalogOnly 模式下指向真正伺服内容的实例 | 5.2 |
--nosearchbar | -n | 关 | 关闭阅读器顶栏搜索框 | 5.3 |
--nolibrarybutton | -m | 关 | 关闭阅读器顶栏「库」按钮 | 5.3 |
--blockexternal | -b | 关 | 阻断 ZIM 内容里的外站链接 | 5.3 |
--threads=<n> | -t | 4 | 并行线程数 | 5.4 |
--searchLimit=<n> | -s | 0(不限) | 多书联合全文检索的最大书数 | 5.4 |
--attachToProcess=<pid> | -a | 0 | 绑定进程生命周期,被绑定进程退出则服务退出 | 5.4 |
--daemon | -d | 关 | 服务进程脱离主进程后台运行 | 5.4 |
--verbose | -v | 关 | 向 STDOUT 打印调试日志 | 5.4 |
--version / --help | -V / -h | — | 版本 / 帮助 | 第三节 |
kiwix-manage 动作一览(完整用法见 5.5):
| 动作 | 语法 | 作用 |
|---|---|---|
add | kiwix-manage 库文件 add [--zimPathToSave=路径] [--url=网址] ZIM路径 ... | 把 ZIM 登记入库(可自定义库内路径、附加在线来源 URL) |
show | kiwix-manage 库文件 show [ZIMID ...] | 列出库内容(可按 ID 过滤) |
delete/remove | `kiwix-manage 库文件 (delete | remove) ZIMID ...` |
-v / -h | kiwix-manage -v / -h | 版本 / 帮助 |
五、核心参数分类详解
5.1 监听与网络
--port(-p):注意双重默认值——裸二进制默认 80,而官方镜像的 start.sh 在 PORT 环境变量未设置时固定拼 --port=8080。容器场景下容器内端口与宿主映射(compose ports)必须成对考虑。端口被占时的报错(实测两个实例抢 8089):
No stemming for language 'ur'
ERROR: Unable to instantiate the HTTP daemon. The port 8089 is maybe already occupied or need more permissions to be open. Please try as root or with a port number higher or equal to 1024.
第二实例以 exit 1 退出——注意与库文件加载失败(exit 0,见 5.2)的区别,这决定了监控告警能不能靠退出码兜底。
--address(-i):默认 all(IPv4+IPv6 双栈)。启动日志的监听清单是验证手段——默认态两行(Compose 栈实测):
The Kiwix server is running and can be accessed in the local network at:
- http://10.89.57.10:8080
- http://[::1]:8080
加 --address=ipv4 后只剩 IPv4 一行(探针实测,[::1] 行消失):
The Kiwix server is running and can be accessed in the local network at:
- http://10.89.65.2:8088
--urlRootLocation(-r):把整站挂到子路径,反代场景友好。实测 --urlRootLocation=/wiki:根路径 404、/wiki/ 200:
$ wget -S --spider http://127.0.0.1:8083/
HTTP/1.1 404 Not Found
$ wget -S --spider http://127.0.0.1:8083/wiki/
HTTP/1.1 200 OK
--ipConnectionLimit(-L):单 IP 并发连接上限,默认 0(无限),官方建议 ≥6——无界并发下单 IP 可耗尽线程池。旗标行为未做专项压测,按官方口径采用(生产模板中启用)。
5.2 内容装载与库旗标
直接列 ZIM 与目录参数:kiwix-serve [options] ZIMPATH ... 支持多个 ZIM 路径。官方文档写明「PATH 也可以是目录,目录下所有 ZIM 都会被装载」,但 3.8.2 实测不支持目录(传目录直接报错,且镜像 start.sh 兜底打印 /data 内容):
/usr/local/bin/kiwix-serve --port=8080 /data
Unable to add the ZIM file '/data' to the internal library.
Here is the content of /data:
/data/library.xml
/data/wikibooks_ur_all_nopic_2026-10.zim
/data/wikibooks_zh_all_nopic_2026-10.zim
结论:ZIM 必须逐个列文件路径(此差异与 kiwix-manage 的目录行为一致,见 5.5)。
--library(-l):把命令行参数从 ZIM 路径切换为库文件(XML 或 OPDS)。库文件是强依赖——文件不存在/不可加载时服务退出(退出码 0),容器编排下表现为重启循环,完整排障实录见部署篇 11.1 节。多个库文件可用分号串联(官方口径)。
--monitorLibrary(-M):监视库文件变化并自动重载。实测(Compose 栈,全程不重启容器):kiwix-manage delete 一本书后 OPDS 条目 2→1,add 回来后 1→2,数秒内生效;重载动作默认不打印日志,用 OPDS 条目数验证。另注意 --library 不带 -M 时重载也不会自动发生,但可手动触发——向进程发 SIGHUP 即强制重载(官方文档口径 + 实测验证):不带 -M 的实例删除库条目并 kill -HUP 后,OPDS 条目同样 2→1→2(探针实测)。
--skipInvalid(-k):默认情况下一个损坏 ZIM 会让整个实例起不来;加此旗标则跳过损坏文件继续伺服其余书目。实测构造一个垃圾 ZIM 并与正常 ZIM 同启:
$ echo "not-a-zim" > /data/broken.zim
$ kiwix-serve --port=8087 --skipInvalid /data/broken.zim /data/zims/wikibooks_ur_all_nopic_2026-10.zim
Skipping invalid '/data/broken.zim' ...continuing
No stemming for language 'ur'
The Kiwix server is running and can be accessed in the local network at:
- http://10.89.65.2:8087
- http://[::1]:8087
OPDS 目录确认只有 1 个有效条目(损坏文件被跳过)。
--nodatealiases(-z):为 _YYYY-MM 日期式命名的 ZIM 生成去日期别名。对照实验(同一请求 /content/wikibooks_zh_all_nopic/Python):不带旗标 → 404;带 --nodatealiases → 200,且响应带书目 UUID 派生的 ETag(ETag: "5c3cd871-8b19-8cc7-76ec-c02a1180d221/Z"),内容直接可达。别名规则与 library.xml 的 name 字段关系见 5.6。
--customIndex(-c):用自定义 HTML 替换默认欢迎页。实测放一个中文欢迎页文件后,根路径返回的就是它(逐字回显):
<!DOCTYPE html><html><head><meta charset="utf-8"><title>内网离线图书馆</title></head><body><h1>内网离线图书馆</h1><p>请从下方目录选择读物。</p></body></html>
--catalogOnly:只伺服欢迎页与 OPDS 目录、不伺服 ZIM 内容。实测:/catalog/v2/entries?count=-1 返回 2 条书目,但内容请求 404——与官方文档「ZIM 文件无需可访问」的描述一致:
$ wget -q -O- "http://127.0.0.1:8085/catalog/v2/entries?count=-1" | grep -c "<entry>"
2
$ wget -q -O- "http://127.0.0.1:8085/content/wikibooks_zh_all_nopic_2026-10/Python"
wget: server returned error: HTTP/1.1 404 Not Found
--contentServerURL=<url>:必须与 --catalogOnly 搭配——目录实例把内容预览指向另一台真正伺服内容的实例(官方口径:适合「目录服务与内容服务分离」的多机形态)。本文未组双实例,部署上属可选进阶项。
5.3 阅读器界面裁剪
三个界面旗标控制内置阅读器(viewer)的行为,其生效状态可通过容器内 /viewer_settings.js 直接观测。三旗标齐开(--nosearchbar --nolibrarybutton --blockexternal)的实测回显:
const viewerSettings = {
toolbarEnabled: false,
linkBlockingEnabled: true,
libraryButtonEnabled: false
}
与旗标的对应关系:--nosearchbar → toolbarEnabled(关顶栏)、--nolibrarybutton → libraryButtonEnabled(关库按钮)、--blockexternal → linkBlockingEnabled(开外链拦截)。--blockexternal 的配套机制是拦截页端点 /catch/external:离线环境里用户点 ZIM 内的外站链接时不再直跳死链。
5.4 运行控制与多书检索
--threads(-t):并行线程数,默认 4。伺服静态 ZIM 内容属 IO 密集,中小规模默认值即可;大并发场景调大并配合 --ipConnectionLimit。本文未做专项压测,按默认值与官方口径采用。
--searchLimit(-s):多书联合全文检索的最大 ZIM 数,默认 0(不限)。实测 --searchLimit=1 且装载两本书后访问 /search?pattern=Python(默认跨书检索会请求 2 本书):
HTTP 400
<title>Invalid request</title>
Too many books requested (2) where limit is 1
超限是明确的 400 错误页而非静默截断——部署多书库时若要启用此限制,需同步告知用户检索范围。
--attachToProcess(-a):把服务生命周期绑到另一个进程。实测:绑定一个 sleep 300 进程后服务正常伺服(HTTP 200);kill 掉 sleep 后服务随即退出(连接拒绝):
alive-before=200
wget: can't connect to remote host (127.0.0.1): Connection refused
适用形态:由外部监督进程(如自定义守护脚本)托管生命周期。
--daemon(-d):服务进程 fork 到后台、主进程立即返回。探针容器内实测:命令瞬间返回 exit=0,8099 端口的服务保持可访问。容器编排场景禁用:PID 1 链条(dumb-init → start.sh → kiwix-serve)里 start.sh 会随 kiwix-serve 后台化而立即退出,容器随之停止——容器本身就是守护单元,无需再 daemon 化。
--verbose(-v):向 STDOUT 打印调试日志。排障首选(配合 docker logs -f 观察请求级日志)。
5.5 库管理工具 kiwix-manage
无参数运行即打印完整用法(逐字回显):
Arguments did not match expected patterns
Manipulates the Kiwix library XML file
Usage:
kiwix-manage LIBRARYPATH add [--zimPathToSave=<custom_zim_path>] [--url=<http_zim_url>] ZIMPATH ...
kiwix-manage LIBRARYPATH (delete|remove) ZIMID ...
kiwix-manage LIBRARYPATH show [ZIMID ...]
kiwix-manage -v | --version
kiwix-manage -h | --help
动作一:add(登记入库)。基础用法 kiwix-manage 库文件 add ZIM路径;条目的标题/语言/条目数/媒体数/大小等元数据自动读取自 ZIM 内嵌信息,成功回显仅一行词干提示(无害):
$ kiwix-manage /data/library.xml add /data/wikibooks_zh_all_nopic_2026-10.zim
No stemming for language 'zh'
两个可选参数(实测):
| 参数 | 作用 | 实测结果 |
|---|---|---|
--url=<网址> | 在库条目上附加在线来源 URL | add 后 XML 出现 url="https://download.kiwix.org/zim/wikibooks/wikibooks_ur_all_nopic_2026-10.zim" |
--zimPathToSave=<路径> | 库内记录的路径与实际传入路径解耦(自定义登记路径) | 官方口径:替换库中保存的 ZIM 路径 |
不支持目录:add /data/zims(目录)报 Unable to add the ZIM file '/data/zims' to the internal library.——必须逐个列 ZIM 文件(3.8.2 实测,与官方文档「目录亦可用」的表述不符)。
动作二:show(查看库)。show 全量列出(逐字段回显样例,见部署篇 4.2 节完整版),支持按 ID 过滤:
$ kiwix-manage /tmp/lib-hup2.xml show 5c3cd871-8b19-8cc7-76ec-c02a1180d221
id: 5c3cd871-8b19-8cc7-76ec-c02a1180d221
path: /data/zims/wikibooks_zh_all_nopic_2026-10.zim
url:
title: Wikibooks
动作三:delete / remove(按 ID 删除)。两个动词等价;ID 必须精确匹配,否则报错(实测 exit 1):
$ kiwix-manage /tmp/lib-hup2.xml delete deadbeef-dead-dead-dead-deadbeefdead
Invalid book id 'deadbeef-dead-dead-dead-deadbeefdead'.
注意事项:
- 参数顺序是
kiwix-manage 库文件 动作,写成kiwix-manage show 库文件直接拒绝执行(Arguments did not match expected patterns)。 size口径差异:XML 属性size单位 KiB(如 91148),show输出显示字节数但标 KB(93335552 KB,实为 93335552 字节)。- 同一 ZIM 重复 add 按 ID 去重覆盖(book id 源自 ZIM 内嵌 UUID,删除重加不变——实测)。
- kiwix-manage 只读写库文件,不影响运行中服务;配合
--monitorLibrary或 SIGHUP 让变更生效(见 5.2)。
5.6 library.xml 结构与字段
根元素与书目条目(favicon Base64 图标截断展示):
<library version="20110515">
<book id="5c3cd871-8b19-8cc7-76ec-c02a1180d221" path="wikibooks_zh_all_nopic_2026-10.zim" title="Wikibooks" description="An Offline Version of Wikibook in Chinese Language" language="zho" creator="Wikibooks" publisher="openZIM" name="wikibooks_zh_all" flavour="nopic" tags="wikibooks;_category:wikibooks;_pictures:no;_videos:no;_details:yes;_ftindex:yes" faviconMimeType="image/png" favicon="iVBORw0KGgo……" date="2026-10-15" articleCount="8510" mediaCount="132" size="91148" />
</library>
| 字段 | 含义 | 实测要点 |
|---|---|---|
version="20110515" | 库文件格式版本(日期数字) | 所有 3.8.2 生成的库均为该值 |
id | 书目 UUID | 源自 ZIM 内嵌 UUID,唯一键;delete 按 it 定位 |
path | ZIM 文件路径 | 相对路径以库文件所在目录为基准解析(实测:库文件在 /tmp、相对 path 指向 /tmp 下不存在的文件时,重载后书目 0 条);建议统一写绝对路径 |
name | 内容的 URL 名称 | /content/<name>/... 与 /search?books.name=<name> 中的书标识 |
flavour | 精度变体(nopic/maxi 等) | URL 名 = name +(_flavour)+(_YYYY-MM 快照日期) |
tags | 分号分隔标签 | _ftindex:yes 表示含全文索引(可被 /search 检索);_ 前缀为机器私有标签(分类/图片/视频/详情) |
articleCount / mediaCount | 条目数 / 媒体数 | add 时自动从 ZIM 元数据读取 |
date | 快照日期 | 与文件名 _YYYY-MM 对应 |
size | 文件大小(KiB) | 与 show 的字节口径差 1024 倍 |
favicon / faviconMimeType | Base64 书封 | add 自动提取 |
url | 在线来源 | 仅 add --url= 时写入,默认为空 |
--nodatealiases 的别名规则(官方文档口径 + 实测印证):对文件名含 _YYYY-MM 的 ZIM,去掉日期段生成别名 URL;去掉的是日期而非 flavour——wikibooks_zh_all_nopic_2026-10 的别名是 wikibooks_zh_all_nopic(实测 200),官方示例 wikipedia_en_all_2020-08 的别名是 wikipedia_en_all。
六、生产配置模板
三档模板(均为 compose command 片段,完整编排框架见部署篇):
小型(单书/双书直列,家庭/教室场景,内存 512MB、磁盘 = ZIM 体积):
command: ["/data/wikibooks_zh_all_nopic_2026-10.zim"]
中型(库模式 + 热重载 + 外链管控 + 单 IP 限连,机构内网图书馆,内存 1~2GB、磁盘数十 GB、书目经常增删):
command: ["--library", "/data/library.xml", "--monitorLibrary",
"--blockexternal", "--ipConnectionLimit=30", "--threads=8"]
大型(目录/内容分离,多机分发,内存 2GB+、书目上千):
# 目录实例(只出书目与 OPDS)
command: ["--library", "/data/library.xml", "--monitorLibrary", "--catalogOnly",
"--contentServerURL=http://<内容实例地址>:8080"]
# 内容实例(去掉 --catalogOnly,按 5.1/5.4 收紧网络与连接参数)
选型依据:小/中型用「一个容器全干」;书目规模大到内容伺服与目录查询相互影响时才拆分双实例。
七、常见问题
docker run <镜像> --help先报Unexpected argument: --port=8080, --help:参数经镜像入口 start.sh 被拼上--port=8080;用docker exec <容器> kiwix-serve --help直达二进制(见第三节)。- 裸二进制
--port默认 80,镜像里却是 8080:两个默认值来源不同(二进制 vs start.sh 的PORT环境变量);容器内改端口用PORT环境变量,别在 command 里再写--port(会拼出两个--port)。 - 库模式起不来且容器反复重启:
--library文件缺失/损坏时 kiwix-serve 退出且退出码为 0(日志含ERROR: Failed to load the XML library file '...'与 start.sh 兜底的 /data 文件清单)——监控别依赖退出码,用 HTTP 探活或重启次数;修复库文件后restart: unless-stopped会自动拉起自愈。完整实录见部署篇 11.1。 - kiwix-manage 报
Arguments did not match expected patterns:参数顺序写反了,正确为kiwix-manage 库文件 动作(见 5.5)。 - 把目录当 ZIM 传入报
Unable to add the ZIM file '/data' to the internal library.:3.8.2 实测 kiwix-serve 与 kiwix-manage 都不支持目录,逐个列 ZIM 文件(与官方文档表述不一致,见 5.2/5.5)。 - 库模式书变为 0 条:检查 library.xml 里的相对
path——它相对库文件所在目录解析;把库文件挪位置或用绝对路径(见 5.6 实测案例)。 - 启动日志里的
No stemming for language 'xx':该语言无词干归并规则,仅影响检索词形归一,非错误,无需处理。 - 多书搜索报 400
Too many books requested (N) where limit is M:--searchLimit生效中;调大限制或减少参与检索的书目(需同语言,见 5.4)。
八、参考链接
- 本专栏前置阅读:《Kiwix 介绍与选型指南》、《Kiwix 3.8.2 Docker Compose 部署指南》
- kiwix-serve 官方文档(旗标与 HTTP API):https://kiwix-tools.readthedocs.io/en/latest/kiwix-serve.html (查询日期 2026-11-01)
- kiwix-tools 源码与发布仓库:https://github.com/kiwix/kiwix-tools (查询日期 2026-11-01)
- ZIM 文件格式规范(tags 与
_ftindex语义):https://openzim.org/wiki/ZIM_file_format (查询日期 2026-11-01)