QuickShare 0.11.4 配置参数详解
QuickShare 0.11.4 全量配置参数详解:六组配置项与四个环境变量的默认值、加载优先级与实测生效证据,附生产配置模板与六类排障实录。
QuickShare 0.11.4 配置参数详解
QuickShare 是一款开箱即用的自托管文件分享服务,但「开箱即用」不等于「无需了解配置」:数据目录放哪、端口怎么改、上传限速多少、验证码开关在哪,这些都在一份配置文件里。本文基于 0.11.4 版本(当前最新稳定版),在真实 Ubuntu 服务器上逐项实测,给出全部配置参数的默认值、生效行为与排障实录。
环境与版本信息如下:
| 项目 | 值 |
|---|---|
| 服务器系统 | Ubuntu 22.04 LTS(x86_64) |
| QuickShare 版本 | 0.11.4(linux amd64 单二进制,官方发行包 quickshare_0.11.4_linux_amd64.zip) |
| 服务二进制 | /opt/quickshare/bin/quickshare(约 32.7 MB,Go 静态编译) |
| 配置文件 | /opt/quickshare/config.json |
| 服务端口 | 8129(本文实测端口,默认 8686) |
| 管理员账号 | admin / q1w2e3r4 |
| 数据目录 | /opt/quickshare/quickshare(含 SQLite 数据库与文件索引) |
组件定位与选型背景见《QuickShare 介绍与选型指南》,安装部署过程见《QuickShare 0.11.4 Docker Compose 部署指南》,本文聚焦其配置体系。
一、前置条件
- 已按部署指南完成 QuickShare 安装,服务可正常启动(
curl http://localhost:8129/v1/settings/health返回正常)。 - 可通过 SSH 登录服务器编辑配置文件,并具备重启服务进程的权限。
- 了解基础 JSON/YAML 语法(配置文件两种格式均支持)。
本文所有实测均在同一台服务器完成:修改配置 → 重启服务 → 用 curl 验证行为变化,命令与输出均为真实记录,可直接复现。
二、配置的加载顺序与修改方式
2.1 五层加载顺序
QuickShare 0.11.4 的配置加载遵循固定顺序,后加载的覆盖先加载的(源码 LoadCfg 的合并顺序):
- 内置默认值:编译在二进制里的默认配置(见第三节总览表)。
- SQLite 数据库中的站点配置:数据库文件已存在时,读取其中保存的前端站点设置(站点名称、背景等,即界面「设置」里改的内容)。
- 配置文件:
-c参数指定的文件,可传多个、按顺序合并;按扩展名解析(.json/.yml/.yaml,其他扩展名直接报错)。 - 命令行参数:
-h/--host、-p/--port、-d/--db(数据库路径),非空时覆盖前面的值。 - 环境变量:仅 4 个——
DEFAULTADMIN、DEFAULTADMINPWD、TOKENSECRET、PORT。其中PORT在服务构造的最后阶段才覆盖端口,是全链路优先级最高的端口配置。
一个典型启动命令:
/opt/quickshare/bin/quickshare -c /opt/quickshare/config.json
2.2 修改配置的四种方式
方式一:配置文件(推荐)。 JSON 或 YAML 皆可,键名用小驼峰(searchResultLimit)。0.11.4 改用 Go 的 JSON 解析,键名大小写不敏感——实测配置文件里写 PascalCase("Port": 8130)同样生效;但官方模板均为小驼峰,建议从众,避免与 0.10.x 时代的大写键格式混淆(见排障实录 6.6)。
方式二:命令行参数。 适合临时验证:./quickshare -c config.json -p 9000 临时换端口启动,不落盘。
方式三:环境变量。 仅 4 个,且各自只在特定时机读取(详见 4.5 节),不是通用配置通道。
方式四:界面/站点动态配置。 登录后在「设置」里修改站点名称、描述、背景,实际写入 SQLite。这类配置只影响前端展示(siteName、siteDesc、背景图等),不涉及端口、限速等服务端参数。
2.3 如何确认修改已生效
配置修改后必须重启服务进程(站点动态配置除外)。重启后三步确认:
# 1. 确认新进程已在跑(旧进程退出需要 1~2 秒,见排障实录 7.2)
pgrep -af quickshare
# 2. 确认监听端口符合预期
curl -s -o /dev/null -w '%{http_code}\n' http://localhost:8129/v1/settings/health
# 3. 查看日志确认启动参数(数据目录下 quickshare.log 亦有同样记录)
启动成功时日志会输出监听地址(JSON 格式,实测节选):
{"level":"info","msg":"quickshare is starting","hostname:port":"0.0.0.0:8130"}
若端口没变,大概率是改错了文件(-c 没指向它)或被环境变量 PORT 抢占(见 4.5 节)。
三、参数总览
0.11.4 配置分六组(server/users/fs/secrets/workers/db),全部键与默认值如下表(源自程序内置默认值,并经实测核对):
| 组 | 键 | 类型 | 默认值 | 说明 |
|---|---|---|---|---|
| server | debug | bool | false | 调试模式(开启后 gin 输出详细日志) |
| server | host | string | 0.0.0.0 | 监听地址 |
| server | port | int | 8686 | 监听端口(可被环境变量 PORT 覆盖) |
| server | readTimeout | int | 2000(毫秒) | 读超时 |
| server | writeTimeout | int | 86400000(毫秒,1 天) | 写超时;同时决定文件读取器的缓存时长 |
| server | maxHeaderBytes | int | 512 | HTTP 头大小上限(实测行为见 5.1) |
| server | dynamic.clientCfg.siteName | string | Quickshare | 站点名称(界面显示) |
| server | dynamic.clientCfg.siteDesc | string | Quick and simple file sharing | 站点描述 |
| server | dynamic.clientCfg.bg | object | 空 | 背景图(url/repeat/position/align/bgColor) |
| server | dynamic.clientCfg.allowSetBg | bool | false | 是否允许普通用户设置背景 |
| server | dynamic.clientCfg.autoTheme | bool | true | 自动主题 |
| users | enableAuth | bool | true | 认证开关,关闭后所有请求按管理员处理(危险,见 5.2) |
| users | cookieTTL | int | 604800(秒,7 天) | 登录 cookie 有效期 |
| users | cookieSecure | bool | false | cookie 仅 HTTPS 传输(公网 HTTPS 部署应开启) |
| users | cookieHttpOnly | bool | true | cookie 禁止 JS 读取(防 XSS 偷 token) |
| users | minUserNameLen | int | 3 | 用户名最小长度 |
| users | minPwdLen | int | 8 | 密码最小长度 |
| users | captchaEnabled | bool | true | 登录验证码开关 |
| users | captchaWidth / captchaHeight | int | 256 / 60 | 验证码图片尺寸(像素) |
| users | uploadSpeedLimit | int | 1048576(B/s,1 MB/s) | 新用户默认上传限速 |
| users | downloadSpeedLimit | int | 1048576(B/s,1 MB/s) | 新用户默认下载限速;低于 102400 启动直接失败 |
| users | spaceLimit | int | 104857600(100 MB) | 新用户默认空间配额 |
| users | limiterCapacity / limiterCyc | int | 1000 / 1000(毫秒) | 请求限流窗口(窗口内最多 1000 次请求) |
| users | predefinedUsers | array | [] | 预置用户列表(name/role/pwd) |
| fs | root | string | quickshare | 数据根目录(相对启动目录或绝对路径) |
| fs | opensLimit | int | 1024 | 文件句柄池上限 |
| fs | openTTL | int | 60(秒) | 句柄空闲回收时间 |
| fs | publicPath | string | static/public | 匿名可访问的公共目录 |
| fs | searchResultLimit | int | 16 | 搜索结果数上限 |
| fs | initFileIndex | bool | true | 启动时初始化文件搜索索引 |
| secrets | tokenSecret | string | 空 | 实测为无效配置(见 4.6,勿依赖) |
| workers | queueSize | int | 1024 | 后台任务队列长度 |
| workers | sleepCyc | int | 1 | 工作协轮询间隔 |
| workers | workerCount | int | 2 | 后台工作协程数 |
| db | dbPath | string | quickshare.sqlite | 数据库文件名(相对 fs.root 拼接) |
💡 技术拓展:QuickShare 的配置体系由作者自研的 gocfg 库驱动,特点是「多层合并、按路径取值」——所有键最终都扁平化成
组.键形式(如Fs.Root),配置文件、命令行、环境变量都只是往这张扁平表里写值,谁后写谁生效。这也是「环境变量优先级可以压过一切」的根源:它不是在启动时读一次,而是在真正使用该值的那一刻才读。
四、核心参数分类详解
4.1 server 组:监听与超时
port(默认 8686)。本文实测将其改为 8130:配置文件写入 {"server": {"port": 8130}},重启后 curl http://localhost:8130/v1/settings/health 立即返回正常,旧端口 8686 不再监听——修改直接生效。
host(默认 0.0.0.0):监听所有网卡。仅本机使用可改为 127.0.0.1,配合反向代理暴露。
readTimeout / writeTimeout(毫秒):默认 2 秒 / 1 天。writeTimeout 有个隐蔽联动——它同时决定文件读取器的缓存时长(源码将 writeTimeout/1000 作为 reader TTL 传入文件系统层),大文件慢速下载场景不要调小这个值。
maxHeaderBytes(默认 512):HTTP 头大小上限。实测这个值的行为比较特殊——用 Python 对服务端发不同大小的自定义请求头(详见 4.1 节实测数据)。
pad=2100B -> HTTP 200
pad=3000B -> HTTP 200
pad=4096B -> HTTP 200
pad=5000B -> HTTP 431
即实际生效的上限约在 4 KB~5 KB 之间,并非字面的 512 字节(登录 cookie 本身就有约 200 字节,日常请求不受影响)。反向代理场景若遇到 431 错误,可调大此值后实测验证。
4.2 users 组:认证、验证码与配额
enableAuth(默认 true):认证总开关。生产环境严禁设为 false——关闭后所有请求(包括未登录的匿名请求)都按管理员身份处理,等于向全网开放管理员权限。它只适合纯内网临时调试。
captchaEnabled(默认 true):登录验证码。实测关闭方式——配置 {"users": {"captchaEnabled": false}} 后重启,登录请求不再携带验证码字段即可通过:
curl -s -c cookie.txt -X POST http://localhost:8130/v1/users/login \
-H 'Content-Type: application/json' \
-d '{"user":"admin","pwd":"q1w2e3r4"}'
# 输出:{"msg":"OK"}
若开启验证码,登录前需先 GET /v1/captchas/ 获取验证码 ID 与图片。公网部署建议保持开启。
minPwdLen(默认 8):新建用户时校验密码长度,短于 8 位会被拒绝。
uploadSpeedLimit / downloadSpeedLimit / spaceLimit:新用户的默认配额(已存在用户的配额存在数据库里,改配置不影响他们)。三者的默认值是 1 MB/s / 1 MB/s / 100 MB。实测一台初始化完成的服务上,管理员账号的实际配额为 1 GB 空间、50 MB/s 上传下载(管理员配额在数据库初始化时单独设定):
{"id":"0","name":"admin","role":"admin","usedSpace":"0",
"quota":{"spaceLimit":"1073741824","uploadSpeedLimit":52428800,"downloadSpeedLimit":52428800}}
注意 downloadSpeedLimit 有启动期校验:低于 102400(100 KB/s)时服务启动直接失败,因为下载按 100 KB 分块读取,限速低于块大小会阻塞。
limiterCapacity / limiterCyc(默认 1000 次 / 1000 毫秒):接口限流窗口——每个用户 1 秒内最多 1000 次请求,超限返回 429。防止脚本爆破登录或爬接口。
predefinedUsers:数组,可在首次初始化时批量创建用户,元素含 name/role/pwd。仅数据库不存在(首次启动)时生效。
4.3 fs 组:存储根目录与搜索
root(默认 quickshare):所有用户文件与数据库的根目录。相对路径相对启动时的工作目录解析。两个实测要点:
- 目录会在启动时自动创建(权限 0760),无需手动 mkdir;
- 目录名不能与工作目录下的同名文件冲突,典型翻车是把二进制命名为
quickshare放在数据目录同级(见排障实录 6.1)。
建议用绝对路径写死,如 {"fs": {"root": "/opt/quickshare/quickshare"}}。
searchResultLimit(默认 16):搜索结果上限。实测将配置文件设为 5 后,创建 6 个名称含 f1~f6 的文件,搜索行为如下(搜索按名称匹配,多个 k 参数为「与」关系):
curl -s -b cookie.txt 'http://localhost:8130/v1/fs/search?k=f1'
# 输出:{"results":["admin/files/srch/f1.txt"]}
curl -s -b cookie.txt 'http://localhost:8130/v1/fs/search?k=f1&k=f2'
# 输出:{"results":[]}
即该参数控制的是单次搜索最多返回的条目数;改小它可以让搜索在大量文件下更快返回。
initFileIndex(默认 true):启动时构建/加载文件名索引(持久化在数据目录 fileindex.jsonl)。关闭后搜索不可用。手动重建索引可调用 PUT /v1/fs/reindex。
opensLimit / openTTL:文件句柄池——高并发上传下载时可调大 opensLimit(默认 1024)。
4.4 workers 与 db 组
workerCount(默认 2)/ queueSize(默认 1024):后台任务协程数与队列长度。QuickShare 的空间用量重算等操作走异步任务队列,多用户高负载时可把 workerCount 调到 4~8。
dbPath(默认 quickshare.sqlite):数据库文件名,相对 fs.root 拼接——实测数据库实际位于数据目录内(<fs.root>/quickshare.sqlite),写绝对路径 d 参数(命令行 -d)可挪到别处。备份数据时需同时备份数据目录下的 SQLite 文件与用户文件。
4.5 环境变量:四个特殊参数
| 环境变量 | 读取时机 | 实测行为 |
|---|---|---|
PORT | 服务构造的最后阶段 | 优先级最高,覆盖配置文件与 -p;只影响监听端口 |
DEFAULTADMIN | 仅数据库不存在(首次初始化)时 | 初始管理员用户名;数据库已存在则完全忽略 |
DEFAULTADMINPWD | 同上 | 初始管理员密码;未设置时随机生成并打印到控制台 |
TOKENSECRET | 服务启动构建 JWT 模块时 | 实测不产生实际安全效果(见 4.6) |
前两个变量配合可做到「首次启动全自动初始化管理员」,这正是部署指南中 Docker 方案的玩法:首次启动注入 DEFAULTADMIN=admin、DEFAULTADMINPWD=q1w2e3r4,之后数据库落盘,再重启时这两个变量即被忽略(改密码请走登录后的「修改密码」接口,而不是改环境变量)。
4.6 secrets.tokenSecret 与 TOKENSECRET 实测真相
这是本文实测中最重要的一个发现,请务必读完。
配置文件里有一组 secrets.tokenSecret,注释声称「留空则自动生成」;环境变量里有 TOKENSECRET。按直觉,它应该是登录令牌(JWT)的签名密钥:设置它可以让登录态跨重启保持有效。实测结论:两者在 0.11.4 中都不起实际作用。
实验一:改变 TOKENSECRET,旧登录态仍然有效。 同一台服务,先正常启动并登录得到 cookie,随后带上 TOKENSECRET=envsec123 重启,再用旧 cookie 访问管理员接口:
# 重启前登录并保存 cookie
curl -s -c r4a.cookie -X POST http://localhost:8130/v1/users/login \
-H 'Content-Type: application/json' -d '{"user":"admin","pwd":"q1w2e3r4"}'
# 输出:{"msg":"OK"}
# 带 TOKENSECRET=envsec123 重启后,旧 cookie 依然有效:
curl -s -o /dev/null -w '%{http_code}\n' -b r4a.cookie http://localhost:8130/v1/users/list
# 输出:200 (按理应因签名密钥变化而失效)
实验二:完全伪造的管理员令牌直接被接受。 取一个真实 token,保持头部与签名不动、仅篡改载荷中的角色字段;再构造一个签名完全随意、但载荷声明自己是管理员的 token:
A.baseline(原始 token) : 200
B.篡改 expire 为过去时间 : {"error":"token is expired"} [401]
C.篡改 role 为 visitor : {"error":"access denied"} [403]
D.完全伪造的 admin token(假签名) : 200
E.不带任何 cookie : {"error":"access denied"} [403]
D 行意味着:任何人按 {uid, user, role, expire} 四个字段的格式拼一个载荷,签名随便填,就能以管理员身份调用接口。B/C 两行进一步说明服务端读到的是篡改后的值(过期检查、角色判断都基于被篡改的载荷),签名校验根本没有发生。
根因(源码核验):QuickShare 使用的 JWT 库 robbert229/jwt v2.0.0 提供了两个方法——Decode(仅解码载荷,不验签)和 DecodeAndValidate(验签)。QuickShare 的令牌校验代码只调用了前者。签名密钥确实参与了签发,但验证环节把它漏掉了,于是密钥是什么、改没改,都不影响结果。
给使用者的建议:
- 不要依赖 0.11.4 的登录令牌做防伪——暴露面管理才是真正的安全边界:不要把服务直接暴露公网,务必置于反向代理 + 访问控制(IP 白名单、VPN、认证网关)之后;
enableAuth保持 true、captchaEnabled保持 true,抬高爆破成本;secrets.tokenSecret与TOKENSECRET写不写都行,写了也无副作用(未来版本修复验签后它们会真正生效,届时不改配置即可平滑过渡);- 关注上游版本更新,升级后重新按实验二验证一次。
五、生产配置模板
5.1 内网小团队模板(JSON,1~10 人,机械盘即可)
{
"server": {
"port": 8686,
"writeTimeout": 86400000
},
"users": {
"captchaEnabled": false,
"uploadSpeedLimit": 10485760,
"downloadSpeedLimit": 10485760,
"spaceLimit": 1073741824
},
"fs": {
"root": "/opt/quickshare/quickshare",
"searchResultLimit": 16
},
"db": {
"dbPath": "quickshare.sqlite"
}
}
要点:内网受信环境可关验证码换取登录便捷;限速放宽到 10 MB/s;每人 1 GB 空间;数据目录用绝对路径避免工作目录漂移。磁盘占用 ≈ 实际文件总量 × 1.1(SQLite 与索引体积很小),内存常驻约 30~60 MB。
5.2 公网/半公网模板(YAML,置于反向代理之后)
server:
port: 8686
writeTimeout: 86400000
maxHeaderBytes: 512
users:
enableAuth: true
captchaEnabled: true
cookieSecure: true
cookieHttpOnly: true
cookieTTL: 86400
minPwdLen: 10
uploadSpeedLimit: 1048576
downloadSpeedLimit: 1048576
spaceLimit: 524288000
limiterCapacity: 300
limiterCyc: 1000
fs:
root: /opt/quickshare/quickshare
searchResultLimit: 8
要点:验证码必开;cookieSecure: true 配合 HTTPS;cookie 有效期缩到 1 天;限流收紧到每秒 300 次防爆破;minPwdLen 提到 10。**再次强调:0.11.4 的令牌不防伪造,公网暴露前必须叠加反向代理层的访问控制。**限速 1 MB/s 时 1 GB 文件约 17 分钟传完,按需调整。
六、常见问题与排障实录
6.1 启动即退出:can not create quickshare folder
现象:把二进制重命名为 quickshare 后直接启动,进程秒退(退出码 1),日志只有一行:
{"level":"fatal","ts":1793504896.9892006,"msg":"can not create quickshare folder: there is a file with same name"}
根因:默认数据目录名恰好也是 quickshare(fs.root 默认值)。启动时程序检查根目录,发现工作目录下已有一个同名文件(就是二进制自己),创建目录失败即 fatal。
解决:二进制改名(如 /opt/quickshare/bin/quickshare 配合不同的工作目录),或显式配置 fs.root 指向别的路径。推荐后者,一劳永逸。
6.2 重启失败:address already in use
现象:改完配置立即重启,新进程报监听失败:
listen error: listen tcp 0.0.0.0:8130: bind: address already in use
根因:QuickShare 收到终止信号后要完成收尾(持久化文件索引、停后台任务、关数据库),实测优雅退出耗时 1~2 秒;旧进程还没释放端口,新进程就抢跑了。旧进程退出阶段的实测现象还包括后台任务打印的收尾日志,此处不赘述。
解决:重启脚本里先确认进程消失再启动:
pkill -f 'quickshare -c' ; sleep 3
pgrep -af quickshare || /opt/quickshare/bin/quickshare -c /opt/quickshare/config.json
6.3 改了配置却不生效的排查清单
按命中率排序:
- 进程唯一性:
pgrep -af quickshare确认没有旧进程还挂在旧端口上(本人在实验中两次因残留旧实例而误判「配置未生效」); -c指向:启动命令里的配置文件路径是否就是刚编辑的那份(多个-c时后面的覆盖前面的);- 环境变量
PORT:若系统服务单元里设了PORT,它会覆盖配置文件里的端口; - 键名拼错:0.11.4 用分层小驼峰(
searchResultLimit),不是 0.10 的大写键(SearchResultLimit)。虽然 JSON 键大小写不敏感,但层级写错(把searchResultLimit放到顶层而非fs组下)一定无效; - 确认手段:改完重启后按 2.3 节三步走,别凭感觉。
6.4 secrets.tokenSecret 写了没反应
现象:配置文件里设置 "secrets": {"tokenSecret": "changed-secret-c1"},重启后预期「旧登录态全部失效」——实际旧 cookie 照样能用。
根因:同 4.6 节——签名验证环节缺失,密钥根本没参与校验;而且即便验签逻辑正常,该配置键也只被存储、不被启动代码读取(程序只读环境变量 TOKENSECRET)。
解决:无需处理,也不要依赖它做任何安全决策。升级新版本后重新验证。
6.5 删除文件报 500:used space can not be negative
现象:删除文件返回 500 {"error":"used space can not be negative"},且文件实际已被删除。
根因:每个用户有「已用空间」计数(SQLite 里),删除文件时会扣减该计数,若计数比文件实际大小还小(历史漂移,例如曾绕过接口直接删过文件、或早期版本 bug),扣减结果为负即报错。实测中计数为 12 时删除 30 字节文件稳定复现。
解决:调用管理员接口触发重算,让程序扫描实际目录重建计数(请求体为字符串格式的用户 ID):
curl -s -b cookie.txt -X PUT http://localhost:8130/v1/fs/used-space \
-H 'Content-Type: application/json' -d '{"userID":"0"}'
# 输出:{"msg":"OK"} (异步重算,稍后查询 usedSpace 已恢复正确)
6.6 从 0.10.x 升级后配置全部失效
现象:沿用旧版单层大写键的 config.json(如 "Root": "quickshare"),0.11.x 启动后一切按默认值跑。
根因:0.10.x 与 0.11.x 的配置结构是两代格式——旧版是单层大写键,0.11.x 改为六组分层小驼峰,旧文件里的键在新版对应不上(JSON 键大小写不敏感救不了「层级不同」的问题),全部被当作未知键忽略。
解决:按第三节总览表重写配置文件;数据库与文件目录结构是兼容的,只需迁移配置。
七、参考链接
- 官方仓库:https://github.com/ihexxa/quickshare
- 官方发行包下载:https://github.com/ihexxa/quickshare/releases
- 本专栏系列:《QuickShare 介绍与选型指南》 · 《QuickShare 0.11.4 Docker Compose 部署指南》 · 配套的《QuickShare 0.11.4 API 使用详解》逐个实测了全部接口的行为