Loomio 3.14.0 配置参数详解
Loomio 3.14.0 配置体系详解:.env 全量参数分类(注释整行才算禁用)、URL/SSL/SMTP/Puma/Rack::Attack/存储/特性开关/SSO/主题/可观测逐段语义与 boot/site、rails about、puma.rb 实测生效验证,16GB 生产模板与 5 条配置排障实录。
Loomio 3.14.0 配置参数详解
目标:把 Loomio 3.14.0 的全部配置面(官方
env_template约 130 行、60+ 变量)按类别拆解语义,并逐段给出"改了怎么确认生效"的实测手段;结论均来自 2026-11-02 主机实测实例(192.168.1.172:8144)。实例由 《Loomio 3.14.0 Docker Compose 部署指南》 部署,CLI 验证工具见 《Loomio 3.14.0 常用 CLI 命令与工具详解》。
一、环境信息
- Loomio 3.14.0(release 1793498930),Rails 8.1.3.1 / Ruby 4.0.9 / Puma 8.0.2
- 配置载体:
deploy/.env(composeenv_file注入 app/worker/db/hocuspocus 四服务),无独立应用配置文件 - 参数权威来源:发行包
deploy/env_template(2026-11-02 实查全文)、应用源码config/application.rb、config/puma.rb、app/extras/app_config.rb - 运行时核对通道:
GET /api/v1/boot/site(免登录)、GET /api/v1/boot/version、bin/rails about、psql、redis-cli
二、前置条件
- 已按 《Loomio 3.14.0 Docker Compose 部署指南》 起栈且 6 服务健康(
docker compose ps全 Up,app(healthy)) - 主机侧可执行
docker compose exec(本文所有验证命令均在 compose 文件所在目录运行) - 修改参数前备份
.env:cp .env .env.bak.$(date +%F)
三、参数查看与修改方式
3.1 唯一入口:.env 文件与"注释即禁用"规则
Loomio 全部配置经环境变量注入。env_template 首行警告原文(实测照抄):
# PLEASE NOTE: To disable a setting you MUST comment out (or delete) the line.
# If you set change SOME_FEATURE=1 to SOME_FEATURE=0, that feature is still enabled!
生效机制在源码:应用按 ENV['KEY'].present? 判断开关——任何非空值(包括 0、false)都算启用,禁用必须注释或删除整行。实测反例见"常见问题"6.1。
3.2 修改与生效路径
.env 属容器启动时注入,改完必须重启相关服务:
docker compose up -d --force-recreate app worker hocuspocus
验证生效(本文各节均给出对应手段):站点级参数看 boot/site JSON;进程级参数看 rails about / docker compose exec app env;数据库参数看 psql。
3.3 运行时全量核对:boot/site
免登录接口返回前端实际拿到的配置合并结果,是核对参数是否生效的第一手段(实测节选):
curl -s http://192.168.1.172:8144/api/v1/boot/site | python3 -c \
"import json,sys;d=json.load(sys.stdin);print(json.dumps({'version':d['version'],'baseUrl':d['baseUrl'],'theme':{k:v for k,v in d['theme'].items() if k in ('site_name','canonical_host','hocuspocus_url')},'demos':d['features']['app']['demos'],'local_login':d['features']['app']['local_login'],'sentry_sample_rate':d['features']['app']['sentry_sample_rate'],'max_message_length':d['features']['app']['max_message_length']},ensure_ascii=False))"
{"version": "3.14.0", "baseUrl": "http://192.168.1.172:8144/", "theme": {"site_name": "Loomio", "hocuspocus_url": "ws://192.168.1.172:8145", "canonical_host": "192.168.1.172"}, "demos": false, "local_login": true, "sentry_sample_rate": 0.05, "max_message_length": 100000}
四、参数总览
按类别汇总(默认值列取自 env_template 注释与实测;完整模板见 B2 篇 4.2):
| 类别 | 变量 | 默认值/示例 |
|---|---|---|
| 版本钉 | LOOMIO_CONTAINER_IMAGE/TAG、POSTGRES_CONTAINER_TAG、HARAKA_CONTAINER_TAG、NGINX_PROXY_CONTAINER_TAG、ACME_COMPANION_CONTAINER_TAG | loomio/loomio / 3.5(滞后,需钉 3.14.0) / 17 / stable / 1.11-alpine / 2.8 |
| 主机与 URL | SITE_NAME、CANONICAL_HOST、CANONICAL_PORT、PUBLIC_APP_URL、PRIVATE_APP_URL、HOCUSPOCUS_URL、SUPPORT_EMAIL | — / 必填 / 8144 实测 / http://… / http://app:3000 / ws://… / — |
| SSL | FORCE_SSL、ASSUME_SSL | 启用态(无 TLS 必须注释)/ 注释 |
| SMTP | SMTP_DOMAIN/SERVER/PORT/USERNAME/PASSWORD、SMTP_AUTH、SMTP_USE_SSL | — / plain / 465 示例 / 注释=不启用 |
| 收信 | REPLY_HOSTNAME、RAILS_INBOUND_EMAIL_URL、RAILS_INBOUND_EMAIL_PASSWORD、BOUNCE_ADDRESS、COMPLAINTS_ADDRESS、SES_SUPPRESSION_REGION | haraka 形态必填 |
| 并发 | WEB_CONCURRENCY、MIN_THREADS、MAX_THREADS、PUMA_WORKERS、RAILS_MAX_THREADS | auto / 3 / 3 / —(PUMA_WORKERS 优先) |
| 限速 | USE_RACK_ATTACK、RACK_ATTACK_RATE_MULTPLIER、RACK_ATTACK_TIME_MULTPLIER、THROTTLE_MAX_LINK_PREVIEWS_GLOBAL | 1 / 1 / 1 / 100 |
| 数据库 | POSTGRES_PASSWORD、POSTGRES_DB、DATABASE_URL | — / loomio_production / postgresql://…@db/… |
| 缓存 | REDIS_CACHE_URL、REDIS_MAXMEMORY | redis://redis:6379/0 / 256mb |
| 附件 | ACTIVE_STORAGE_SERVICE、FILE_UPLOAD_MAX_MB、AWS_/DO_/STORAGE_*(s3_compatible) | local / 1024 |
| 特性开关 | FEATURES_DISABLE_CREATE_USER/CREATE_GROUP/HELP_LINK/LOCAL_LOGIN/EMAIL_LOGIN、FEATURES_REVEAL_EMAIL_ACCOUNT_STATUS、FEATURES_DEFAULT_PATH、LOOMIO_RESTRICT_EXPLORE_TO_SIGNED_IN_USERS、ALLOW_ROBOTS | 全部注释(默认启用创建) |
| 演示/数据保留 | LOOMIO_DISABLE_DEMO_GROUPS、FEATURES_DEMO_GROUPS_SIZE、GROUP_DELETION_DELAY_DAYS、DEFAULT_ONBOARDING_GROUP_ID、LOOMIO_ENFORCE_TERMS_FOR_EXISTING_USERS | 注释=启用演示 / 3 / 90 / — |
| 密钥 | SERVER_API_KEY(≥17 字符)、SECRET_COOKIE_TOKEN、RAILS_INBOUND_EMAIL_PASSWORD、VAPID_PUBLIC_KEY/PRIVATE_KEY/SUBJECT、PUSH_RELAY_URL | create_env.sh 自动生成 |
| SSO | SAML_APP_KEY、SAML_IDP_METADATA_URL/METADATA、SAML_ISSUER、SAML_LOGIN_PROVIDER_NAME、SAML_ALLOW_IDP_INITIATED、OAUTH_AUTH_URL/TOKEN_URL/PROFILE_URL/SCOPE/APP_KEY/APP_SECRET/ATTR_/LOGIN_PROVIDER_NAME、LOOMIO_SSO_UPDATE_USER_PROFILE_ON_LOGIN、LOOMIO_DISABLE_EDIT_USER_PROFILE、LOOMIO_SSO_FORCE_USER_ATTRS、FACEBOOK_/GOOGLE_* | 全部注释 |
| 主题 | THEME_ICON_SRC、THEME_APP_LOGO_SRC、THEME_EMAIL_HEADER/FOOTER_LOGO_SRC、THEME_ACCENT_COLOR、THEME_DEFAULT_DARK/LIGHT_THEME、THEME_LIGHT_/DARK_/LIGHTBLUE_/DARKBLUE_(配色组) | light/dark 四套内置主题 |
| 可观测 | SENTRY_PUBLIC_DSN、SENTRY_SAMPLE_RATE、SENTRY_PROFILES_SAMPLE_RATE、SENTRY_ENABLE_LOGS、PLAUSIBLE_SRC/SITE、TURNSTILE_SITE_KEY/SECRET_KEY | 0.05 / 1.0 / 注释 |
| 其他 | TRANSLATE_CREDENTIALS、OPENAI_API_KEY、LOOMIO_HELP_TITLE/SUBTITLE/URL、LOOMIO_SYSTEM_RELOAD、RAILS_ENV | — / 1 |
五、核心参数分类详解
5.1 主机与 URL:CANONICAL_HOST / CANONICAL_PORT / PUBLIC_APP_URL / PRIVATE_APP_URL / HOCUSPOCUS_URL
config/application.rb 用 CANONICAL_HOST+CANONICAL_PORT 拼出 Rails 侧协议与主机(protocol 由 FORCE_SSL 决定);PUBLIC_APP_URL 是浏览器侧基址(邮件链接、boot/site baseUrl),PRIVATE_APP_URL 供 Node 侧(hocuspocus)回调 Rails 内部地址。实测生效值即 3.3 节 boot/site 的 baseUrl=http://192.168.1.172:8144/ 与 theme.canonical_host=192.168.1.172。
HOCUSPOCUS_URL 必须是浏览器可达的 ws/wss 地址(实测 ws://192.168.1.172:8145,boot/site 回显同值);官方形态用 wss://hocuspocus.<域名> 走独立子域。
⚠️ 注意:
create_env.sh拒绝非 FQDN 主机名(源码!hostname.include?(".")即 abort),IP 部署必须手写.env(见 B2 篇 3.3)。
5.2 SSL:FORCE_SSL / ASSUME_SSL
FORCE_SSL:application.rb实测源码config.force_ssl = ENV['FORCE_SSL'].present?——置0仍强制 HTTPS;无 TLS 场景整行注释(本文实测形态),否则浏览器被 307 弹到 https 打不开。ASSUME_SSL:前置代理已终结 TLS、转发给 Loomio 的是 http 时启用,防止应用再回 301。
验证:curl -s -o /dev/null -w '%{http_code} %{redirect_url}\n' http://192.168.1.172:8144/ 实测 302 http://192.168.1.172:8144/dashboard(无 https 跳转即正确)。
5.3 SMTP 与邮件
出站:SMTP_SERVER/PORT/DOMAIN/USERNAME/PASSWORD,认证方式 SMTP_AUTH=plain;SMTP_USE_SSL 同样"注释才禁用"(源码 ENV['SMTP_USE_SSL'].present?)。实测内网形态指向 mailpit(mailpit:1025,无认证无 TLS),捕获 API {"total":0,"unread":0,"count":0,"messages_count":0,"messages_unread":0,"start":0,"tags":[],"messages":[]} 在线。入站:haraka 形态需 REPLY_HOSTNAME(MX 主机名)+ RAILS_INBOUND_EMAIL_PASSWORD;退信/投诉回流用 BOUNCE_ADDRESS/COMPLAINTS_ADDRESS。
5.4 Puma 并发:WEB_CONCURRENCY / MAX_THREADS / PUMA_WORKERS / RAILS_MAX_THREADS
config/puma.rb 实测源码(发行包原文):
worker_value = ENV['PUMA_WORKERS'] || ENV['WEB_CONCURRENCY'] || 0
workers worker_value.to_s.downcase == "auto" ? :auto : Integer(worker_value)
threads_count = Integer(ENV['RAILS_MAX_THREADS'] || ENV['MAX_THREADS'] || 3)
threads threads_count, threads_count
port ENV.fetch("PORT", 3000)
优先级链:PUMA_WORKERS > WEB_CONCURRENCY;RAILS_MAX_THREADS > MAX_THREADS > 3。auto 取 CPU 核数——官方默认 WEB_CONCURRENCY=auto,6 核即 6 worker 进程,内存吃紧;本文实测降为 WEB_CONCURRENCY=2,app 稳态 480 MiB。验证:docker compose logs app | head 实测回显:
[22] Puma starting in cluster mode...
[22] * Puma version: 8.0.2 ("Into the Arena")
[22] * Listening on http://0.0.0.0:3000
5.5 限速与防护:USE_RACK_ATTACK / RACK_ATTACK_* / TURNSTILE_*
USE_RACK_ATTACK=1 挂载 Rack::Attack 对建组、注册等 POST 限速;两个 MULTPLIER(模板原文拼写如此)分别放大速率与时间窗。实测生效证据——bin/rails about 的 Middleware 行含两次 Rack::Attack(输出节选,实测首尾):
Middleware Rack::Sendfile, ..., Rack::TempfileReaper, Rack::Deflater, Rack::Attack, HttpAcceptLanguage::Middleware, Rack::Attack
THROTTLE_MAX_LINK_PREVIEWS_GLOBAL 覆盖链接预览每小时限额(默认 100)。注册/登录防刷可选 Cloudflare Turnstile 双键。
5.6 数据库与缓存:DATABASE_URL / REDIS_CACHE_URL / REDIS_MAXMEMORY
DATABASE_URL=postgresql://postgres:q1w2e3r4@db/loomio_production(口令即 POSTGRES_PASSWORD 实值)同时被 app/worker/db 服务读取(db 服务靠 POSTGRES_PASSWORD/POSTGRES_DB 初始化)。Redis 定位"仅缓存与 Action Cable",compose 实测启动参数 --save "" --appendonly no --maxmemory 256mb --maxmemory-policy allkeys-lru。
💡 技术拓展:Redis 内存淘汰策略不止 allkeys-lru——
策略 行为 适用 noeviction 满了直接报错不删 数据不可丢的场景 allkeys-lru 全体 key 按最近最少使用淘汰 纯缓存(Loomio 选用) allkeys-lfu 按访问频率淘汰 热点集中的缓存 allkeys-random 随机淘汰 访问均匀 volatile-* 只淘汰带 TTL 的 key 混合存储 Loomio 把 Redis 当纯缓存且关闭持久化,
allkeys-lru丢了可重建,是官方 compose 实测默认。
验证:docker compose exec redis redis-cli config get maxmemory-policy → allkeys-lru;redis-cli ping 实测 PONG。
5.7 附件与存储:ACTIVE_STORAGE_SERVICE / FILE_UPLOAD_MAX_MB / 云存储组
local 落盘 ./storage(compose bind mount);可选 amazon/digitalocean/s3_compatible 三套云后端,对应 AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY/AWS_BUCKET/AWS_REGION、DO_ENDPOINT/DO_ACCESS_KEY_ID/DO_SECRET_ACCESS_KEY/DO_BUCKET、STORAGE_ENDPOINT/STORAGE_ACCESS_KEY_ID/STORAGE_SECRET_ACCESS_KEY/STORAGE_REGION/STORAGE_BUCKET_NAME/STORAGE_FORCE_PATH_STYLE。FILE_UPLOAD_MAX_MB 默认 1024;官方形态还需同步调 nginx client_max_body_size(compose configs: nginx-custom)。验证:上传附件后 ls ./storage 出现对象即 local 生效。
5.8 特性开关与演示群组
FEATURES_DISABLE_CREATE_USER=1:禁自助注册(只能邀请);FEATURES_DISABLE_CREATE_GROUP:禁用户建组;FEATURES_DISABLE_LOCAL_LOGIN=1:关闭密码/邮箱码/passkey 本地账号(SSO-only 站点);FEATURES_REVEAL_EMAIL_ACCOUNT_STATUS=1:反查邮箱是否注册(便利但引入账号枚举风险,默认关)。- 实测生效证据:
boot/site的features.app回显create_user:true / create_group:true / local_login:true;demos:false(因设了LOOMIO_DISABLE_DEMO_GROUPS=1)。 - 演示群组判定在
app/extras/app_config.rb:203demo_groups_enabled?:只要CANONICAL_HOST有值即默认启用;FEATURES_DEMO_GROUPS_SIZE控制 Redis 预热组数(默认 3)。 GROUP_DELETION_DELAY_DAYS(默认 90):废弃群组保留期;DEFAULT_ONBOARDING_GROUP_ID:新用户自动入组;LOOMIO_ENFORCE_TERMS_FOR_EXISTING_USERS:老用户补签条款。
5.9 密钥与令牌
| 变量 | 约束与用途 |
|---|---|
| SERVER_API_KEY | ≥17 字符否则应用拒绝启动(env_template 原文);Server API Bearer 密钥,注释整行=关闭 Server API |
| SECRET_COOKIE_TOKEN | Cookie 签名密钥,轮换会使全部会话失效 |
| RAILS_INBOUND_EMAIL_PASSWORD | 收信 relay 口令 |
| VAPID_PUBLIC_KEY/PRIVATE_KEY/SUBJECT | 三者齐备即启用 Web Push(create_env.sh 自动生成) |
| PUSH_RELAY_URL | 移动端推送共享 relay(HTTPS 可达才配) |
生成方式实测:openssl rand -hex 32。
5.10 SSO:SAML 与 OAuth2/OIDC
SAML 组:SAML_APP_KEY=1 总开关 + SAML_IDP_METADATA_URL(优先)或 SAML_IDP_METADATA 直配 + SAML_ISSUER + SAML_LOGIN_PROVIDER_NAME(按钮文案)+ SAML_ALLOW_IDP_INITIATED(默认关,仅 IdP 不支持 SP-initiated 时开)。OAuth2/OIDC 组:OAUTH_AUTH_URL/TOKEN_URL/PROFILE_URL/SCOPE/APP_KEY/APP_SECRET + 字段映射 OAUTH_ATTR_UID/NAME/EMAIL/PICTURE(默认 sub/name/email/picture)+ OAUTH_LOGIN_PROVIDER_NAME。SSO 托管资料:LOOMIO_SSO_UPDATE_USER_PROFILE_ON_LOGIN=1(每次登录同步姓名/邮箱/头像)、LOOMIO_DISABLE_EDIT_USER_PROFILE=1(禁改 SSO 托管字段);LOOMIO_SSO_FORCE_USER_ATTRS 为二者合并的遗留开关,新配置建议用显式两项。另有 Facebook/Google 社交登录键。
5.11 主题与品牌
THEME_ICON_SRC/THEME_ICON_MASKABLE_192_SRC/THEME_ICON_MASKABLE_512_SRC/THEME_APP_LOGO_SRC/THEME_EMAIL_HEADER_LOGO_SRC/THEME_EMAIL_FOOTER_LOGO_SRC 指向 /files/ 前缀(即 compose 挂载的 ./files 目录;logo 优先 SVG,图标 192/512 且留 80% 安全区)。配色按 light/lightblue/dark/darkblue 四套主题分组(THEME_LIGHT_PRIMARY、THEME_DARK_BACKGROUND_GRADIENT 等),THEME_DEFAULT_LIGHT_THEME/THEME_DEFAULT_DARK_THEME 选默认;邮件品牌色 THEME_ACCENT_COLOR 等。实测 boot/site 的 theme.site_name=Loomio 即 SITE_NAME 生效值。帮助链接文案可整体替换(LOOMIO_HELP_TITLE/SUBTITLE/URL)。
5.12 可观测与升级重载
Sentry:SENTRY_PUBLIC_DSN 启用,采样 SENTRY_SAMPLE_RATE 默认 0.05(实测 boot/site 回显 sentry_sample_rate:0.05),SENTRY_PROFILES_SAMPLE_RATE 默认 1.0,日志上报 SENTRY_ENABLE_LOGS 默认关。Plausible:PLAUSIBLE_SRC+PLAUSIBLE_SITE。LOOMIO_SYSTEM_RELOAD=1 时 boot/version 带 reload:true,客户端升级后自动重载——实测回显:
curl -s http://192.168.1.172:8144/api/v1/boot/version
{"version":"3.14.0","release":"1793498930","reload":true,"notice":null}
六、生产配置模板
适用:16 GB 内存、NVMe SSD、50–200 人内网决策协作场景(域名 + TLS 官方形态,WEB_CONCURRENCY=auto 在 8 核约 8 worker,实测 6 核 2 worker 形态内存 1.1 GB,16 GB 主机余量充足):
LOOMIO_CONTAINER_IMAGE=loomio/loomio
LOOMIO_CONTAINER_TAG=3.14.0
SITE_NAME=MyDecisions
CANONICAL_HOST=loomio.example.com
PUBLIC_APP_URL=https://loomio.example.com
PRIVATE_APP_URL=http://app:3000
SUPPORT_EMAIL=admin@example.com
REPLY_HOSTNAME=loomio.example.com
HOCUSPOCUS_URL=wss://hocuspocus.loomio.example.com
SMTP_SERVER=smtp.example.com
SMTP_PORT=465
SMTP_USERNAME=loomio@example.com # 你的邮件服务提供的发信账号
SMTP_PASSWORD=ChangeMeSmtp123! # 对应发信口令(以邮件服务商下发为准)
SMTP_USE_SSL=1
WEB_CONCURRENCY=auto
MAX_THREADS=3
USE_RACK_ATTACK=1
POSTGRES_PASSWORD=<openssl rand -hex 32>
DATABASE_URL=postgresql://postgres:<同一口令>@db/loomio_production
ACTIVE_STORAGE_SERVICE=local
LOOMIO_DISABLE_DEMO_GROUPS=1
ALLOW_ROBOTS=1 # 公网站点若不想被索引,删除本行
SERVER_API_KEY=<openssl rand -hex 32>
SECRET_COOKIE_TOKEN=<openssl rand -hex 32>
RAILS_INBOUND_EMAIL_PASSWORD=<openssl rand -hex 32>
RAILS_ENV=production
与实测内网形态的差异:恢复 FORCE_SSL=1、haraka/nginx-proxy/acme 三服务与 25/80/443 端口、SMTP_USE_SSL=1、关闭演示群组(两形态都应设)。
七、常见问题
Q1:FORCE_SSL=0 后访问仍被 307 重定向到 https?
present? 判定下 0 也是启用。注释整行后 docker compose up -d --force-recreate app 生效(5.2)。
Q2:应用起不来,日志报 SERVER_API_KEY 相关错误?
该键不足 17 字符(或被设成短值)。用 openssl rand -hex 32 重生成;不需要 Server API 就注释整行(5.9)。
Q3:改了 .env 里 SITE_NAME,页面还是旧名?
.env 只在容器创建时注入,restart 不重读,必须 up -d --force-recreate app worker hocuspocus,再用 boot/site 的 theme.site_name 核对(3.3)。
Q4:新注册用户默认进了某个组 / 没进?
DEFAULT_ONBOARDING_GROUP_ID 未设则不进组;设成不存在的组 ID 静默无效。实测 boot/site 无该键回显,需以行为验证(注册后 memberships 数)。
Q5:create_env.sh 报 hostname must be a fully qualified domain name?
传入的是 IP 或无点主机名,脚本强制 FQDN;内网手写 .env(5.1)。
Q6:Redis 内存到 256mb 后缓存频繁被挤掉?
属预期(allkeys-lru)。Action Cable 连接抖动明显时上调 REDIS_MAXMEMORY 并 recreate redis 服务(5.6)。