TagSpaces 6.13.9 配置参数详解
TagSpaces 6.13.9 配置参数详解:extconfig.js 全参数(品牌/启动/打标/ExtLocations 位置/标签库/搜索分组)语义与默认值、热生效与单文件挂载 inode 陷阱实录、个人与团队两档生产配置模板及常见问题,官方文档溯源+本地实测。
TagSpaces 6.13.9 配置参数详解
目标:讲清 TagSpaces 6.13.9(Web 形态)的唯一配置入口
extconfig.js的全部参数——查看与修改方式、界面品牌/启动行为/打标行为三类全局开关、最核心的ExtLocations位置参数、标签库与搜索分组配置,并给出可直接落地的生产配置模板与排障实录。参数语义以官方文档溯源为准(查询日期 2026-11-01),生效行为全部在本地实测栈验证。
一、环境信息
- 操作系统:Linux x86_64;Docker 29.x + Docker Compose v2
- 实测栈:本专栏《TagSpaces 6.13.9 Docker Compose 部署指南》部署的
tagspaces-6.13.9-stack——tagspaces/tagspaces-lite-web:6.13.9(nginx 1.31.2 伺服,宿主端口 8148)+ MinIO(S3 后端,宿主端口 8149/8150) - 配置载体:
extconfig.js(Web 版)/extconfig.json(桌面版)——官方《External Configuration》页原文:"This document will describe how to deploy TagSpaces Pro and Custom with predefined configuration... saved in a file called extconfig.js (for web) and extconfig.json (for desktop version)";官方该页面向 Pro/Custom 编写,但 Lite Web 镜像同样读取该文件(本文全部实测基于 Lite Web 6.13.9) - 参数依据:https://docs.tagspaces.org/dev/external-config/ (查询日期 2026-11-01)
- 容器内路径:
/usr/share/nginx/html/extconfig.js;宿主侧./extconfig.js只读挂载(见部署篇 4.1 节编排) - 文件大小实测:
986字节(wc -c extconfig.js),nginx 直出Content-Length: 986
二、前置条件
- 已完成部署篇的栈部署(
docker compose ps中 web/minio 均 Up); - 已定位配置文件:宿主 compose 目录下的
extconfig.js,与容器内/usr/share/nginx/html/extconfig.js一一对应; - 明确修改通道:没有服务端重启的概念——TagSpaces Web 是纯静态应用,改完文件浏览器刷新即可(生效机制与陷阱见第三章);
- 建议先通读部署篇第六章(预置位置的写入闭环),本章在其基础上展开全部参数。
三、参数查看与修改方式
3.1 查看当前生效的配置
配置文件由 nginx 直接伺服,浏览器加载的就是它。三种查看方式等价:
# 方式一:HTTP 直接取(所见即浏览器所得)
curl -s http://127.0.0.1:8148/extconfig.js
# 方式二:进容器看
docker exec tagspaces-6.13.9-web cat /usr/share/nginx/html/extconfig.js
# 方式三:看宿主挂载源文件
cat ./extconfig.js
实测响应头(curl -sI http://127.0.0.1:8148/extconfig.js):
HTTP/1.1 200 OK
Server: nginx/1.31.2
Content-Type: application/javascript
Content-Length: 986
Last-Modified: Sun, 01 Nov 2026 07:11:32 GMT
ETag: "..."
Accept-Ranges: bytes
加载机制实测:extconfig.js 由 index.html 以普通 <script> 同步引入(容器内 grep -n extconfig /usr/share/nginx/html/index.html 回显 40: <script type="text/javascript" src="extconfig.js"></script>),即它在应用 bundle 之前执行,把 window.Ext* 参数挂到全局对象上供应用读取。由此可推知两点:文件必须是合法 JavaScript;参数全部以 window.Ext参数名 = 值; 的语句形式书写(官方文档所有示例均如此)。
3.2 修改与热生效(实测)
服务端侧零重启:向文件追加一行参数后立即用 curl 验证。实测序列(追加 → 验证 → 还原 → 验证):
echo 'window.ExtShowTSVersion = false;' >> extconfig.js
curl -sI http://127.0.0.1:8148/extconfig.js | grep Content-Length
curl -s http://127.0.0.1:8148/extconfig.js | tail -1
cp /tmp/extconfig.bak extconfig.js # 还原
curl -sI http://127.0.0.1:8148/extconfig.js | grep Content-Length
实测回显:
Content-Length: 1019
window.ExtShowTSVersion = false;
Content-Length: 986
Content-Length 从 986 即时变为 1019、新参数行立即伺服、还原后回到 986——服务端侧文件改完即生效;浏览器侧只需刷新页面让应用重新执行该脚本。ExtShowTSVersion 的实际界面效果(隐藏左上角版本号)属界面行为,本文以官方文档为准。
3.3 修改不生效的头号陷阱:单文件 bind mount 的 inode 问题(排障实录)
如果用 sed -i、vim 等会原子替换文件的方式编辑宿主的 extconfig.js,会出现「宿主文件明明改了、应用伺服的还是旧内容」:单文件 bind mount 绑定的是 inode,原子替换生成了新 inode,容器仍挂在旧 inode 上。实测实录:
wc -c extconfig.js # 宿主:986 字节(新内容)
curl -sI http://127.0.0.1:8148/extconfig.js | grep Content-Length # 容器伺服:1019 字节(旧内容)
处置二选一:
# 方案一:重建容器,重新绑定当前 inode(秒级,推荐)
docker compose up -d --force-recreate tagspaces
# 方案二(根治):编排里改挂目录不挂单文件,或编辑时用「写同 inode」的方式(echo >>、cp 覆盖)
重建后复测,伺服 Content-Length 与宿主 wc -c 一致(实测均为 986)。本文以下所有实验都在重建后的一致状态上进行。
3.4 浏览器侧会不会缓存它?
实测容器内 sw-config.js 的 Service Worker 预缓存清单 FILES_TO_CACHE 只包含 offline.html 与 dist/*.bundle.js、dist/style.css,不含 extconfig.js;且 nginx 对该文件回显 ETag/Last-Modified 协商缓存头。因此改配置后浏览器刷新即可拿到新内容;若个别浏览器强缓存,用强制刷新(Ctrl+Shift+R)排除干扰。
四、参数总览
全部 window.Ext* 参数一览(类型/默认值/出处均为官方《External Configuration》页原文,查询日期 2026-11-01;「锁定」指设置后用户无法在应用设置对话框中更改):
| 参数 | 类型 | 默认值 | 作用 |
|---|---|---|---|
ExtLogoURL | 字符串(URL/相对路径) | 无 | 自定义应用 logo(≤250×50px,JPG/GIF/PNG/SVG) |
ExtShowTSLogo | 布尔 | true | 是否显示左上角 TagSpaces logo |
ExtShowTSVersion | 布尔 | true | 是否显示左上角版本号 |
ExtIsFirstRun | 布尔 | true | 跳过首次启动引导对话框与许可确认 |
ExtCheckForUpdatesOnStartup | 布尔 | true | 启动时检查新版本 |
ExtDisplayMode | "desktop" / "mobile" | — | 桌面/移动界面模式 |
ExtUseSidecarsForFileTagging | 布尔 | — | 打标方式全局锁定为旁车(true)或改名(false);设置后 UI 不可再改(锁定) |
ExtUseOnlyTagsFromTagLibrary | 布尔 | — | 强制只能用标签库预置标签打标;设置后 UI 不可再改(锁定) |
ExtFilenameTagPlacedAtEnd | 布尔 | true | 改名打标时标签段放文件名尾部(file [tag].ext)还是头部 |
ExtPrivacyURL | 字符串(URL) | 无 | 隐私政策页面链接 |
ExtImprintURL* | 字符串(URL) | 无 | 印记页(imprint)链接(*官方文档示例存在笔误,见 5.5 与 FAQ) |
ExtLocations | 数组 | 无 | 预置位置列表(对象存储/本地文件夹),最核心参数 |
ExtLocationsReadOnly | 布尔 | — | 已废弃:外置配置的位置现在自动只读 |
ExtSaveLocationsInBrowser | 布尔 | Web 版 false / 桌面版 true | 位置数据(含 S3 密钥)持久化进浏览器 localStorage |
ExtTagLibrary | 数组 | 无 | 预置标签库(分组+标签,定义后 UI 只读) |
ExtSearchTypeGroups | 对象 | 官方默认(见 5.7) | 搜索界面的文件类型分组 |
五、核心参数分类详解
5.1 界面品牌类(ExtLogoURL / ExtShowTSLogo / ExtShowTSVersion)
官方示例:
window.ExtLogoURL = "https://www.tagspaces.org/content/text-logo.svg";
// window.ExtLogoURL = "custom-logo.png"; // 相对路径:文件与应用同目录伺服
window.ExtShowTSLogo = false;
window.ExtShowTSVersion = false;
要点:logo 图片建议不超过 250px 宽、50px 高;用相对路径时把图片与 extconfig.js 放同一目录(nginx 站点根)。私有化部署最常用组合是 ExtLogoURL + ExtShowTSLogo = false 做白标(白标完整能力属于官方 Custom 付费版,Lite 只能覆盖 logo 层面)。
5.2 启动行为类(ExtIsFirstRun / ExtCheckForUpdatesOnStartup / ExtDisplayMode)
window.ExtIsFirstRun = true; // 跳过首次启动 onboarding 与许可确认
window.ExtCheckForUpdatesOnStartup = false; // 关闭启动检查更新(内网部署建议关闭)
window.ExtDisplayMode = "mobile"; // 可选 "desktop" / "mobile"
三者默认值分别为 true、true、无(跟随设备)。内网/离线环境建议显式关闭更新检查,避免无意义的对外请求。
5.3 打标行为类(ExtUseSidecarsForFileTagging / ExtUseOnlyTagsFromTagLibrary / ExtFilenameTagPlacedAtEnd)
window.ExtUseSidecarsForFileTagging = false; // false=改名打标, true=旁车打标
window.ExtUseOnlyTagsFromTagLibrary = false; // true=只允许标签库内的标签
window.ExtFilenameTagPlacedAtEnd = true; // 标签段在文件名尾部
两个「锁定」参数是管理员治理的关键:一旦在 extconfig.js 里显式给出(无论 true/false),用户在设置对话框里就只能看不能改(官方 tip 原文:"If the parameter is specified then this setting could not be changed in the TagSpaces settings dialog anymore")。团队统一打标口径的推荐配置:ExtUseOnlyTagsFromTagLibrary = true 配合 5.6 的 ExtTagLibrary。
与位置级参数的关系:persistTagsInSidecarFile(5.4)是单位置的打标方式声明,本组是全局默认;对象存储位置因 S3 对象无法改名,实践上必须配套 persistTagsInSidecarFile: true(部署篇 6.1 节实测配置即如此)。官方文档未明述两级的覆盖规则,生产上建议显式设置两级、避免依赖隐式行为。
💡 技术拓展:两种打标落盘机制的全链路实测对比(文件名嵌入
[tag1 tag2].ext改名 vs.ts/*.json旁车),见本专栏《TagSpaces 6.13.9 常用 CLI 命令与工具详解》的 tag 命令详解。
5.4 位置参数 ExtLocations(核心)
ExtLocations 是数组,每项描述一个预置位置。官方文档给出对象存储(type: "1")与本地文件夹(type: "0")两套示例,字段逐项如下(含义列含官方注释原文归纳;实测值列取自本文实测栈的 extconfig.js):
| 字段 | 适用 | 含义 | 实测值 |
|---|---|---|---|
uuid | 两者 | 位置唯一 ID | "b3f2a1c8-6d4e-4f2a-9b7c-1a2b3c4d5e6f" |
type | 两者 | "1"=对象存储,"0"=本地文件夹 | "1" |
name | 两者 | 位置显示名 | "MinIO ts-demo" |
path | 对象存储 | 桶内子前缀(如 "demo"),空串=桶根 | "" |
paths | 本地 | 本地目录路径数组(官方本地示例用 paths,JSON 示例又写作 path——官方示例本身两种写法并存,对象存储位置用单数 path 无歧义) | —(Web 版无本地位置) |
accessKeyId | 对象存储 | S3 Access Key | "admin" |
secretAccessKey | 对象存储 | S3 Secret Key | "q1w2e3r4" |
bucketName | 对象存储 | 桶名 | "ts-demo" |
region | 对象存储 | S3 区域 | "us-east-1"(MinIO 默认) |
endpointURL | 对象存储 | S3 API 端点(浏览器可达的地址) | "http://localhost:8149" |
isNotEditable | 对象存储 | 禁止打开位置属性与导出 | false |
isDefault | 两者 | 应用启动自动加载 | true |
isReadOnly | 两者 | UI 整体只读模式 | false |
disableIndexing | 两者 | true=只复用已有索引不重建;false=每次搜索时按需建索引(受 maxIndexAge 控制有效期) | false |
disableThumbnailGeneration | 对象存储 | 关闭缩略图生成(避免为出缩略图整目录拉取,桶场景常用) | false |
fullTextIndex | 两者 | 对 TXT/MD/HTML 启用全文索引 | true |
watchForChanges | 两者 | 监视文件变化(官方注明云位置不生效) | false |
maxIndexAge | 两者 | 索引有效期毫秒数,官方示例 600000=10 分钟 | 600000 |
persistTagsInSidecarFile | 对象存储 | 该位置的打标方式(true=旁车) | true |
ignorePatternPaths | 对象存储 | 索引时忽略的路径通配,如 ["**/node_modules/**"] | 未设置 |
三条官方确认的行为规则:
- 自动只读:凡是外置配置下发的位置,UI 中自动只读(官方 tip:"as soon as you have externally configured locations they are automatically read-only")——不能在界面改属性、导出;旧参数
ExtLocationsReadOnly已废弃。 endpointURL是浏览器视角:页面从 8148 打开、S3 请求发往endpointURL,跨端口即跨域,MinIO 默认按请求源回显 CORS 头(部署篇 5.3 节实测)。maxIndexAge决定搜索新鲜度:浏览器会话内索引超过该毫秒数即过期重建;命令行批量预生成索引的姿势见 D1 篇 indexer 详解。
5.5 位置持久化与隐私(ExtSaveLocationsInBrowser / ExtPrivacyURL)
window.ExtSaveLocationsInBrowser = true; // 桌面默认 true;Web 版默认 false
window.ExtPrivacyURL = "https://tagspacesweb.yourdomain.com/privacy/";
官方原文要点:开启后位置配置(含 S3 access/secret key)存入浏览器 localStorage,免去每次打开重建位置;官方警告原文:"It is not recommended to use TagSpaces Web installations with ExtSaveLocationsInBrowser = true on public computers, since the location information will potentially stay there even after you close the browser." 私人电脑可用,公用/共享电脑必须保持默认关闭。本文实测栈为演示便利开启了 true(部署篇 6.1)。
隐私/印记页链接:官方说明 Web 版默认不显示隐私政策与 imprint 入口,用 ExtPrivacyURL 配置隐私政策页。⚠️ 官方文档的「Custom imprint page URL」一节示例代码也写的是 window.ExtPrivacyURL = ".../imprint/"(与隐私政策示例同名)——按官方文本照录并在此标注:印记页参数名以官方后续修订为准,若两个入口都需要,建议实测验证参数名后再上线。
5.6 标签库 ExtTagLibrary
官方结构(一个或多个标签组,组内一个或多个标签):
window.ExtTagLibrary = [
{
uuid: "17882854-44a7-4b2d-a2b1-b022846ac41d", // 标签组唯一 ID
title: "Common Tags", // 组名
color: "#008000", // 组内标签默认底色
textcolor: "#ffffff", // 默认文字色
readOnly: true, // 该组只读
children: [ // 标签数组
{ type: "plain", title: "book", description: "", color: "#008000", textcolor: "#ffffff" }
],
expanded: true // true 才会在界面展开显示
}
];
官方导入流程:应用内标签库三点菜单 → Export → 选择导出的组 → 打开导出 JSON,把 tagGroups 数组内容拷进 window.ExtTagLibrary = [...]。生效后标签库在 UI 中渲染为只读(官方 tip:用户不能增删改其中的标签)。
本文实测栈的标签库(extconfig.js 实际内容节选):
window.ExtTagLibrary = [
{
title: "项目标签",
color: "#8bc34a",
textcolor: "#ffffff",
expanded: true,
children: [
{ title: "财务", color: "#f44336", textcolor: "#ffffff" },
{ title: "合同", color: "#2196f3", textcolor: "#ffffff" },
{ title: "已审阅", color: "#4caf50", textcolor: "#ffffff" }
]
}
];
(实测文件未写 uuid/readOnly,应用可正常加载——官方示例字段并非全部强制。)
5.7 搜索类型分组 ExtSearchTypeGroups
该参数自定义搜索界面的类型分组,官方给出完整默认值。分组键与扩展名对应关系(官方默认配置照录,篇幅所限列出分组与代表扩展名):
| 分组键 | 官方默认扩展名 |
|---|---|
any | [''](全部) |
images | jpg/jpeg/jfif/jif/jiff/png/gif/svg/webp/bmp/tga/tif/tiff/nef/cr2/dng/psd/avif |
notes | md/mdown/txt/html |
documents | pdf/doc/docx/xls/xlsx/odt/ods/odp/pptx/numbers/potx/sldx/dotx |
audio | ogg/mp3/wav/wave/flac/acc/m4a/opus |
video | ogv/mp4/webm/m4v/mkv/avi/3gp/3g2/mov |
archives | zip/rar/gz/tgz/arc/7z |
bookmarks | url/lnk/sym/desktop/website |
ebooks | epub/mobi/azw/prc/azw1/azw3/azw4/azw8/azk |
emails | eml/msg |
folders / files / untagged | 特殊分组标记(folders/files/untagged) |
该分组同时被 CLI 的 search --type 复用(可选值 any, images, documents, notes, audio, video, archives, bookmarks, ebooks, emails, folders, files, untagged,实测见 D1 篇 search 详解)。要为私有格式加分组时,整体覆盖 window.ExtSearchTypeGroups 对象即可。
六、生产配置模板
6.1 个人自托管(8GB 内存 VPS,单人使用)
// extconfig.js —— 单人自托管:MinIO + 本地浏览器专用
window.ExtIsFirstRun = true; // 跳过引导
window.ExtCheckForUpdatesOnStartup = false; // 内网/离线关闭更新检查
window.ExtSaveLocationsInBrowser = true; // 私人设备才开启(含密钥,见 5.5 警告)
window.ExtLocations = [
{
uuid: "<生成一个 UUID>",
type: "1",
name: "我的云盘",
path: "",
accessKeyId: "<MinIO access key>",
secretAccessKey: "<MinIO secret key>",
bucketName: "ts-demo",
region: "us-east-1",
endpointURL: "http://<服务器IP>:8149", // 浏览器可达地址
isDefault: true,
disableIndexing: false,
disableThumbnailGeneration: false,
fullTextIndex: true,
watchForChanges: false,
maxIndexAge: 600000,
persistTagsInSidecarFile: true
}
];
适用:单人、设备可控。资源占用面:该配置只影响浏览器行为,服务端仍是两个常驻容器(Web 静态 + MinIO),内存占用以对象存储为主。
6.2 团队只读分发(含白标与统一标签口径)
// extconfig.js —— 团队场景:白标 + 只读位置 + 标签库治理
window.ExtLogoURL = "logo.svg"; // 与本文件同目录伺服(≤250×50)
window.ExtShowTSLogo = false;
window.ExtShowTSVersion = false;
window.ExtIsFirstRun = true;
window.ExtCheckForUpdatesOnStartup = false;
window.ExtUseOnlyTagsFromTagLibrary = true; // 锁定:只能用标签库标签
window.ExtFilenameTagPlacedAtEnd = true;
window.ExtSaveLocationsInBrowser = false; // 默认即 false,显式写出以示安全边界
window.ExtPrivacyURL = "https://intra.example.com/privacy/";
window.ExtTagLibrary = [ /* 5.6 结构,导出后拷入 */ ];
window.ExtLocations = [
{
uuid: "<生成一个 UUID>",
type: "1",
name: "团队资料库",
path: "",
accessKeyId: "<只读子账号 access key>", // 最小权限:对象存储侧另建只读子账号
secretAccessKey: "<只读子账号 secret key>",
bucketName: "team-docs",
region: "us-east-1",
endpointURL: "https://s3.example.com", // 建议走反向代理 + TLS
isDefault: true,
isReadOnly: true, // UI 只读模式
disableThumbnailGeneration: false,
fullTextIndex: true,
maxIndexAge: 600000,
persistTagsInSidecarFile: true,
ignorePatternPaths: ["**/node_modules/**", "**/.git/**"]
}
];
配套两件服务端事项(不在 extconfig.js 内,但属同一交付物):① nginx 层 basic auth 保护站点与 extconfig.js 本身(该文件含 S3 密钥时官方明确要求限制访问,操作步骤见部署篇第九章与 FAQ Q6);② 对象存储侧为使用者创建最小权限子账号而非下发 root 密钥(部署篇第八章)。
七、常见问题
Q1:改了 extconfig.js,应用伺服的还是旧内容?
先分清两层:服务端伺服旧内容 → 3.3 节的 inode 陷阱(sed -i/编辑器原子替换 + 单文件挂载),docker compose up -d --force-recreate tagspaces 重建即可,实测 986/1019 字节不一致 → 重建后一致;服务端已是新内容但浏览器没变 → 刷新或强制刷新(extconfig.js 不在 Service Worker 预缓存清单内,实测见 3.4 节)。
Q2:界面上改不了/删不掉外置配置的位置?
官方设计如此:外置配置下发的位置自动只读(5.4 规则 1)。要调整位置属性就改 extconfig.js 再刷新;需要用户自建位置时,从预置列表中去掉对应项即可。
Q3:Web 版能预置本地文件夹位置(type: "0")吗?
不能。浏览器沙箱无法直接读写服务器本地目录,type: "0" 是桌面版能力;Web 形态必须走对象存储位置(或经 S3Proxy 把 NAS 目录桥接成 S3 接口,官方教程支持)。
Q4:extconfig.js 写错语法会怎样?
该文件是被 index.html 同步加载的普通脚本(3.1 节实测),语法错误时该脚本执行中断,其后的 window.Ext* 赋值不生效,应用按内置默认值运行——表现为「配置全丢了」。修改后可用 node --check extconfig.js(或浏览器控制台无报错)先行校验。
Q5:开启了 ExtSaveLocationsInBrowser 有什么风险?
位置数据含 S3 密钥落入浏览器 localStorage,同机其他使用者可设法读取(官方 5.5 节警告原文)。私人设备可开;公用电脑保持关闭,且关闭时每次打开需重新加载位置——有 extconfig.js 预置位置在,重新加载是零成本刷新(部署篇 FAQ Q4/Q5 的处置均基于此)。
Q6:印记页(imprint)参数到底叫什么?
官方文档「Custom imprint page URL」一节的示例代码写作 window.ExtPrivacyURL(与隐私政策参数同名,见 5.5 节标注)。两入口同时需要时,先以实测确认哪个参数名驱动 imprint 入口再上线,避免踩官方文档笔误。
八、参考链接
- 官方《External Configuration》页(本篇全部参数语义来源):https://docs.tagspaces.org/dev/external-config/
- 官方 Docker 部署教程(extconfig.js 放置位置与安全警告):https://docs.tagspaces.org/tutorials/tagspaces-web-docker/
- 官方 MinIO 桶接入教程:https://docs.tagspaces.org/tutorials/setup-minio-bucket-nas/
- 本专栏实测系列:《TagSpaces 介绍与选型指南》、《TagSpaces 6.13.9 Docker Compose 部署指南》(部署与读写闭环实测)、《TagSpaces 6.13.9 常用 CLI 命令与工具详解》(索引与打标命令实测)