配置

Jant 的配置来自两个地方:

  • 环境变量:控制基础设施和运行时行为
  • 设置页面:站点名称、外观、时区等可在线调整的选项

大多数单站点安装只需要设置一个值:AUTH_SECRET,其余按需配置。

环境变量

使用:

  • wrangler.toml 存放 Cloudflare 的非敏感配置
  • .dev.vars 存放本地 Cloudflare secrets
  • .env 或进程环境变量,供 Node 和 Docker 使用

必需项

所有运行时都必须设置这个变量:

变量 说明
AUTH_SECRET better-auth 用于签名 session cookie 的密钥,至少 32 个字符。不要提交进版本库

不要把 AUTH_SECRET 提交进版本库。

  • Cloudflare 本地开发:放进 .dev.vars
  • Cloudflare 生产环境:用 npx wrangler secret put AUTH_SECRET 作为 Worker secret 设置
  • Node 和 Docker:放进 .env 或进程环境变量

公开 URL 和子路径

大多数情况下,这两个变量都不需要设置。Jant 默认从请求的 host 自动推导 origin,并挂载在根路径下。

变量 说明
SITE_ORIGIN 固定公开 origin,例如 https://example.com。影响 RSS、sitemap、export、auth callbacks 等生成的绝对 URL
SITE_PATH_PREFIX 公开路径前缀,例如 /blog。影响所有路由和静态资源路径

只有在以下情况才需要设置:

  • 站点在反向代理后面,并且反向代理没有正确的传递 Host,导致自动推导的 host 不正确:设置 SITE_ORIGIN=https://example.com
  • 挂在子路径下(例如 example.com/blog):设置 SITE_PATH_PREFIX=/blog
  • 需要写死域名

Node 和 Docker

在 Node 和 Docker 下,Jant 通过 DATABASE_URL 判断数据库运行时:

  • file: 表示 SQLite
  • postgres:postgresql: 表示 Postgres

最小 SQLite 示例:

AUTH_SECRET=your-32-plus-character-secret
SITE_ORIGIN=https://your-jant.example
DATABASE_URL=file:./data/jant.sqlite

最小 Postgres 示例:

AUTH_SECRET=your-32-plus-character-secret
SITE_ORIGIN=https://your-jant.example
DATABASE_URL=postgres://USER:PASSWORD@HOST:5432/DBNAME

Node 和 Docker 的常用变量:

变量 默认值 说明
DATA_DIR ./data 默认 SQLite 和本地媒体路径的基础目录
LOCAL_STORAGE_PATH <DATA_DIR>/media 覆盖本地媒体目录
LOCAL_PUBLIC_URL 未设置 供 Jant 外部直接提供媒体的公开基地址;留空时,Jant 使用自己的 /media/* 路由
HOST 裸 Node 下是 127.0.0.1 jant start 的绑定地址
PORT 3000 jant start 的绑定端口
TRUST_PROXY false 是否信任反向代理传来的转发头

官方 Docker 镜像默认把 DATA_DIR 设为 /var/lib/jant,而 Docker Compose 通常会把 TRUST_PROXY=true

Feed 默认值(可选)

变量 默认值 说明
MAIN_RSS_FEED featured 控制 /feed 返回 featured 还是 latest

featured 默认开启是有意为之。Jant 假设很多帖子应该留在站点上,但不一定要自动成为默认订阅 feed 的内容。

分页(可选)

变量 默认值 说明
PAGE_SIZE 50 timelines 和 APIs 的默认分页大小
SEARCH_PAGE_SIZE 继承 PAGE_SIZE 只覆盖搜索页分页
ARCHIVE_PAGE_SIZE 继承 PAGE_SIZE 只覆盖归档页分页

只有在搜索页或归档页真的需要和全站不同的分页大小时,才去设置 SEARCH_PAGE_SIZEARCHIVE_PAGE_SIZE

存储

存储方式取决于运行时:

运行时 默认值 支持的驱动
Cloudflare Workers r2 r2, s3
Node 和 Docker local local, s3

Node 不支持 r2

Cloudflare 不支持 local

通过 STORAGE_DRIVER 环境变量切换驱动,例如 STORAGE_DRIVER=s3。不设置时使用各运行时的默认值。

对 Node 和 Docker 来说,local 是最快起步的方式;s3 通常是更适合长期生产环境的选择。

本地存储(Node / Docker 下最快起步)

本地存储不需要额外驱动配置。

适合这些场景:

  • 想用最简单的方式跑起来
  • 本地测试
  • 单机的小型安装

默认值:

  • DATA_DIR=./data
  • LOCAL_STORAGE_PATH=<DATA_DIR>/media

如果你想把媒体文件放在别处,可以覆盖这个路径:

LOCAL_STORAGE_PATH=/absolute/path/to/jant-media

只有在另一个 Web 服务器会直接托管这些文件时,才设置 LOCAL_PUBLIC_URL

R2(默认)

Cloudflare Workers 默认使用 R2。

变量 说明
R2_PUBLIC_URL 直接提供媒体文件的公开 URL

R2 本身通过 wrangler.toml 中的 [[r2_buckets]] 绑定来配置。

强烈建议设置 R2_PUBLIC_URL。不设置也能工作,但 Jant 就必须通过 Worker 代理每一次媒体请求。

[vars]
R2_PUBLIC_URL = "https://media.yourdomain.com"

S3 兼容存储

适合在这些场景下使用 S3 兼容存储:

  • 你想在 Node 或 Docker 下使用更推荐的长期存储方案
  • 你想在 Cloudflare 和 Node 之间共用同一套存储后端
  • 你更偏好 S3、Backblaze B2、MinIO、DigitalOcean Spaces 或其他兼容服务
  • 你需要通过预签名 URL 做浏览器直传
变量 说明
STORAGE_DRIVER 设为 s3
S3_ENDPOINT S3 API endpoint
S3_BUCKET Bucket 名称
S3_REGION Bucket 区域,默认是 auto
S3_PUBLIC_URL 上传文件对外提供的公开 URL
S3_ACCESS_KEY_ID 访问密钥,必须保密
S3_SECRET_ACCESS_KEY Secret key,必须保密

示例:

[vars]
STORAGE_DRIVER = "s3"
S3_ENDPOINT = "https://s3.us-east-1.amazonaws.com"
S3_BUCKET = "my-bucket"
S3_REGION = "us-east-1"
S3_PUBLIC_URL = "https://cdn.example.com"

这些凭证应该放进 secrets 存储,不要提交进版本库。

浏览器直传的 CORS

如果你使用 STORAGE_DRIVER=s3,bucket 必须为实际上传来源的站点 origin 开启 CORS。

推荐的 CORS 策略:

[
  {
    "AllowedOrigins": ["https://your-site.example"],
    "AllowedMethods": ["GET", "HEAD", "PUT"],
    "AllowedHeaders": [
      "Content-Type",
      "Content-Disposition",
      "Cache-Control",
      "x-amz-checksum-sha256"
    ],
    "ExposeHeaders": ["ETag"],
    "MaxAgeSeconds": 3600
  }
]

如果你会从多个 origin 上传,就把每个 origin 都显式列出来。

图片变换(可选)

变量 说明
IMAGE_TRANSFORM_URL 图片变换服务的基础 URL

如果你使用 Cloudflare 图片变换,请把它指向真正提供图片的域名,并在后面加上 /cdn-cgi/image

示例:

[vars]
R2_PUBLIC_URL = "https://media.yourdomain.com"
IMAGE_TRANSFORM_URL = "https://media.yourdomain.com/cdn-cgi/image"

或者,当图片仍然通过站点域名代理时:

[vars]
IMAGE_TRANSFORM_URL = "https://yourdomain.com/cdn-cgi/image"

静态资源 CDN(可选)

变量 说明
ASSET_BASE_URL 构建产物 JS/CSS 的对外基础 URL(例如独立 CDN 域)

默认情况下,Jant 把打包后的资源放在站点同源的 /_assets/ 下。只有当你想把这些资源部署到独立域名时,才需要设置 ASSET_BASE_URL

[vars]
ASSET_BASE_URL = "https://cdn.yourdomain.com"

该 CDN 必须允许跨域。 Jant 的客户端代码以 ES module 形式加载(<script type="module">),浏览器对跨源 module 脚本会强制执行 CORS——虽然看起来和普通 JS 没区别,但规则不一样。如果 CDN 不返回 Access-Control-Allow-Origin,浏览器会丢弃响应,站点直接加载失败。

资源服务器有两种配置方式,根据你的部署情况二选一:

方案 A:允许任意来源(最简单)

Access-Control-Allow-Origin: *

打包产物都是内容哈希文件、可公开缓存,因此用 * 是安全的。CDN 可以为所有访问者复用同一个缓存响应。

方案 B:限定为你的站点域名

Access-Control-Allow-Origin: https://yourdomain.com
Vary: Origin

适合同一个 CDN 给多个站点服务、希望按站点隔离的场景。Vary: Origin 必须加上,否则 CDN 可能把上一次的 Allow-Origin 头返回给另一个来源的请求。如果你的 CDN 不支持按 Origin 分缓存键,请使用方案 A。

如果是同源部署(未设置 ASSET_BASE_URL),则不涉及任何 CORS 配置。

Cloudflare R2 / S3(JSON 格式的 CORS 规则)

如果 CDN 是直接对外暴露的存储桶(R2 公开桶,或 S3 + CloudFront),把桶的 CORS 规则设置为:

[
  {
    "AllowedOrigins": ["*"],
    "AllowedMethods": ["GET", "HEAD"],
    "AllowedHeaders": ["*"],
    "MaxAgeSeconds": 86400
  }
]

或限定到你的站点域名:

[
  {
    "AllowedOrigins": ["https://yourdomain.com"],
    "AllowedMethods": ["GET", "HEAD"],
    "AllowedHeaders": ["*"],
    "MaxAgeSeconds": 86400
  }
]
  • R2:控制台 → 对应桶 → Settings → CORS policy → 粘贴 JSON
  • S3:AWS 控制台 → 桶 → Permissions → Cross-origin resource sharing (CORS),或用 aws s3api put-bucket-cors

Caddy / nginx(反向代理的 CDN)

# Caddy
header /_assets/* Access-Control-Allow-Origin "*"
# nginx
location /_assets/ {
    add_header Access-Control-Allow-Origin "*" always;
}

Slug(可选)

变量 默认值 说明
SLUG_ID_LENGTH 5 对无标题帖子自动生成随机 slug 时使用的长度

上传大小限制(可选)

变量 默认值 说明
UPLOAD_MAX_FILE_SIZE_MB 500 非图片上传的最大大小(MB)

图片本身还有更严格的专用限制。这个设置主要影响视频、音频和 PDF 上传。

内容摘要和 RSS 限制(可选)

变量 默认值 说明
SUMMARY_MAX_PARAGRAPHS 5 自动生成摘要时的最大段落数
SUMMARY_MAX_CHARS 500 自动生成摘要时的最大字符数
RSS_FEED_LIMIT 50 RSS feeds 中包含的最大帖子数

Settings 页面设置

这些设置可以在初始化完成后,通过 Jant 的 Settings 页面修改。所有设置都可以通过同名环境变量预置初始值——Settings 里改过的值优先级高于环境变量。

设置 用途
SITE_NAME 站点显示名称
SITE_DESCRIPTION Meta description 和 feed description
SITE_LANGUAGE 主要语言代码
TIME_ZONE 显示时区,例如 UTCAsia/Shanghai
HOME_DEFAULT_VIEW 决定首页默认从 Latest 还是 Featured 开始
MAIN_RSS_FEED 决定 /feed 返回什么
SITE_FOOTER 自定义页脚文本
SHOW_JANT_BRANDING_ON_HOME 是否在首页显示 Jant 品牌标识
NOINDEX 请求搜索引擎不要收录这个站点

颜色主题、字型主题、自定义 CSS、头像以及其他外观细节,也都在 Settings 里管理。

保留路径

这些顶层路径是保留的,不能作为 post 或自定义页面的 slug:

featured, latest, collections, signin, signout, setup, settings, dash,
api, feed, search, archive, media, pages, reset, compose, new, static, assets,
_assets, healthz, readyz

配置文件

wrangler.toml

把 Cloudflare 的非敏感配置写进 wrangler.toml

name = "my-jant-site"
main = "index.js"

[vars]
SITE_ORIGIN = "https://myblog.com"
# SITE_PATH_PREFIX = "/blog"
# R2_PUBLIC_URL = "https://media.myblog.com"
# IMAGE_TRANSFORM_URL = "https://media.myblog.com/cdn-cgi/image"

[[d1_databases]]
binding = "DB"
database_name = "my-jant-site-db"
database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

[[r2_buckets]]
binding = "R2"
bucket_name = "my-jant-site-media"

.env(Node 和 Docker)

Node 和 Docker 下,把这些值放进 .env,或者交给你的进程管理器注入:

AUTH_SECRET=your-32-plus-character-secret
SITE_ORIGIN=https://your-jant.example
DATABASE_URL=file:./data/jant.sqlite
# SITE_PATH_PREFIX=/blog
# TRUST_PROXY=true

有用的模板:

.dev.vars(本地开发)

本地 Cloudflare secrets 放进 .dev.vars

AUTH_SECRET=your-32-plus-character-secret
DEV_API_TOKEN=local-debug-token
[email protected]
DEMO_PASSWORD=jant-dev-debug-login
DEMO_MODE=false

DEV_API_TOKENDEMO_EMAILDEMO_PASSWORD 都是本地调试辅助项,不属于正常生产环境配置。

Demo Mode

只有在公开共享的 demo 环境里,才把 DEMO_MODE=true 打开。

效果:

  • 强制开启 noindex
  • 禁用删除账号、修改密码以及一些账号管理操作
  • 仅仅设置 DEMO_EMAILDEMO_PASSWORD 并不会自动开启 demo mode

生产环境 Secrets

Cloudflare 生产环境可以通过 Wrangler 或 Dashboard 设置 secrets:

openssl rand -base64 32
npx wrangler secret put AUTH_SECRET

接下来