Mastodon 4.7.3 配置参数详解

Mastodon 4.7.3 部署配置 .env.production 全参数详解:身份、数据库、Redis、密钥、SMTP、Elasticsearch、对象存储、进程资源、邮箱域校验、数据保留十组参数逐项说明,含 MAX_THREADS 修改-验证闭环与 EMAIL_DOMAIN_ALLOWLIST 正反对照实测。

MastodonMastodonFediverse2026/10/27

Mastodon 4.7.3 配置参数详解

目标:吃透 Mastodon v4.7.3 单实例部署的唯一配置入口 .env.production——全部参数分组逐项讲清作用、默认值、本实测取值与验证方法,并以「修改 → 生效 → 验证 → 回滚」的标准流程完整实测一组变更(MAX_THREADS 5→10→5)与邮箱域校验的正反对照。全部命令与回显在 Ubuntu 22.04 + Mastodon 4.7.3 实测环境采集,配置生效方式(重启/热载/需重建)逐一标注。部署过程本身见《Mastodon 4.7.3 Docker Compose 部署指南》(https://www.quzuo.net/document/rGlBZFpVtwc8),本文基于该实测实例展开。

一、环境信息

  • 操作系统:Ubuntu 22.04 LTS(x86_64),6 核 / 20GB 内存
  • Mastodon:v4.7.3(tootctl version 回显 4.7.3)
  • 数据库:PostgreSQL 14.24;缓存/队列:Redis 7.4.11;Elasticsearch:未启用
  • 实例域名:mastodon.local(/api/v1/instance 回显 uri=mastodon.local)
  • 配置文件:/opt/mastodon/.env.production(部署目录下唯一配置注入点)
  • 参考样本:官方 .env.production.sample(v4.7.3 tag 源码树携带)

二、配置文件位置与加载链

2.1 部署配置文件与加载链

Mastodon 的一切部署配置从环境变量读取,单机部署的载体就是一个文件:/opt/mastodon/.env.production。加载链为:

/opt/mastodon/.env.production
   └─ env_file 注入 → web(Puma)/ streaming(Node)/ sidekiq 三个服务进程
        └─ Rails 启动时读入 → config/initializers/*.rb 全局生效

注意三个进程共用同一份文件:改一处、三服务同步受影响;数据库与缓存服务不读它(db/redis 参数写在编排文件里,见部署篇 4.1)。

生效方式分级(本文逐项标注):

生效方式触发条件适用参数
需重建服务env_file 内容变化,docker compose up -d 检测到环境差异自动重建对应服务全部环境变量
需重启进程进程内热载的少数运行时项无(4.7.3 环境变量类均需重建)
立即生效写数据库的实例设置(管理界面 / tootctl settings)见 2.2

2.2 两层配置模型:环境变量与实例设置

Mastodon 的配置分两层,务必分清,否则改了不生效:

  • 环境变量层(.env.production):基础设施定位——密钥、数据库地址、SMTP、存储、进程资源。改后需 docker compose up -d 重建生效。
  • 实例设置层(数据库 settings 表):业务策略定位——注册开关、站点标题、简介、是否封禁某邮箱域等。由管理员界面或 tootctl settings 修改,立即生效、无需重启。

实测区分方法——实例设置层改注册开关并读回:

docker compose run --rm web bin/tootctl settings registrations open

实测回显:

OK
Opened registrations
docker compose run --rm web bin/rails runner "puts Setting.registrations_mode"

实测回显:

open

改回关闭(本实例恢复原状态):

docker compose run --rm web bin/tootctl settings registrations close

实测回显:

OK
Closed registrations
docker compose run --rm web bin/rails runner "puts Setting.registrations_mode"

实测回显:

none

2.3 当前生效值速查

验证「文件里写的」与「进程里生效的」一致,最直接的办法是列出服务进程环境:

docker compose exec web sh -c 'env | grep -E "^DB_|^REDIS_|^ES_ENABLED|^S3_ENABLED|^SMTP_SERVER"'

实测回显:

REDIS_PORT=6379
DB_PORT=5432
DB_NAME=mastodon
ES_ENABLED=false
S3_ENABLED=false
DB_PASS=
REDIS_HOST=redis
SMTP_SERVER=localhost
DB_HOST=db
DB_USER=postgres

与 .env.production 逐行对得上——配置注入链完整可信。

三、核心配置参数详解

3.1 LOCAL_DOMAIN(实例联邦身份)

LOCAL_DOMAIN=mastodon.local
  • 作用:实例的联邦身份域名,账号 @用户名@域名 的域名部分、帖子 URL 的主机名、联邦发现的锚点。
  • 生效方式:需重建服务。
  • ⚠️ 不可安全更改:官方源码注释原文「This identifies your server and cannot be changed safely later」——开放联邦后改域名意味着全部账号句柄与 URL 断裂。
  • 验证闭环(读实例元数据回显确认身份已生效):
curl -s -H 'Host: mastodon.local' -H 'X-Forwarded-Proto: https' http://127.0.0.1:8135/api/v1/instance | head -c 120

实测回显:

{"uri":"mastodon.local","title":"Mastodon","short_description":"","description":"","email":"","version":"4.7.3","urls":{"streaming_api":"wss://mastodon.local"}
  • 关联参数:WEB_DOMAIN(可选)——网页/API 域与联邦身份域分离时才设置,让用户访问 www.example.com 而联邦身份仍是 example.com;本实测未启用,单域部署无需理会。

3.2 数据库参数组(DB_HOST / DB_USER / DB_NAME / DB_PASS / DB_PORT)

DB_HOST=db
DB_USER=postgres
DB_NAME=mastodon
DB_PASS=
DB_PORT=5432
  • 作用:Mastodon 主存储的全部连接信息——账号、帖子、关系、设置等所有结构化数据。
  • 本实测取值说明:DB_HOST=db 是编排内服务名直连;DB_PASS 留空配套 db 服务的 POSTGRES_HOST_AUTH_METHOD=trust(仅内部网络可达,见部署篇第八章)。生产环境建议口令认证:db 服务设 POSTGRES_PASSWORD=xxx,此处 DB_PASS=xxx,两者必须一致。
  • 默认值参考:官方 sample 为 DB_HOST=/var/run/postgresql、DB_USER=mastodon、DB_NAME=mastodon_production(源码安装形态的 Unix socket 连接)——与部署形态强相关,照抄 sample 不如按形态填写。
  • 验证闭环(数据库就绪 + 应用层链路):
docker compose exec db pg_isready -U postgres

实测回显:

/var/run/postgresql:5432 - accepting connections
docker compose run --rm web bin/tootctl version

实测回显:

4.7.3

💡 说明:tootctl version 看似只打版本号,实际整条链路(Rails 启动 → DB 连接 → Redis 连接)都通了才会执行——数据库参数改错时它是最快的验错命令。

3.3 Redis 参数组(REDIS_HOST / REDIS_PORT)

REDIS_HOST=redis
REDIS_PORT=6379
  • 作用:Redis 承担三件事——Sidekiq 后台任务队列、Rails 缓存、实时推送的 pub/sub 通道。
  • 生效方式:需重建服务。
  • 验证闭环:
docker compose exec redis redis-cli ping

实测回显:

PONG
  • 生产加固(官方支持但本实测未启用,标注边界):REDIS_PASSWORD 可设口令;REDIS_NAMESPACE 可多实例共享一个 Redis。启用口令后三个应用服务自动带上认证,无需改其他参数。

3.4 密钥参数组(SECRET_KEY_BASE / OTP_SECRET / VAPID_* / ACTIVE_RECORD_ENCRYPTION_*)

四小项、三种生成命令,全部「一次生成、终身不改」:

变量生成命令作用更换后果
SECRET_KEY_BASEbin/rails secretRails 会话与摘要加密基钥全部已发会话失效,用户被登出
OTP_SECRETbin/rails secret(另跑一次)两步验证(OTP)数据加密已绑定的二步验证需重新配置
VAPID_PRIVATE_KEY / VAPID_PUBLIC_KEYbin/rails mastodon:webpush:generate_vapid_keyWeb Push 浏览器推送签名已订阅推送的浏览器全部失效
ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY / _KEY_DERIVATION_SALT / _PRIMARY_KEYbin/rails db:encryption:init数据库敏感字段加密(4.7.x 强制)已加密数据无法解密,等于数据损坏

生成命令实测回显(部署篇 4.2 全程实录):bin/rails secret 输出 128 位十六进制串、generate_vapid_key 一次输出成对键值行、db:encryption:init 输出三个 KEY=值 行——部署时直接抄入 .env.production 即可。

验证闭环(确认加密三件套已在位,重复运行生成命令会被拒绝):

docker compose run --rm web bin/rails db:encryption:init

实测回显:

Use IGNORE_ALREADY_SET_SECRETS=true to generate new secrets anyway

⚠️ 注意:这条回显正是「密钥已配置」的证明——4.7.3 检测到环境变量中已有加密密钥后拒绝生成新值,防止误操作破坏密文。多节点部署时三件套必须各节点一致,否则部分密文无法解密。

3.5 SMTP 参数组(SMTP_SERVER / SMTP_PORT / SMTP_LOGIN / SMTP_PASSWORD / SMTP_AUTH_METHOD / SMTP_OPENSSL_VERIFY_MODE / SMTP_ENABLE_STARTTLS_AUTO / SMTP_FROM_ADDRESS)

SMTP_SERVER=localhost
SMTP_PORT=25
SMTP_AUTH_METHOD=none
SMTP_OPENSSL_VERIFY_MODE=none
SMTP_ENABLE_STARTTLS_AUTO=false
SMTP_FROM_ADDRESS=Mastodon <notifications@mastodon.local>
  • 作用:注册确认信、找回密码、回复与提及通知等全部出站邮件的投递通道。
  • 参数口径:SMTP_LOGIN/SMTP_PASSWORD 配合 SMTP_AUTH_METHOD(none/plain/login/cram_md5)使用;SMTP_OPENSSL_VERIFY_MODE 取 none/peer/client_once/fail_if_no_peer_cert;SMTP_PORT=587 为外网服务商标准提交口(sample 默认),25 为内网直投。
  • 本实测场景:未接外部邮件服务的单机演示实例,localhost:25 无监听进程。
  • 验证闭环(真实触发一次投递,暴露当前 SMTP 配置的实际行为):
docker compose run --rm web bin/rails runner "begin; UserMailer.confirmation_instructions(User.find_by(email:'admin@mastodon.local'), 'testtoken', {}).deliver_now; rescue StandardError => e; puts \"#{e.class}: #{e.message}\"; end"

实测回显:

Errno::ECONNREFUSED: Connection refused - connect(2) for "localhost" port 25

解读:配置被正确读入并尝试连接 SMTP_SERVER:SMTP_PORT,连接被拒即该地址无投递服务——生产环境把六项换成真实服务商参数即可;纯内网测试实例可保持现状(管理员账号走 tootctl 创建并 --confirmed,不依赖邮件)。

3.6 Elasticsearch 参数组(ES_ENABLED / ES_HOST / ES_PORT / ES_USER / ES_PASS)

ES_ENABLED=false
  • 作用:全文搜索(帖文/用户/标签检索)与高级搜索的引擎开关。官方 sample 附带 ES_HOST=localhost / ES_PORT=9200 / ES_USER=elastic / ES_PASS=password 模板。
  • 本实测取值:false(未部署 ES,单实例搜索退化为数据库 LIKE 查询,小规模够用)。
  • 验证闭环(关闭状态下执行搜索索引命令,观察开关的真实约束):
docker compose run --rm web bin/tootctl search deploy

实测回显(报错首行):

Connection refused - Connection refused - connect(2) for "localhost" port 9200 (localhost:9200) (Elastic::Transport::Transport::Error)

解读:ES_ENABLED=false 只是不启用索引同步,search deploy 命令本身不受开关约束、仍直连 ES_HOST:ES_PORT 默认值——报错恰好证明当前没有可用的 ES。启用路径:编排文件启用官方注释的 ES 服务(docker.elastic.co/elasticsearch/elasticsearch:8.19.15)→ 本组参数改 true 并填 ES_HOST=elasticsearch → 重建服务 → tootctl search deploy 建索引。

3.7 对象存储参数组(S3_ENABLED / S3_BUCKET / AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / S3_ALIAS_HOST / EXTRA_MEDIA_HOSTS)

S3_ENABLED=false
  • 作用:媒体文件(图片/视频/表情/头像)的存储后端开关。false 落本地磁盘 ./public/system;true 走任意 S3 兼容对象存储(AWS S3、MinIO 等),S3_BUCKET、AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY 为凭据,S3_ALIAS_HOST 指向媒体自定义域名(CDN 直读)。
  • 本实测取值:false。
  • 验证闭环(上传一张媒体,确认 URL 落在本地存储路径 /system/ 下):
{"id":"117509984859987084","type":"image","url":"https://mastodon.local/system/media_attachments/files/117/509/984/859/987/084/original/35546cc09d618a6d.png",...}

url 含 /system/ 前缀即本地存储形态生效;切换 S3 后同一字段变为对象存储域名。EXTRA_MEDIA_HOSTS(可选)用于在远程媒体域之外追加允许展示的媒体主机白名单。

3.8 进程资源参数组(WEB_CONCURRENCY / MAX_THREADS / STREAMING_CLUSTER_NUM)

WEB_CONCURRENCY=1
MAX_THREADS=5
STREAMING_CLUSTER_NUM=1
  • 作用:三个应用进程的横向规模旋钮——WEB_CONCURRENCY 是 Puma 工作进程数,MAX_THREADS 是每进程线程池上限,STREAMING_CLUSTER_NUM 是流式服务进程数。
  • 默认口径:官方编排注释建议单机 20GB 内存场景 WEB_CONCURRENCY=2、MAX_THREADS=20;本实测 5 进程全套服务常驻内存合计约 963MiB(见部署篇第一章),单 worker 单机更省内存但吞吐有限。
  • Puma 启动日志直接反映两项取值(docker compose logs web | head):
[7] *  Min threads: 5
[7] *  Max threads: 5
[7] *      Workers: 1

完整的修改-验证-回滚闭环见第四章实测。

3.9 邮箱域校验参数组(EMAIL_DOMAIN_ALLOWLIST / EMAIL_DOMAIN_DENYLIST)

EMAIL_DOMAIN_ALLOWLIST=mastodon.local
  • 作用:注册邮箱域校验策略。Mastodon 默认会解析注册邮箱域名的 MX 记录,解析失败(或命中阻断列表)即拒绝注册;EMAIL_DOMAIN_ALLOWLIST 中的域名跳过 MX 解析直接放行,EMAIL_DOMAIN_DENYLIST 反之强制拒绝。
  • 典型场景:内网/测试实例用 .local、.invalid 等不可解析域名建号,必须加入白名单,否则注册校验拒绝;生产实例通常不设。
  • 正反对照实测(同一校验器,仅邮箱域不同):

反例——no-mx-domain.invalid 无 MX 记录、不在白名单:

docker compose run --rm web bin/rails runner "u=User.new(email:'mx-test@no-mx-domain.invalid', password:'q1w2e3r4q1w2e3r4', agreement:true, bypass_registration_checks:false); puts u.valid?; puts u.errors.full_messages.inspect"

实测回显:

false
["Account must exist", "E-mail address does not seem to exist", "E-mail address uses a disallowed e-mail provider"]

正例——mastodon.local 无 MX 记录、但命中 EMAIL_DOMAIN_ALLOWLIST:

docker compose run --rm web bin/rails runner "u=User.new(email:'allow-test@mastodon.local', password:'q1w2e3r4q1w2e3r4', agreement:true, bypass_registration_checks:false); puts u.valid?; puts u.errors.full_messages.inspect"

实测回显:

false
["Account must exist"]

解读:两例的 valid? 都为 false 是因为尚未关联 account 记录(Account must exist 属正常前置约束);差异在邮箱校验——反例叠加了「邮箱域不存在」「被阻断」两条错误,正例邮箱项零报错。白名单对 MX 校验的豁免作用以此确证。

3.10 数据保留参数组(IP_RETENTION_PERIOD / SESSION_RETENTION_PERIOD)

IP_RETENTION_PERIOD=31556952
SESSION_RETENTION_PERIOD=31556952
  • 作用:登录 IP 记录与会话记录的保留时长(单位秒,31556952 ≈ 一年,儒略年长度 365.2425 天——官方 sample 原值)。
  • ⚠️ 官方注释的联动关系(sample 原文):把 IP_RETENTION_PERIOD 降到两天(172800 秒)以下时,必须同步把 config/sidekiq.yml 中 ip_cleanup_scheduler 的调度间隔调得比它更短,否则清理赶不上新增。
  • 边界标注:本组参数为官方 sample 默认值,本实测未做改值验证(需长周期观察清理任务,超出本次实测窗口)。

3.11 运行环境与日志参数组(RAILS_ENV / RAILS_LOG_LEVEL)

RAILS_ENV=production
RAILS_LOG_LEVEL=warn
  • RAILS_ENV=production 生产固定值,影响 Rails 缓存、代码热载、错误页形态——改错会直接暴露调试信息,属高危项。
  • RAILS_LOG_LEVEL 取 debug/info/warn/error/fatal;warn 为生产均衡值(只留告警与错误),排障时临时改 debug 观察,完事改回。生效方式:需重建服务。
  • 验证方法:改 RAILS_LOG_LEVEL=debug 重建后访问任意 API,web 日志应出现完整请求行;warn 级别下同样操作日志保持安静(本实测在部署阶段已确认 warn 级别日志形态,未单独改值演示)。

四、配置变更标准流程实测(MAX_THREADS 5→10→5 全程实录)

环境变量类参数的任何修改都走同一条标准链:改文件 → up -d 重建 → 日志/行为验证 → 回滚。以 MAX_THREADS 为例完整实录。

第一步:记录现状(基线,见 3.8 启动日志:Min/Max threads 5)。

第二步:修改配置文件:

sed -i 's/^MAX_THREADS=5/MAX_THREADS=10/' .env.production
grep -n 'MAX_THREADS' .env.production

实测回显:

30:MAX_THREADS=10

第三步:重建生效——env_file 变化会被 up -d 检测,自动重建对应服务:

docker compose up -d web

实测回显(节选):

 Container mastodon-4.7.3-db Running 
 Container mastodon-4.7.3-redis Running 
 Container mastodon-4.7.3-web Recreate 
 Container mastodon-4.7.3-web Recreated 
 Container mastodon-4.7.3-web Starting 
 Container mastodon-4.7.3-web Started 

第四步:验证生效——新进程的启动日志应反映新值:

docker logs mastodon-4.7.3-web 2>&1 | grep -E 'threads' | head -3

实测回显:

[7] *  Min threads: 10
[7] *  Max threads: 10
[7] *  Min threads: 5
[7] *  Max threads: 5

(前两行为本次重建后的新进程:10;后两行为历史进程记录:5——取日志头部即当前值。)

第五步:回滚——同样的链路改回:

sed -i 's/^MAX_THREADS=10/MAX_THREADS=5/' .env.production
docker compose up -d web
docker logs mastodon-4.7.3-web 2>&1 | grep -E 'threads' | head -2

实测回显:

[7] *  Min threads: 5
[7] *  Max threads: 5

💡 说明:验证依据是 Puma 启动日志直读配置——比间接推测可靠。注意 docker compose restart 只重启进程、不重读 env_file,改环境变量后必须 up -d(编排检测环境差异自动重建);这是配置变更最常见的无效操作。

五、配置参数总表

.env.production 本实测启用项 + 官方 sample 涉及项全表(「实测」=本文有验证闭环;「引用」=官方文档/sample 口径,本实测未改值):

参数本实测值必填作用与验证要点状态
LOCAL_DOMAINmastodon.local✅联邦身份,不可安全更改;instance API uri 验证实测
WEB_DOMAIN(未设)—网页/API 域与联邦身份分离引用
RAILS_ENVproduction✅运行环境,固定 production实测
RAILS_LOG_LEVELwarn—日志级别,排障临时调 debug实测*
DB_HOST / DB_PORTdb / 5432✅主存储连接;pg_isready + tootctl 验证实测
DB_USER / DB_NAME / DB_PASSpostgres / mastodon / 空✅凭据;trust 认证配套说明见 3.2实测
REDIS_HOST / REDIS_PORTredis / 6379✅队列/缓存/订阅;redis-cli ping 验证实测
REDIS_PASSWORD / REDIS_NAMESPACE(未设)—Redis 口令与命名空间引用
SECRET_KEY_BASE(128 位生成值)✅会话加密基钥;rails secret 生成实测
OTP_SECRET(128 位生成值)✅OTP 加密;同上另跑一次实测
VAPID_PRIVATE_KEY / VAPID_PUBLIC_KEY(成对生成值)✅Web Push 签名;generate_vapid_key 生成实测
ACTIVE_RECORD_ENCRYPTION_* 三件套(生成值)✅(4.7.x 强制)字段加密;db:encryption:init 生成,不可改实测
SMTP_SERVER / SMTP_PORTlocalhost / 25✅出站邮件投递;UserMailer 投递实测实测
SMTP_LOGIN / SMTP_PASSWORD(未设)—SMTP 认证凭据,配 AUTH_METHOD引用
SMTP_AUTH_METHOD / SMTP_OPENSSL_VERIFY_MODE / SMTP_ENABLE_STARTTLS_AUTOnone / none / false—认证与 TLS 策略实测
SMTP_FROM_ADDRESSMastodon notifications@mastodon.local✅发件人实测
ES_ENABLEDfalse—全文搜索开关;search deploy 报错验证实测
ES_HOST / ES_PORT / ES_USER / ES_PASS(未设,默认 localhost:9200)—ES 连接信息引用
S3_ENABLEDfalse—媒体存储开关;媒体 URL /system/ 路径验证实测
S3_BUCKET / AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / S3_ALIAS_HOST(未设)—对象存储凭据与媒体域名引用
EXTRA_MEDIA_HOSTS(未设)—附加媒体主机白名单引用
WEB_CONCURRENCY1✅Puma worker 进程数;启动日志验证实测
MAX_THREADS5✅Puma 线程池;第四章全程闭环验证实测
STREAMING_CLUSTER_NUM1✅流式服务进程数实测
EMAIL_DOMAIN_ALLOWLISTmastodon.local—邮箱域 MX 校验豁免;正反对照实测实测
EMAIL_DOMAIN_DENYLIST(未设)—邮箱域强制拒绝引用
IP_RETENTION_PERIOD / SESSION_RETENTION_PERIOD31556952—IP/会话记录保留秒数;与 sidekiq.yml 调度联动引用

(「实测*」= 部署阶段确认日志形态,未单独改值演示;「未设」= 本实例未启用,按官方 sample/文档口径引用。)

六、参数依赖关系与决策树

改配置前先看依赖,避免改一半断服务:

  • 数据库认证二选一:POSTGRES_HOST_AUTH_METHOD=trust(内部网络 + 空密码)↔ POSTGRES_PASSWORD + DB_PASS(口令认证)。两者必须成对出现——只改一边会造成应用服务连不上库(restart 循环)。
  • ES 开关链:ES_ENABLED=true → 必须先有可连的 ES_HOST:ES_PORT → 重建后执行 tootctl search deploy 建索引;缺任何一步,搜索功能退化为数据库查询或报错(3.6 实测报错即缺第二步)。
  • S3 开关链:S3_ENABLED=true → S3_BUCKET + AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY 三项必填 → 可选 S3_ALIAS_HOST 自定义媒体域;历史媒体迁移用 tootctl media 组命令。
  • 邮箱域校验:不可解析域名(.local/.invalid)建号 → 必须进 EMAIL_DOMAIN_ALLOWLIST,否则注册校验拒绝(3.9 正反实测);生产环境用真实域名时无需白名单。
  • 资源三旋钮:WEB_CONCURRENCY × MAX_THREADS = web 并发上限;调大前者内存线性增长(每 worker 独立进程)、调大后者受数据库连接池约束——单机先动 MAX_THREADS,多核再动 WEB_CONCURRENCY。
  • 保留时长联动:IP_RETENTION_PERIOD < 2 天时必须同步 config/sidekiq.yml 的 ip_cleanup_scheduler(3.10 官方注释)。

七、常见问题

Q1:改了 .env.production 为什么不生效? 用了 docker compose restart——它只重启进程、不重读 env_file。改环境变量必须 docker compose up -d(检测环境差异自动重建,回显含 Recreate/Recreated,见第四章实录)。

Q2:如何确认某个参数当前生效值? 两类查法:环境变量类用 docker compose exec web sh -c 'env | grep KEY'(2.3 实测);实例设置类用 bin/rails runner "puts Setting.xxx"(2.2 实测)。前者来自文件,后者来自数据库,改错层是配置问题的一半来源。

Q3:db:encryption:init 提示已有密钥、拒绝生成? 说明 ACTIVE_RECORD_ENCRYPTION 三件套已配置(正常状态),回显见 3.4——这是保护机制,切勿用 IGNORE_ALREADY_SET_SECRETS=true 在已运行实例上重生成,旧密文将无法解密。

Q4:内网域名(如 mastodon.local)注册账号被拒? 默认 MX 解析校验拒绝不可解析域,把该域加入 EMAIL_DOMAIN_ALLOWLIST 即放行(3.9 实测对照)。报错形态为「E-mail address does not seem to exist」。

Q5:邮件发不出去,报 Connection refused? SMTP 参数指向的地址不可达(本实测 localhost:25 无投递服务,报错见 3.5)。核对 SMTP_SERVER/SMTP_PORT/SMTP_LOGIN/SMTP_PASSWORD 四项与邮件服务商文档,外网服务商通常 SMTP_PORT=587 + SMTP_AUTH_METHOD=plain。

Q6:想临时关闭注册? 属于实例设置层(2.2),不是环境变量:tootctl settings registrations close 立即生效(实测回显见 2.2),无需重启任何服务。

八、常用变更命令

cd /opt/mastodon
# 环境变量类:改文件 → 重建 → 验证(第四章完整实录)
sed -i 's/^MAX_THREADS=5/MAX_THREADS=10/' .env.production && docker compose up -d web
docker logs mastodon-4.7.3-web 2>&1 | grep threads | head -2

# 实例设置类:立即生效(注册开关)
docker compose run --rm web bin/tootctl settings registrations open    # 打开注册
docker compose run --rm web bin/tootctl settings registrations close   # 关闭注册

# 生效值速查
docker compose exec web sh -c 'env | grep -E "^DB_|^REDIS_"'           # 环境变量层
docker compose run --rm web bin/rails runner "puts Setting.registrations_mode"   # 实例设置层

# 密钥生成(仅首次部署用,运行中实例严禁重生成)
docker compose run --rm web bin/rails secret
docker compose run --rm web bin/rails mastodon:webpush:generate_vapid_key
docker compose run --rm web bin/rails db:encryption:init

# SMTP 链路验证(真实触发一次投递)
docker compose run --rm web bin/rails runner "begin; UserMailer.confirmation_instructions(User.find_by(email:'admin@mastodon.local'), 'testtoken', {}).deliver_now; rescue StandardError => e; puts \"#{e.class}: #{e.message}\"; end"

九、参考链接