jetlog 1.2 Docker Compose 部署指南
从零开始在 Linux 服务器上用 Docker Compose 部署 jetlog v1.2 个人飞行日志服务,覆盖镜像选型、首次部署、初始化验证、默认口令修改、数据持久化、版本升级与回滚、备份校验与日常运维命令。
jetlog 1.2 Docker Compose 部署指南
目标:从零开始在 Linux 服务器上用 Docker Compose 部署 jetlog v1.2 个人飞行日志服务,覆盖镜像选型、首次部署、初始化验证、默认口令修改、数据持久化、版本升级与回滚、备份校验与日常运维命令。已在 Ubuntu 22.04 服务器(Docker 29.9.2 + Docker Compose v5.6.1)、服务端口 8142、数据目录
/opt/jetlog/data全流程实测通过。
一、环境信息
本文所有命令与回显均来自下列实测环境,读者复核时版本号可能已更新:
| 项 | 取值 |
|---|---|
| 操作系统 | Ubuntu 22.04(x86_64) |
| Docker | 29.9.2(docker --version 实测) |
| Docker Compose | v5.6.1(docker compose version 实测) |
| jetlog 版本 | v1.2(pbogre/jetlog:1.2,Releases 页当前最新稳定版) |
| 服务端口 | 8142(宿主侧)→ 3000(应用监听,JETLOG_PORT 默认值) |
| 数据目录 | /opt/jetlog/data(bind mount 到数据路径 /data) |
| 默认账号 | admin / admin(首次启动自动创建,改密后为 admin / q1w2e3r4) |
| 实测时间 | 2026-10-31 |
版本号以官方 Releases 页为准(查询日期 2026-10-31),组件背景、架构与同类对比见 《jetlog 介绍与选型指南》。
二、镜像选型说明
jetlog 官方只发布 Docker 镜像与源码两种形态,官方 README 的 Getting Started 直接以 docker-compose.yml 起步。镜像托管在 Docker Hub(pbogre/jetlog),按官方 Installation Wiki 的 tag 策略有三种选择(查询日期 2026-10-31):
| tag | 含义 | 适用场景 |
|---|---|---|
latest | 最新稳定版,随发布滚动 | 想始终用最新版、可接受偶发变化 |
experimental | 未充分测试的新特性 | 尝鲜、提前验证新特性 |
x.x.x(如 1.2) | 锁定具体版本 | 生产长期运行、可复现升级 |
💡 说明:本文全部实测使用
pbogre/jetlog:1.2(锁定版本)。本地实测拉取后的占用:1.2为 408MB、上一稳定版1.1.7为 419MB,均支持linux/amd64与linux/arm64双架构。
docker images pbogre/jetlog --format '{{.Repository}}:{{.Tag}} {{.Size}}'
实测回显:
pbogre/jetlog:1.2 408MB
pbogre/jetlog:1.1.7 419MB
选型建议:生产环境锁定 x.x.x 版本 tag,升级时显式改 tag 重拉,可复现、可回滚;不建议在生产追 latest。
三、前置条件
部署前确认服务器具备以下条件,每项给出实测命令:
- Docker 与 Compose 插件已安装:
docker --version
docker compose version
实测回显:
Docker version 29.9.2, build a82e528
Docker Compose version v5.6.1
- 端口未被占用(本文用 8142,可按需更换):
ss -ltn | grep -w 8142 || echo "8142 空闲"
实测回显:
8142 空闲
⚠️ 注意:数据目录
./data不必提前创建,Compose 在启动时会对缺失的 bind mount 宿主目录自动建目录;jetlog 把全部数据存在该目录下的单个 SQLite 文件jetlog.db,请确保落在持久盘上,备份即备份该目录(见第十章)。
四、部署步骤
本节从空目录开始完整走一遍部署,每步命令与回显均为实测。
4.1 编写 docker-compose.yml
在 /opt/jetlog/ 下创建 docker-compose.yml(内容与实测部署一致):
name: jetlog
services:
jetlog:
image: pbogre/jetlog:1.2
restart: unless-stopped
volumes:
- ./data:/data
environment:
JETLOG_PORT: 3000
SECRET_KEY: "b2lab-Xk9mQ2vT7wZr4Nb8Cd1Ef3Gh5Jl6Mn0Pq7Rs9Tu2Vx4zA6bY8dF0"
TOKEN_DURATION: 7
ENABLE_EXTERNAL_APIS: "false"
PUID: 1000
PGID: 1000
ports:
- "8142:3000"
networks:
- jetlog-net
networks:
jetlog-net:
driver: bridge
ipam:
config:
- subnet: 10.89.65.0/24
逐项说明:
image: pbogre/jetlog:1.2:锁定版本(第二章选型结论);restart: unless-stopped:除手动停止外随系统自启;volumes: ./data:/data:把宿主目录挂为数据路径/data,SQLite 文件落宿主盘;JETLOG_PORT: 3000:应用内部监听端口,保持默认 3000 即可,对外端口由ports左侧控制;SECRET_KEY:JWT 签名密钥,必填,改一次则全体已登录令牌失效;生产请换成自己的长随机串(可用openssl rand -base64 48生成);TOKEN_DURATION: 7:登录令牌有效期 7 天(整数,单位天);ENABLE_EXTERNAL_APIS: "false":关闭对公共航班号查询服务的出站调用(隐私优先;为true时可按航班号自动补全航司);PUID/PGID: 1000:以 uid/gid 1000 运行服务进程并把数据目录属主改为该身份;ports: "8142:3000":宿主 8142 → 应用 3000;networks:独立网段 10.89.65.0/24,避免与其他服务网段冲突(可省略,省略时 Compose 自动建默认网络)。
4.2 启动服务
cd /opt/jetlog && docker compose up -d
实测回显(全新部署,首次创建网络与服务):
Network jetlog_jetlog-net Creating
Network jetlog_jetlog-net Created
Container jetlog-jetlog-1 Creating
Container jetlog-jetlog-1 Created
Container jetlog-jetlog-1 Starting
Container jetlog-jetlog-1 Started
4.3 观察首次初始化日志
docker compose logs
实测回显(全新数据目录的首启日志,节选至初始化完成;初始化在收到首个请求时触发):
jetlog-1 | Container running as root, setting permissions to 1000:1000...
jetlog-1 | INFO: Started server process [11]
jetlog-1 | INFO: Waiting for application startup.
jetlog-1 | INFO: Application startup complete.
jetlog-1 | INFO: Uvicorn running on http://0.0.0.0:3000 (Press CTRL+C to quit)
jetlog-1 | Initializing database connection
jetlog-1 | Database file not found, creating it...
jetlog-1 | Creating first user admin:admin...
jetlog-1 | REMEMBER TO CHANGE THE DEFAULT PASSWORD FOR THIS USER!!!
jetlog-1 | Updating airports and airlines tables...
jetlog-1 | Database initialization complete
jetlog-1 | INFO: 10.89.65.1:56582 - "GET / HTTP/1.1" 200 OK
解读:首行说明进程先以 root 启动、把数据目录属主改为 PUID:PGID(1000:1000)再降权运行;Database file not found 起的五行是 SQLite 数据库初始化——建库、创建默认账号 admin/admin、导入内置机场与航司参考数据(来自 OurAirports 数据集,几秒完成)。
4.4 验证服务与默认登录
docker compose ps --format 'table {{.Name}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}'
curl -s -o /dev/null -w '首页 %{http_code}\n' http://127.0.0.1:8142/
实测回显:
NAME IMAGE STATUS PORTS
jetlog-jetlog-1 pbogre/jetlog:1.2 Up 5 seconds 0.0.0.0:8142->3000/tcp, [::]:8142->3000/tcp
首页 200
用默认账号换取 API 令牌(curl 实测;浏览器访问 http://<服务器IP>:8142/ 在登录页输入同样账号亦可):
curl -s -X POST -d 'username=admin&password=admin' http://127.0.0.1:8142/api/auth/token
实测回显(输出节选,令牌中间截断):
{"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhZG1pbiIsImV4cCI6MTc5Mzk4...","token_type":"bearer"}
💡 技术拓展:
restart策略决定服务随系统与异常退出的自启行为,常用取值对比——
策略 行为 适用场景 no默认,从不自动重启 临时调试 on-failure仅在非 0 退出时重启 可预期会失败退出的任务 always总是重启(含手动 stop 后 daemon 重启时) 需要绝对常驻 unless-stopped总是重启,但手动 stop 后不再拉起 常规自托管服务 本文采用
unless-stopped:日常手动停服维护后不会被意外拉起,服务器重启后又能自动恢复。
4.5 立即修改默认口令
官方在日志中直接警告 REMEMBER TO CHANGE THE DEFAULT PASSWORD FOR THIS USER!!!。用刚才的令牌调用户接口改密(示例改为 q1w2e3r4):
NT=$(curl -s -X POST -d 'username=admin&password=admin' http://127.0.0.1:8142/api/auth/token | sed -E 's/.*"access_token":"([^"]+)".*/\1/')
curl -s -X PATCH -H "Authorization: Bearer $NT" -H 'Content-Type: application/json' \
-d '{"password":"q1w2e3r4"}' http://127.0.0.1:8142/api/users/admin
实测回显:
null
验证新口令生效、旧口令失效:
curl -s -X POST -d 'username=admin&password=admin' -o /dev/null -w '旧密码 %{http_code}\n' http://127.0.0.1:8142/api/auth/token
curl -s -X POST -d 'username=admin&password=q1w2e3r4' -o /dev/null -w '新密码 %{http_code}\n' http://127.0.0.1:8142/api/auth/token
实测回显:
旧密码 401
新密码 200
⚠️ 注意:
SECRET_KEY与口令共同决定登录态安全。若怀疑泄露,改SECRET_KEY重建服务即可让全部已发令牌立即失效(跨密钥令牌互不认账,实测见第十一章)。
五、数据持久化说明
jetlog 的全部业务数据(用户、航班、设置)与内置参考数据(机场/航司库)都在数据目录下的单个 SQLite 文件里:
ls -la /opt/jetlog/data/
实测回显:
total 1420
drwxr-xr-x 2 root root 4096 Oct 31 00:53 .
drwxr-xr-x 3 root root 4096 Oct 31 00:53 ..
-rw-r--r-- 1 yahui yahui 1441792 Oct 31 00:53 jetlog.db
- 文件初始约 1.4MB(含全套机场/航司参考库),随航班数缓慢增长;
- 属主为
1000:1000(PUID/PGID生效结果),升级或重建服务不影响该文件; - 只要把
./data目录留在宿主盘,销毁并重建服务(docker compose down && up -d)后数据原样保留; - 跨版本兼容实测:把该文件从 v1.2 切到 v1.1.7 再切回(见第十章升级与回滚),登录与数据均正常。
💡 技术拓展:持久化两种常见形态对比——
形态 写法 特点 适用 bind mount ./data:/data数据在指定目录,肉眼可见、随手备份 单机自托管(本文采用) named volume jetlog-data:/data由 Docker 统一管理,迁移需 volume命令不方便管目录的环境 本文采用 bind mount:jetlog 数据就是单文件,直接可见、直接
cp备份最直观。
六、环境变量表
jetlog 的行为全部由环境变量驱动(没有配置文件),可用变量汇总如下(默认值取自官方镜像内置定义,均为实测核对):
| 变量 | 必填 | 默认值 | 作用 | 实测要点 |
|---|---|---|---|---|
SECRET_KEY | 是 | 无 | JWT 签名密钥 | 缺失直接拒绝启动并报 Environment variable 'SECRET_KEY' is not set. Aborting... |
DATA_PATH | 是 | /data | 数据目录路径 | 换路径后数据库在新路径创建;镜像已声明该路径为数据卷 |
JETLOG_PORT | 否 | 3000 | 应用监听端口 | 设为 8139 实测监听 http://0.0.0.0:8139 |
TOKEN_DURATION | 否 | 7 | 令牌有效期(天) | 填非整数启动即报 should be an integer;设 1 实测令牌 exp 恰为 +1 天 |
ENABLE_EXTERNAL_APIS | 否 | true | 是否调用外部航班号查询服务 | 设 false 后调用补全接口返回 400(隐私开关,见 C1 篇实测) |
PUID / PGID | 否 | 1000 / 1000 | 运行身份与数据目录属主 | 首启日志 setting permissions to 1000:1000,落盘文件属主实测 1000:1000 |
USE_IPV6 | 否 | false | 监听 IPv6(::) | 设 true 实测日志变为 http://[::]:3000;配合默认端口发布时宿主侧不可达,需同栈转发 |
JETLOG_BASE_URL | 否 | / | 子路径部署声明 | 设 /jetlog/ 后 /config 返回 BASE_URL:/jetlog/;应用不直接响应带前缀路径,须反代剥前缀 |
AUTH_HEADER | 否 | 无 | 反代请求头认证的头部名 | 设置后该头部即视为登录身份,且优先于 Bearer 令牌(安全责任在反代,慎用) |
💡 说明:上表是速查版;每个变量的逐项对照实验(含完整请求/回显与报错原文)沉淀在 《jetlog 1.2 配置参数详解》,建议调参前先读该篇。
七、配置参数说明
第四章 compose 文件中的关键配置展开说明,便于按环境裁剪:
- 端口规划:对外端口只改
ports左侧(如"8142:3000");若想连应用监听端口一起改(如内网直通场景),把JETLOG_PORT与ports右侧一起改(JETLOG_PORT: 3000→8139配"8142:8139"),两者不必相同。 - SECRET_KEY 强度:JWT 采用 HS256 对称签名,密钥即信任根。建议 ≥48 字符随机串;本文示例值仅用于演示环境。密钥变更的连带影响(全部令牌失效、跨实例令牌互拒)已在第十一章与 C1 篇实测。
- TOKEN_DURATION 与安全平衡:单位是天、必须整数。个人自托管 7 天是官方默认;缩短到 1 天意味着每天重新登录(实测 exp 恰为签发时刻 +1 天)。
- ENABLE_EXTERNAL_APIS 与隐私:
true时仅一个出站用途——按航班号到公共查询服务补全航司信息;jetlog 不上报任何用户数据(官方 Privacy Notice)。纯内网环境建议false。 - PUID/PGID 与目录权限:服务进程以 root 起步仅为了改属主,随后降权到
PUID:PGID运行。若数据目录属主与PUID/PGID不匹配且无法 chown,进程会直接以 root 运行并打日志Could not set data folder ownership, running Jetlog as root...(源码内置的兜底路径)。 - 网段隔离:
networks.jetlog-net的subnet: 10.89.65.0/24是实测值示例;多套自托管栈共存时给每个栈分配不重叠的网段可避免地址冲突,不需要时可整段删掉。
八、配置文件挂载
jetlog 没有任何「配置文件」——配置面只有环境变量(第六章),数据面只有 /data 目录下的 jetlog.db。因此本部署没有需要挂载的配置文件,标准做法是:
- 改配置 → 编辑 compose 的
environment:段 →docker compose up -d重建生效; - 只有数据目录需要挂载(
./data:/data),且强烈建议保持挂载,否则数据随服务销毁而丢失(第五、十章)。
若未来需要挂只读的附加内容(如自定义证书),同样往 volumes: 段加一行 ./xxx:/xxx:ro 即可,模式与数据目录一致。
九、等价 docker run
不使用 Compose 时,等价的一次性启动命令为(参数与第四章 compose 一一对应):
docker run -d \
--name jetlog \
--restart unless-stopped \
-p 8142:3000 \
-v /opt/jetlog/data:/data \
-e JETLOG_PORT=3000 \
-e SECRET_KEY="b2lab-Xk9mQ2vT7wZr4Nb8Cd1Ef3Gh5Jl6Mn0Pq7Rs9Tu2Vx4zA6bY8dF0" \
-e TOKEN_DURATION=7 \
-e ENABLE_EXTERNAL_APIS="false" \
-e PUID=1000 \
-e PGID=1000 \
pbogre/jetlog:1.2
实测回显(64 位十六进制串即启动成功的回执):
f844cbe3c01f59d5587ac2fd3a0d9d0eb0d6c83454a1d5e79dd62302c97a27bc
本等价命令实测验证:启动后 curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8142/ 返回 200,与 Compose 方式行为一致。
⚠️ 注意:
docker run方式没有 Compose 的编排能力(升级要docker stop+docker rm+ 重新run,改环境变量也要重建),长期运行建议仍用第四章的 Compose 方式;本节仅作等价性参考。
十、常用运维命令
以下命令均在 /opt/jetlog/ 目录内执行(compose 项目名 jetlog),全部实测。
10.1 日常状态与日志
docker compose ps
docker compose logs --tail 20
docker compose restart
实测回显(restart 与 logs 节选):
Container jetlog-jetlog-1 Started
jetlog-1 | INFO: 10.89.65.1:59238 - "GET /config HTTP/1.1" 200 OK
docker compose stop
docker compose start
实测回显:
Container jetlog-jetlog-1 Stopped
Container jetlog-jetlog-1 Started
10.2 升级与回滚(版本切换实测)
jetlog 数据是单文件 SQLite,跨小版本可直接切换。实测把 1.2 切到上一稳定版 1.1.7 再切回,全程数据无损:
sed -i 's|pbogre/jetlog:1.2|pbogre/jetlog:1.1.7|' docker-compose.yml
docker compose up -d
docker compose ps --format 'table {{.Name}}\t{{.Image}}\t{{.Status}}'
实测回显:
NAME IMAGE STATUS
jetlog-jetlog-1 pbogre/jetlog:1.1.7 Up 5 seconds
降版本后验证登录(admin/q1w2e3r4)返回 200、/config 正常:
{"BASE_URL":"/","ENABLE_EXTERNAL_APIS":false}
切回新版同理(tag 换回 1.2 再 up -d),实测 ps 显示 pbogre/jetlog:1.2、/config 正常。
⚠️ 注意:切换前先按 10.3 备份数据文件;跨大版本升级前先读官方 Releases 的破坏性变更说明。升级拉取新镜像时用
docker compose pull,实测回显:Image pbogre/jetlog:1.2 Pulling Image pbogre/jetlog:1.2 Pulled
10.3 备份与完整性校验
cp /opt/jetlog/data/jetlog.db /opt/jetlog/jetlog-backup-20261031.db
ls -la /opt/jetlog/jetlog-backup-20261031.db
实测回显:
-rw-r--r-- 1 root root 1441792 Oct 31 00:50 /opt/jetlog/jetlog-backup-20261031.db
用镜像内置的 sqlite3 做完整性校验(宿主机不必装 SQLite):
docker run --rm --entrypoint sqlite3 -v /opt/jetlog/data:/data:ro pbogre/jetlog:1.2 /data/jetlog.db 'PRAGMA integrity_check;'
实测回显:
ok
恢复:停服(docker compose stop)→ 用备份覆盖 data/jetlog.db → docker compose start,再跑一次 PRAGMA integrity_check; 确认 ok。
10.4 卸载
cd /opt/jetlog && docker compose down
实测回显(down 会一并删除项目网络):
Container jetlog-jetlog-1 Removed
Network jetlog_jetlog-net Removing
Network jetlog_jetlog-net Removed
确认不再需要数据后删除数据目录:
rm -rf /opt/jetlog/data
十一、常见问题
Q1:启动立刻退出,日志出现 Environment variable 'SECRET_KEY' is not set. Aborting...
实测复现(去掉 SECRET_KEY 启动):
Container running as root, setting permissions to 1000:1000...
Environment variable 'SECRET_KEY' is not set. Aborting...
原因与解决:SECRET_KEY 是必填项,补上该环境变量后 docker compose up -d 即可。
Q2:启动报 TOKEN_DURATION' should be an integer, got 'seven'
实测回显:
Environment variable 'TOKEN_DURATION' should be an integer, got 'seven'
原因与解决:TOKEN_DURATION 只接受整数(单位天),改成 7 这类数字后重建。
Q3:换了 SECRET_KEY 后所有人被登出 / 令牌在另一套部署上无效
实测:把 A 实例签发的 Bearer 令牌拿到 SECRET_KEY 不同的 B 实例上调用受保护接口,返回 401 与 {"detail":"Invalid token"},反向同样。这是预期行为:令牌由密钥签名,跨密钥即无效。恢复办法是各用各的令牌重新登录;有意全员登出时改密钥重建即可。
Q4:端口起不来 / 页面打不开
先 docker compose ps 看状态与端口映射(应有 0.0.0.0:8142->3000/tcp),再 ss -ltn | grep 8142 确认宿主监听存在;若端口被其他服务占用,换 ports 左侧端口重建。实测健康探针:curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8142/ 返回 200。
Q5:USE_IPV6=true 后宿主机连不上
实测现象:日志确认监听 http://[::]:3000,但默认 -p 端口发布下从宿主侧以 IPv4/IPv6 回环访问均失败。该开关面向「宿主与栈同处 IPv6 网络栈」的部署形态(如宿主网络模式或由同栈反代转发);常规端口发布场景保持默认 false 即可。
Q6:数据目录权限报错后以 root 运行
日志出现 Could not set data folder ownership, running Jetlog as root... 说明 PUID/PGID 的 chown 失败(目录在别的文件系统/只读挂载等)。能改属主就 chown -R 1000:1000 /opt/jetlog/data 后重建;不能改则接受 root 运行并收紧宿主目录权限。
十二、参考链接
- 官方 GitHub 仓库:https://github.com/pbogre/jetlog(README Getting Started、LICENSE)
- Installation Wiki(环境变量表、镜像 tag 策略):https://github.com/pbogre/jetlog/wiki/Installation
- Releases 版本页:https://github.com/pbogre/jetlog/releases(v1.2 发布说明)
- Docker Hub 镜像页:https://hub.docker.com/r/pbogre/jetlog
- 本专栏相关篇目:《jetlog 介绍与选型指南》(认知与选型)、《jetlog 1.2 配置参数详解》(环境变量逐项实测)、《jetlog 1.2 REST API 使用详解》(接口实测)
本文所有命令与回显实测于 2026-10-31;版本号与镜像体积随时间变化,请以当日官方页面为准。