jetlog 1.2 配置参数详解

jetlog 1.2 全部环境变量逐项实测详解:SECRET_KEY 必填校验与跨实例令牌互拒、TOKEN_DURATION 令牌有效期解码、AUTH_HEADER 反代头认证覆盖实验、JETLOG_PORT/USE_IPV6/JETLOG_BASE_URL 网络三件套、ENABLE_EXTERNAL_APIS 隐私开关、PUID/PGID 运行身份,含报错原文与生产配置模板。

jetlogjetlogSQLite环境变量2026/10/31

jetlog 1.2 配置参数详解

目标:把 jetlog v1.2 的全部环境变量逐一讲清——参数含义、默认值、生效行为与错误形态,每个结论都来自独立对照实验的真实请求与回显。已在 Ubuntu 22.04 服务器(jetlog v1.2,多组对照实例并存)逐项实测通过,实验日期 2026-10-31。

一、环境信息

本文的每个参数都做了「改一个变量、起一个对照实例、发真实请求验证」的实验,环境如下:

项取值
操作系统Ubuntu 22.04(x86_64)
jetlog 版本v1.2(pbogre/jetlog:1.2,官方最新稳定版)
实测方式多组单变量对照实例(每组只改一个环境变量,其余同默认),curl 发请求核对行为
主实例端口8134(SECRET_KEY 56 字符、TOKEN_DURATION=7、ENABLE_EXTERNAL_APIS=true)
对照实例端口8137(TOKEN_DURATION=1)、8139(JETLOG_PORT=8139)、8135(JETLOG_BASE_URL=/jetlog/)、8140(AUTH_HEADER=X-Auth-User)、8141(DATA_PATH=/var/lib/jetlog)、8142(ENABLE_EXTERNAL_APIS=false)
实测工具curl、JWT 解码(base64)、启动日志比对
实测日期2026-10-31

jetlog 的配置面只有环境变量——没有配置文件,改配置即改部署编排的 environment: 段。部署方法本身见 《jetlog 1.2 Docker Compose 部署指南》第四章,组件背景见 《jetlog 介绍与选型指南》。

二、前置条件

复现本文实验只需三样东西:

  1. 一套正在运行的 jetlog v1.2 服务(部署方法见 B2 篇),记下其访问端口;
  2. curl(发请求)与任意 JWT 解码手段(本文用 Python 标准库 base64);
  3. (可选)再部署第二套不同 SECRET_KEY 的实例,用于跨实例令牌互拒实验——两套实例必须使用不同密钥,否则看到的就是同一实例的行为。

参数归属说明:jetlog 的环境变量分两层——SECRET_KEY/DATA_PATH/AUTH_HEADER/TOKEN_DURATION/ENABLE_EXTERNAL_APIS 是应用在启动时主动读取的;JETLOG_PORT/USE_IPV6/JETLOG_BASE_URL/PUID/PGID/APP_PATH 由官方镜像的启动入口脚本与镜像定义消费。对使用者来说都是同一个改法:改 environment: 后重建生效。

三、参数查看与修改方式

查看生效值:应用内置了一个无需认证的配置自省端点,直接 GET:

curl -s http://127.0.0.1:8134/config

实测回显(主实例,ENABLE_EXTERNAL_APIS=true):

{"BASE_URL":"/","ENABLE_EXTERNAL_APIS":true}

对照实例(ENABLE_EXTERNAL_APIS=false):

{"BASE_URL":"/","ENABLE_EXTERNAL_APIS":false}

/config 只暴露两件事:子路径声明 BASE_URL 与外部 API 开关。其余变量从启动日志与部署编排中核对:docker compose logs 首行可见 setting permissions to ${PUID}:${PGID} 的实际值,docker compose exec jetlog env | grep -E 'JETLOG|SECRET|TOKEN|ENABLE|PUID|PGID|DATA_PATH' 可见全部注入值(输出含密钥,注意不要截图外传)。

修改方式:编辑部署编排(docker-compose.yml)的 environment: 段,然后重建——环境变量不是热更新的,进程启动时读取一次:

cd /opt/jetlog
# 编辑 docker-compose.yml 的 environment: 段
docker compose up -d

实测回显(环境变更后 Compose 自动重建):

 Container jetlog-jetlog-1 Recreate
 Container jetlog-jetlog-1 Recreated
 Container jetlog-jetlog-1 Starting
 Container jetlog-jetlog-1 Started

重建后用 /config、启动日志或实际行为验证新值已生效(下文每节都有对应验证)。

四、参数总览

jetlog v1.2 全部环境变量一览(默认值取自官方镜像内置定义并经实测核对):

变量必填默认值类别一句话作用
SECRET_KEY是无认证安全JWT 登录令牌的签名密钥
DATA_PATH是/data数据SQLite 数据库所在目录
TOKEN_DURATION否7认证安全登录令牌有效期(整数,天)
AUTH_HEADER否无(禁用)认证安全反代请求头认证的头部名
JETLOG_PORT否3000网络应用监听端口
USE_IPV6否false网络监听 IPv6 通配地址 ::
JETLOG_BASE_URL否/网络反向代理子路径部署声明
ENABLE_EXTERNAL_APIS否true隐私是否调用外部航班号查询服务
PUID / PGID否1000 / 1000运行身份进程运行 uid/gid 与数据目录属主
APP_PATH只读/app镜像内置应用安装目录(镜像内固定,无需改)

关键差异与阅读建议:必填的只有两个(缺了直接拒绝启动,报错原文见 5.1 与 5.4);多数场景只碰 SECRET_KEY、TOKEN_DURATION、ENABLE_EXTERNAL_APIS 三个;网络三件套(JETLOG_PORT/USE_IPV6/JETLOG_BASE_URL)只在特殊接入形态下才需要动。下文按类别逐项给出实测。

五、核心参数分类详解

5.1 认证与安全:SECRET_KEY、TOKEN_DURATION、AUTH_HEADER

SECRET_KEY(必填)——JWT 的 HS256 对称签名密钥,是整套登录体系的信任根:签发令牌用它签名,校验令牌用它验签。缺失时拒绝启动,实测(去掉该变量启动):

Container running as root, setting permissions to 1000:1000...
Environment variable 'SECRET_KEY' is not set. Aborting...

💡 技术拓展:JWT 签名算法不止对称一种,选型对比——

算法族代表密钥形态特点与适用
对称HS256单一共享密钥签发与校验同一方,部署最简(jetlog 采用)
非对称RS256/ES256私钥签发 + 公钥校验多方校验时不必分发私钥,适合大型 SSO
无签名none无明文本体,仅调试,禁止生产

jetlog 固定使用 HS256(源码 ALGORITHM = "HS256"),单服务单密钥的形态与之匹配;代价是密钥即一切——泄露等同全员账号沦陷,故务必长随机(≥48 字符,openssl rand -base64 48 生成)。

「密钥即信任根」的直接后果是跨密钥令牌互不认账,实测把实例 A(密钥 X)签发的令牌拿到密钥 Y 的实例 B 上用:

curl -s -o /dev/null -w '%{http_code}\n' -H "Authorization: Bearer $TOKEN_A" http://127.0.0.1:8134/api/users/me

实测回显(A 实例令牌打 B 实例;反向同样 401):

401
{"detail":"Invalid token"}

因此:换 SECRET_KEY = 全员登出(可用作应急手段);多套部署绝不能共用密钥(否则一套泄露、令牌全网通用)。

TOKEN_DURATION(默认 7,单位天,必须整数)——登录令牌的有效期,签发时写进 JWT 的 exp 字段。解码主实例(=7)的令牌实测:

python3 -c "
import base64, json, datetime
p = TOKEN.split('.')[1]; p += '=' * (-len(p) % 4)
d = json.loads(base64.urlsafe_b64decode(p))
print('payload:', d, '| exp =', datetime.datetime.fromtimestamp(d['exp']))"

实测回显:

payload: {'sub': 'admin', 'exp': 1793978390} | exp = 2026-11-06 23:19:50

签发时刻是 2026-10-30 23:19:50——exp 恰为签发 +7 天。把对照实例设为 TOKEN_DURATION=1 再登录解码,实测 exp = 2026-11-01 00:51:25,与其登录时刻 2026-10-31 00:51:25 精确 +1 天,两个取样互相印证「值 = 天数」。

类型校验实测(填非整数 seven 启动):

Environment variable 'TOKEN_DURATION' should be an integer, got 'seven'

AUTH_HEADER(默认不启用)——反向代理场景的「请求头认证」:设置后,只要请求携带同名请求头,其值就被当作用户名直接采信,且优先于 Bearer 令牌。实测实例设 AUTH_HEADER=X-Auth-User:

# 带头部、不带任何令牌
curl -s -H 'X-Auth-User: admin' http://127.0.0.1:8140/api/users/me

实测回显:

{"id":1,"username":"admin","passwordHash":"$argon2id$v=19$m=65536,t=3,p=4$...","isAdmin":true,"lastLogin":null,"createdOn":"2026-10-30T16:43:57"}

三个值得注意的实测细节:lastLogin 为 null——走头部认证不更新最后登录时间;头部里的用户名不存在时返回 403 与原文 {"detail":"Username supplied in header does not exist, please have your instance admin create this user."};完全不带头部则回到令牌校验,无令牌实测返回 401 与 {"detail":"Invalid token"}。

「优先于令牌」的覆盖性实测——坏令牌 + 好头部照样 200:

curl -s -o /dev/null -w '%{http_code}\n' -H 'Authorization: Bearer bad.token.here' -H 'X-Auth-User: admin' http://127.0.0.1:8140/api/users/me

实测回显:

200

⚠️ 注意:这个头部谁都能伪造,身份真实性完全押在反代身上(反代必须剥掉外部传入的同名头部、只注入自己认证后的值)。官方文档对它的评价是「不清楚就不要用」——没接好 SSO 就保持默认不启用。

5.2 网络与接入:JETLOG_PORT、USE_IPV6、JETLOG_BASE_URL

JETLOG_PORT(默认 3000)——应用进程的监听端口(uvicorn 启动参数)。对照实例设 JETLOG_PORT=8139,启动日志实测:

Container running as root, setting permissions to 1000:1000...
INFO:     Started server process [11]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:8139 (Press CTRL+C to quit)

curl http://127.0.0.1:8139/ 实测 200。注意它只是「应用内部监听口」,对外暴露哪个端口由部署编排的端口映射左侧决定,两者不必相同(如映射 "8142:8139")。

USE_IPV6(默认 false)——设为 true 时监听地址从 0.0.0.0 换成 ::,实测日志:

INFO:     Uvicorn running on http://[::]:3000 (Press CTRL+C to quit)

但实测发现一个关键限制:在该实例内部 curl http://localhost:3000/ 与 curl -g 'http://[::1]:3000/' 均 200(应用本身在 :: 上工作正常),而通过常规端口映射从宿主侧访问(IPv4 回环与 IPv6 回环都试了)连接失败。结论:USE_IPV6=true 面向宿主与应用同处一个 IPv6 网络栈的部署形态(宿主网络模式、同栈反代转发);常规端口映射发布下保持默认 false。

JETLOG_BASE_URL(默认 /)——把 jetlog 挂在反代子路径下(如 https://example.com/jetlog/)时声明的路径前缀。对照实例设 JETLOG_BASE_URL=/jetlog/,实测三个事实:

curl -s http://127.0.0.1:8135/config      # 应用自身配置端点
curl -s -w ' [%{http_code}]\n' http://127.0.0.1:8135/jetlog/config
curl -s -o /dev/null -w '/ -> %{http_code}\n' http://127.0.0.1:8135/

实测回显:

{"BASE_URL":"/jetlog/","ENABLE_EXTERNAL_APIS":true}
{"detail":"Not Found"} [404]
/ -> 200

解读:设了前缀后 /config 正常返回且 BASE_URL 值随之变化(前端单页应用从这里读取前缀、拼装自己的 API 地址),但应用并不直接响应带前缀的路径(/jetlog/config 404)——JETLOG_BASE_URL 只是把前缀「声明」给应用与自动生成的接口文档,真正的路径改写要由反向代理完成:反代把 /jetlog/* 剥掉前缀转发给应用。首页资源全部是相对路径(./assets/...),经反代子路径访问时正好可用。官方 Wiki 提供了对应的 nginx 配置示例。

5.3 隐私与外部调用:ENABLE_EXTERNAL_APIS

jetlog 唯一的外部依赖是公共航班号查询服务(adsbdb),用途仅一个:按航班号自动补全航司信息。本开关就是它的总闸(布尔,字面量 true/false)。两个对照实例同接口对照实测(POST /api/flights/airlines_from_callsigns):

ENABLE_EXTERNAL_APIS=false 实例(8142):

400
{"detail":"This endpoint relies on the use of an external API, which you have opted out of."}

ENABLE_EXTERNAL_APIS=true 实例(8134):

200
{"amountSkipped":1,"amountUpdated":1}

开启时实测效果:库中一条无航司的航班(航班号 MU5301)被自动补全为 CES(China Eastern Airlines),随后导出 CSV 中该行的 airline 列从空变为 CES——闭环确认外部调用真实发生。此外开关状态会如实反映在 /config 端点(第三章两实例回显即为 true/false 各一)。

选型建议:内网/离线/隐私优先环境设 false,无副作用(只是失去自动补全,手工填写航司不受影响);联网且想省事保持默认 true。

5.4 运行身份与数据:PUID、PGID、DATA_PATH

PUID/PGID(默认 1000/1000)——启动入口先以 root 运行,把数据目录属主改成 PUID:PGID,再降权到该身份跑应用。主实例首启日志实测:

Container running as root, setting permissions to 1000:1000...

落盘验证:数据目录中的数据库文件属主实测为 1000:1000:

-rw-r--r-- 1 yahui yahui 1441792 Oct 31 00:53 jetlog.db

(yahui 是宿主上 uid/gid 1000 的账号——文件系统里显示的是名字,本质就是 1000:1000。)当 chown 不可行(目录只读挂载等)时,入口有内置兜底:打日志 Could not set data folder ownership, running Jetlog as root... 后直接以 root 运行。

DATA_PATH(默认 /data,必填)——SQLite 数据库(jetlog.db)所在目录。对照实例设 DATA_PATH=/var/lib/jetlog 并挂载宿主目录,实测新路径落盘:

drwxr-xr-x 2 yahui yahui 4096 Oct 31 00:43 .
-rw-r--r-- 1 yahui yahui 1441792 Oct 31 00:43 jetlog.db

应用在新数据路径上正常服务(首页实测 200)。迁移数据目录 = 停服 → 把 jetlog.db 拷到新路径 → 改 DATA_PATH → 重建。缺失该变量同样拒绝启动(报错形态与 SECRET_KEY 相同的 is not set. Aborting...)。

APP_PATH(镜像内置,只读了解)——应用代码在镜像内的安装目录 /app,镜像定义固定,部署时不需要也不应该改它;列出只为参数全景完整。

六、生产配置模板

模板一:家庭 NAS / 个人服务器(1–2 用户,隐私优先,512MB 内存级别即可承载——jetlog 是单进程 SQLite 应用,镜像实测 408MB)

environment:
  JETLOG_PORT: 3000
  SECRET_KEY: "<openssl rand -base64 48 生成,勿用示例值>"
  TOKEN_DURATION: 7
  ENABLE_EXTERNAL_APIS: "false"
  PUID: 1000
  PGID: 1000

要点:外部 API 关闭、令牌 7 天、PUID/PGID 对齐宿主普通用户;密钥每套部署独立生成。

模板二:公网可达(反代 TLS + 子路径),配合多用户日常使用

environment:
  JETLOG_PORT: 3000
  SECRET_KEY: "<openssl rand -base64 48 生成>"
  TOKEN_DURATION: 3
  ENABLE_EXTERNAL_APIS: "true"
  JETLOG_BASE_URL: "/jetlog/"
  PUID: 1000
  PGID: 1000

要点:公网暴露时令牌缩到 3 天降低令牌被盗用窗口;子路径挂反代后启用 HTTPS(官方 Wiki 有 nginx 示例);AUTH_HEADER 仅在反代能保证剥除外来同名头部时才考虑启用(5.1 实测过它的覆盖风险);多用户账号管理走应用内管理页或 REST API(见 《jetlog 1.2 REST API 使用详解》第六章)。

两个模板共同的反面清单(均为本文实测依据):不要留默认 admin/admin 口令(B2 篇实测改密流程);不要与其他部署共用 SECRET_KEY(5.1 互拒实验的反面即「共钥互认」);不要把 TOKEN_DURATION 设成非整数(5.1 报错原文)。

七、常见问题

Q1:改了环境变量为什么没生效?

环境变量只在进程启动时读取。只 restart 而编排文件已变更时,用 docker compose up -d 让 Compose 检测差异并重建;重建后用 /config 端点或新行为验证(第三章有完整流程)。

Q2:启动报 Environment variable 'xxx' is not set. Aborting...

必填项缺失:SECRET_KEY 与 DATA_PATH 二者缺一不可(实测原文见 5.1、5.4)。补齐后重建即可。

Q3:所有人突然被登出?

SECRET_KEY 变更会让全部已签发令牌验签失败(5.1 实测跨密钥 401)。若非本人操作,检查编排文件是否被改动;若是有意为之(应急登出),属预期行为,重新登录即可。

Q4:令牌没到 TOKEN_DURATION 天就失效了?

检查是否登录到了另一套部署(不同 SECRET_KEY 的令牌互不认账),或密钥/数据库在两次登录间被重建。同实例同密钥下,exp 精确等于签发时刻 + N 天(5.1 两组解码实测)。

Q5:USE_IPV6=true 后宿主机连不上?

见 5.2 实测:该开关只改监听地址为 ::,常规端口映射下宿主侧不可达。要么保持 false,要么让访问方与应用同处 IPv6 网络栈(宿主网络/同栈反代)。

Q6:挂到反代子路径 /jetlog/ 后 404?

JETLOG_BASE_URL 只是前缀声明(5.2 实测应用不响应带前缀路径),必须在反代上配置剥前缀转发:/jetlog/* → /* 转给应用。前端资源是相对路径,剥前缀后一切正常。

八、参考链接

本文所有对照实验实测于 2026-10-31,jetlog v1.2;参数默认值以官方镜像定义为准,升级后请复核差异。