TagSpaces 6.13.9 配置参数详解

TagSpaces 6.13.9 配置参数详解:extconfig.js 全参数(品牌/启动/打标/ExtLocations 位置/标签库/搜索分组)语义与默认值、热生效与单文件挂载 inode 陷阱实录、个人与团队两档生产配置模板及常见问题,官方文档溯源+本地实测。

TagSpacesTagSpaces自托管文件服务器2026/11/01

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

二、前置条件

  1. 已完成部署篇的栈部署(docker compose ps 中 web/minio 均 Up);
  2. 已定位配置文件:宿主 compose 目录下的 extconfig.js,与容器内 /usr/share/nginx/html/extconfig.js 一一对应;
  3. 明确修改通道:没有服务端重启的概念——TagSpaces Web 是纯静态应用,改完文件浏览器刷新即可(生效机制与陷阱见第三章);
  4. 建议先通读部署篇第六章(预置位置的写入闭环),本章在其基础上展开全部参数。

三、参数查看与修改方式

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/**"]未设置

三条官方确认的行为规则:

  1. 自动只读:凡是外置配置下发的位置,UI 中自动只读(官方 tip:"as soon as you have externally configured locations they are automatically read-only")——不能在界面改属性、导出;旧参数 ExtLocationsReadOnly 已废弃。
  2. endpointURL 是浏览器视角:页面从 8148 打开、S3 请求发往 endpointURL,跨端口即跨域,MinIO 默认按请求源回显 CORS 头(部署篇 5.3 节实测)。
  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[''](全部)
imagesjpg/jpeg/jfif/jif/jiff/png/gif/svg/webp/bmp/tga/tif/tiff/nef/cr2/dng/psd/avif
notesmd/mdown/txt/html
documentspdf/doc/docx/xls/xlsx/odt/ods/odp/pptx/numbers/potx/sldx/dotx
audioogg/mp3/wav/wave/flac/acc/m4a/opus
videoogv/mp4/webm/m4v/mkv/avi/3gp/3g2/mov
archiveszip/rar/gz/tgz/arc/7z
bookmarksurl/lnk/sym/desktop/website
ebooksepub/mobi/azw/prc/azw1/azw3/azw4/azw8/azk
emailseml/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 入口再上线,避免踩官方文档笔误。

八、参考链接

  1. 官方《External Configuration》页(本篇全部参数语义来源):https://docs.tagspaces.org/dev/external-config/
  2. 官方 Docker 部署教程(extconfig.js 放置位置与安全警告):https://docs.tagspaces.org/tutorials/tagspaces-web-docker/
  3. 官方 MinIO 桶接入教程:https://docs.tagspaces.org/tutorials/setup-minio-bucket-nas/
  4. 本专栏实测系列:《TagSpaces 介绍与选型指南》、《TagSpaces 6.13.9 Docker Compose 部署指南》(部署与读写闭环实测)、《TagSpaces 6.13.9 常用 CLI 命令与工具详解》(索引与打标命令实测)