solidtime v0.21.0 配置参数详解

solidtime v0.21.0 全量配置参数逐项实测详解:双环境文件体系、General/认证/日志/数据库/邮件/队列/存储/限流/容器模式,含 TRUSTED_HOSTS 双向闭环与限流 60 精准触发验证。

solidtime时间追踪自托管项目管理2026/10/24

solidtime v0.21.0 配置参数详解

目标:逐一讲清 solidtime v0.21.0 自托管部署涉及的配置项——来源、取值、生效行为与实测验证。本文所有行为验证均在 2026-10-24 于真实服务器部署的 solidtime v0.21.0 实例上实测完成(部署过程见《solidtime v0.21.0 Docker Compose 部署指南》),官方参数定义以 docs.solidtime.io/self-hosting/configuration 为底本逐项核对;未做运行时验证的项均如实标注「官方定义,未实测」。

一、配置体系总览

solidtime 基于 Laravel 框架,配置完全由环境变量驱动,官方采用双环境文件形态:

文件作用域说明
docker-compose.ymlDocker Compose 编排服务拓扑、端口、CONTAINER_MODE 等编排级变量
laravel.envsolidtime 应用进程由 compose env_file: 注入,全部为应用运行时配置

实测要点:容器内 printenv 可见 laravel.env 全部变量(实测 DB_HOST=database、DB_PORT=5432、QUEUE_CONNECTION=database、MAIL_MAILER=log 均正确注入),compose 文件中 environment: 段的编排级变量(如 CONTAINER_MODE)同样可见。

配置变更生效方式(实测验证):修改 laravel.env 后执行 docker compose up -d,compose 检测到环境变量变化自动重建相关容器,新值即刻生效(本篇 TRUSTED_HOSTS 实测即通过此流程完成两轮改值验证,见 2.4 节)。应用每次启动还会自动执行 storage:link 与配置缓存重建(入口日志实测:The [public/storage] link has been connected to [storage/app/public])。

二、General(基础与访问控制)

APP_URL

  • 类型:URL 字符串,必改项
  • 官方定义:实例基础 URL,所有生成的绝对链接(邮件、OAuth 回调、分享报表)都基于它
  • 实测:APP_URL=http://localhost:8137(HTTP 直连验证环境);生产 HTTPS 环境应写 https://your-domain.com
  • 行为:与实际访问协议/主机名不一致时,生成的链接(如密码重置、邀请接受)会指向错误地址

APP_FORCE_HTTPS

  • 类型:true/false,默认 false
  • 官方定义:反代终结 TLS、反代到应用为 HTTP 时置 true,应用将所有请求视为 HTTPS
  • 实测:本篇 HTTP 直连环境保持 false(置 true 会引发 HTTP 访问异常,属预期,未做破坏性实测)

APP_ENABLE_REGISTRATION

  • 类型:on / invite-only / off(旧值 true/false 兼容映射为 on/off)
  • 官方定义:
    • on:任何人可注册
    • invite-only:仅持有组织邀请的邮箱可注册(有 pending 邀请的邮箱先接受邀请再注册)
    • off:关闭自助注册,仅登录,用户经超管面板或 CLI 创建
  • 实测:off 下登录页 HTML 中无任何注册入口(grep Register 为空);CLI admin:user:create 与超管面板建号不受影响;API 邀请流程正常发信(见 7.1)

TRUSTED_PROXIES

  • 类型:CIDR 列表,逗号分隔
  • 官方定义:信任的代理 IP 段,应用仅从这些来源 IP 的请求中读取 X-Forwarded-For 等头
  • 实测:本篇应用与反代同网桥(无反代直连形态),置 *(全信任)——仅限可信内网,生产建议收敛为反代容器网段

TRUSTED_HOSTS

  • 类型:主机名列表,逗号分隔,支持 *.example.com 通配(不含裸域本身)
  • 官方定义:额外的合法 Host 名。默认仅接受 APP_URL 主机名(及其子域),其余 Host 头的请求被拒——防 Host 头投毒(v0.19.0 引入的安全机制)
  • 实测(双向闭环):
    • TRUSTED_HOSTS="localhost,127.0.0.1" 下以服务器 IP 访问 http://192.168.146.128:8137/login → 400 拒绝;
    • 改为 "localhost,127.0.0.1,192.168.146.128" 并 docker compose up -d 重建 → 同一 URL → 200 放行;
    • 还原配置重建 → IP 访问恢复 400,localhost 始终 200。

三、Authentication(认证与密钥)

APP_KEY / PASSPORT_PRIVATE_KEY / PASSPORT_PUBLIC_KEY

  • 类型:APP_KEY 为 base64: 前缀随机串;PASSPORT 两个为 PEM 格式密钥
  • 官方定义:APP_KEY 用于会话加密;PASSPORT 密钥对是 OAuth 服务器签名密钥(个人 API Token 认证依赖)
  • 生成命令(官方):
docker compose run --rm scheduler php artisan self-host:generate-keys

实测输出三行即贴即用(值已脱敏):APP_KEY 为 base64: 单行;PASSPORT 私钥/公钥以 \n 转义的单行 PEM 形态输出,可直接填入 env 文件,无需手工折叠多行:

APP_KEY="base64:/<(44 位随机字符)>"
PASSPORT_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nMIIJQgIBADANBgkqhkiG9w0BAQEF...\n-----END PRIVATE KEY-----"
PASSPORT_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQED...\n-----END PUBLIC KEY-----"
  • 行为实测:密钥就位后创建个人 API Token 成功(实测过程见《solidtime v0.21.0 API 使用详解》);另实测全新实例建 Token 前还需一次性创建 Passport 个人访问客户端(php artisan passport:client --personal --name="solidtime-personal" --provider=users --no-interaction),否则报 Personal access client not found——官方文档未提,属踩坑结论。

SUPER_ADMINS

  • 类型:邮箱列表,逗号分隔
  • 官方定义:名单内邮箱的登录用户可访问 /admin 超级管理员面板
  • 实测:SUPER_ADMINS="admin@solidtime.local",admin 登录后 GET /admin 返回 200

四、Logging(日志)

LOG_CHANNEL / LOG_LEVEL

  • 类型:Laravel 日志通道名 / 级别
  • 官方取值:stderr(容器友好,直接进 docker logs)、daily(storage/logs 按天分文件)、stderr_daily(两者兼顾)
  • 实测:LOG_CHANNEL=stderr 下,docker logs 直接可见应用日志(如迁移期间 [2026-10-24 12:29:36] production.INFO: ... Finished dropping index),与官方描述一致;容器场景推荐 stderr 系

五、Database(数据库)

官方明确:solidtime 仅支持 PostgreSQL,不支持 MySQL/MariaDB。选型时注意别被「Laravel 默认支持多数据库」误导。

DB_HOST / DB_PORT / DB_DATABASE / DB_USERNAME / DB_PASSWORD

  • 类型:连接五要素;容器部署时 DB_HOST 为 compose 服务名(本篇 database),端口 5432
  • 实测:五要素正确配置下迁移与运行时连接全程无错;数据库未就绪时应用启动即失败并被 restart: unless-stopped 拉起(部署篇坑 5)

DB_SSL_MODE

  • 类型:PostgreSQL SSL 模式,默认 prefer
  • 官方定义:外部支持 SSL 的数据库可设 require 强制加密;官方示例的数据库容器不支持 SSL,不可设 require
  • 实测:与 postgres:16-alpine 配合保持 prefer,连接正常

DB_URL(DATABASE_URL 备选)

  • 类型:连接串 URL
  • 官方定义:可用单一 URL 替代五要素,postgresql://user:pass@host:5432/db?sslmode=prefer
  • 实测:官方定义,未实测(与五要素二选一即可)

六、PDF rendering(PDF 渲染)

GOTENBERG_URL

  • 类型:URL,指向 Gotenberg 服务
  • 官方定义:报表 PDF 导出依赖 Gotenberg;应用需能访问该地址
  • 实测:GOTENBERG_URL=http://gotenberg:3000;从应用容器内访问 http://gotenberg:3000/health 实测返回正常(Gotenberg 健康端点可达),服务链路打通

七、Email(邮件)

MAIL_MAILER

  • 类型:Laravel 邮件驱动
  • 官方定义:任意支持 SMTP 的事务性邮件服务;验证阶段可用 log——出站邮件写入日志
  • 实测(全链路):MAIL_MAILER=log 下通过 API 发起组织邀请,队列 worker 消费后日志出现完整邮件(Subject: Organization Invitation、正文 You have been invited to join the demo organization!);验证类邮件的确认链接可从日志纯文本版本复制

MAIL_HOST / MAIL_PORT / MAIL_ENCRYPTION / MAIL_FROM_ADDRESS / MAIL_FROM_NAME / MAIL_USERNAME / MAIL_PASSWORD

  • 类型:SMTP 七件套
  • 官方示例:Scaleway TEM(smtp.tem.scw.cloud:465, tls)
  • 实测:验证环境用 log 驱动,SMTP 七件套按官方示例格式备好即可(不实测外发,避免依赖第三方服务)

八、Queue(队列)

QUEUE_CONNECTION

  • 类型:sync / database
  • 官方定义:sync 同步执行(不推荐生产);database 需要独立 worker 角色(CONTAINER_MODE=worker 容器)消费队列
  • 实测:database 下邀请邮件入队 → worker 消费 → 邮件落日志,全链路秒级完成;消费后数据队列表计数归零,确认无积压

九、File Storage(文件存储)

FILESYSTEM_DISK / PUBLIC_FILESYSTEM_DISK

  • 类型:磁盘名。私有文件盘与公开文件盘(如头像)分别配置
  • 官方取值:local+public(本地盘);s3 走 S3 兼容对象存储
  • 实测:本地盘下应用启动自动建立 public/storage → storage/app/public 软链(入口日志可见),导入/导出文件落在数据卷内

S3_REGION / S3_BUCKET / S3_ENDPOINT / S3_ACCESS_KEY_ID / S3_SECRET_ACCESS_KEY

  • 类型:S3 五件套,官方示例 Scaleway(fr-par/nl-ams/pl-waw)
  • 实测:无对外 S3 服务,按官方示例格式说明,不做真实上传验证

十、API Rate Limiting(API 限流)

API_RATE_LIMIT_AUTH_PER_MINUTE / API_RATE_LIMIT_GUEST_PER_MINUTE

  • 类型:整数,默认 200 / 60
  • 官方定义:认证用户按用户计数、访客按 IP 计数;仅 APP_ENV=production 时强制;Web 界面走同一 API,同样计数
  • 实测(精准触发):以无 token 访客身份对 /api/v1/currencies 连续请求 75 次,实测恰好前 60 次 200、第 61 次起全部 429,与默认值 60 严格一致——限流按 IP 计数且边界精准

十一、Container Mode(容器模式)

CONTAINER_MODE

  • 类型:http(默认)/ scheduler / worker / horizon / reverb / ssr
  • 官方定义(文档列出前三种):同一镜像按模式启动不同进程——HTTP 服务 / 调度器 / 队列 worker
  • 实测(读镜像入口脚本核实):v0.21.0 镜像实际支持六种模式,比官方文档多 horizon(队列监控面板)、reverb(WebSocket 推送)、ssr(Inertia 服务端渲染)三种
  • 实测:三个容器分别以 http / scheduler / worker 模式运行正常;worker 模式必须显式传 WORKER_COMMAND(如 php artisan queue:work),缺失即启动失败循环重启(日志刷 WORKER_COMMAND is undefined.),官方文档未提

OCTANE_SERVER

  • 类型:frankenphp(镜像默认)/ swoole / roadrunner
  • 官方定义:仅 http 模式生效,选择 Octane HTTP 引擎
  • 实测:镜像默认 frankenphp,未设置任何变量时 app 即以 FrankenPHP 运行(supervisord 拉起 octane 进程 + Caddy 管理端口 2019 可见);官方文档行文仍以 Swoole 举例,以镜像默认值为准

AUTO_DB_MIGRATE

  • 类型:true/false,默认 false
  • 官方定义:应用启动时自动执行数据库迁移
  • 实测(源码核实):入口脚本确认开启后执行 php artisan migrate --isolated --force;多角色部署仍推荐手动迁移,避免多容器并发迁移竞态

十二、参数速查表

变量必改默认/推荐一句话说明
APP_URL✅https://your-domain.com实例基础 URL
APP_ENV建议productionproduction 下限流等生效
APP_DEBUG建议false生产禁用
APP_FORCE_HTTPS视场景falseHTTPS 反代后置 true
APP_ENABLE_REGISTRATION✅off注册控制 on/invite-only/off
TRUSTED_PROXIES视场景*(内网)信任代理段
TRUSTED_HOSTS视场景—额外合法 Host,IP 直访必加
APP_KEY✅generate-keys 生成会话加密
PASSPORT_PRIVATE_KEY/PUBLIC_KEY✅generate-keys 生成OAuth 签名密钥对
SUPER_ADMINS建议—超管邮箱名单
LOG_CHANNEL建议stderr容器场景 stderr 系
DB_HOST/PORT/DATABASE/USERNAME/PASSWORD✅—PG 连接五要素(仅支持 PostgreSQL)
DB_SSL_MODE视场景prefer外部 SSL 库可 require
DB_URL可选—连接串替代五要素
GOTENBERG_URL建议http://gotenberg:3000PDF 渲染服务
MAIL_MAILER✅log(验证)/smtp邮件驱动
QUEUE_CONNECTION建议databasedatabase 需 worker 角色
FILESYSTEM_DISK/PUBLIC_FILESYSTEM_DISK可选local/public本地盘
S3_*可选—S3 对象存储
API_RATE_LIMIT_AUTH/GUEST_PER_MINUTE可选200/60仅 production 强制,实测 60 精准触发
CONTAINER_MODE✅http实测六模式:http/scheduler/worker/horizon/reverb/ssr
OCTANE_SERVER可选frankenphphttp 模式引擎
WORKER_COMMANDworker 必填php artisan queue:workworker 模式缺失即循环重启
AUTO_DB_MIGRATE可选false启动自动迁移

十三、参考链接