jetlog 1.2 Docker Compose 部署指南

从零开始在 Linux 服务器上用 Docker Compose 部署 jetlog v1.2 个人飞行日志服务,覆盖镜像选型、首次部署、初始化验证、默认口令修改、数据持久化、版本升级与回滚、备份校验与日常运维命令。

jetlogjetlogDocker Compose自托管2026/10/31

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)
Docker29.9.2(docker --version 实测)
Docker Composev5.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。

三、前置条件

部署前确认服务器具备以下条件,每项给出实测命令:

  1. Docker 与 Compose 插件已安装:
docker --version
docker compose version

实测回显:

Docker version 29.9.2, build a82e528
Docker Compose version v5.6.1
  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 volumejetlog-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 运行并收紧宿主目录权限。

十二、参考链接

本文所有命令与回显实测于 2026-10-31;版本号与镜像体积随时间变化,请以当日官方页面为准。