PixelFed 0.15.2 配置参数详解
逐项讲清 PixelFed v0.15.2 的 .env 配置体系(APP/实例准入/站点地址与 Cookie/媒体/功能开关/数据库与 Redis/队列与 Horizon/联邦/邮件与对象存储),关键参数均给出修改、生效、验证的实测闭环,开放注册、故事、文案与相册上限四项完成行为级闭环。
PixelFed 0.15.2 配置参数详解
目标:逐项讲清 PixelFed v0.15.2 的 .env 配置体系(APP / 实例准入 / 站点地址与 Cookie / 媒体 / 功能开关 / 数据库与 Redis / 队列与 Horizon / 联邦 / 邮件与对象存储),每一组关键参数都给出「修改 → 生效 → 验证」的实测闭环。已在 Ubuntu 22.04 服务器(IP 192.168.146.128,端口 8135)实测通过,其中开放注册、故事开关、文案上限、相册上限四个参数完成了完整的行为级闭环验证。
一、环境信息
| 项目 | 实测值 |
|---|---|
| 操作系统 | Ubuntu 22.04(x86_64) |
| PixelFed | v0.15.2(官方编排形态部署) |
| 数据库 | MariaDB 11.8 |
| 缓存/队列 | Redis 8 |
| 配置文件 | /opt/pixelfed/.env(基于官方 .env.example 88 行) |
| 访问地址 | http://192.168.146.128:8135 |
| 演示账号 | admin / q1w2e3r4(管理员) |
本文命令均在部署目录 /opt/pixelfed 下执行,各 php artisan 命令一律通过编排内执行形态调用(同《PixelFed 0.15.2 Docker Compose 部署指南》4.6 节的方式)。
二、前置条件
- 已完成 v0.15.2 部署并迁移通过(
php artisan migrate:status计 268 个 Ran); - 服务全部 healthy(5 个服务 Up,健康检查通过);
- 已有管理员账号可登录(验证行为级闭环需要会话);
- 理解「配置缓存」双层机制(见第三章)——这是本文绝大多数「改了不生效」问题的根源。
三、参数查看与修改方式
3.1 查看参数当前值
两种实测方式:config:show(看 Laravel 运行时配置)与 tinker 的 config_cache()(看 Pixelfed 实例配置缓存层)。
# 方式一:config:show 查看像素配置组(pixelfed 配置键)
docker compose exec pixelfed php artisan config:show pixelfed
实测回显(输出节选):
max_photo_size ....................................................... 15000
max_caption_length ..................................................... 500
max_album_length ......................................................... 4
image_quality ........................................................... 80
# 方式二:tinker 查看实例配置缓存层取值
docker compose exec pixelfed php artisan tinker --execute='echo var_export(config_cache("pixelfed.max_album_length"),true);'
实测回显:
4
3.2 修改参数的标准三步
# 第 1 步:编辑 /opt/pixelfed/.env(本文以 sed 为例,手改亦可)
sed -i 's/MAX_ALBUM_LENGTH="4"/MAX_ALBUM_LENGTH="6"/' /opt/pixelfed/.env
# 第 2 步:重建服务使新环境变量进入运行时(restart 不重读 .env,实测无效)
cd /opt/pixelfed && docker compose up -d
# 第 3 步:验证生效
docker compose exec pixelfed php artisan config:show pixelfed | grep max_album_length
⚠️ 注意:
docker compose restart只重启不重读 .env,改动必须用up -d重建(实测踩坑:restart 后php -r 'echo getenv(...)'仍是旧值)。
3.3 「配置缓存」机制(改参数不生效的第一嫌疑)
Pixelfed 在 Laravel 自身配置缓存之外还有实例配置缓存(ENABLE_CONFIG_CACHE=true 时启用):启动时把一批实例级开关写入数据库 config_caches 表并同步到 Redis(键名形如 config_cache:_v0-key:pixelfed.open_registration,12 小时 TTL),运行期 config_cache() 优先读缓存,未命中才回源 config()。因此对实例级开关,仅改 .env 重建可能仍读旧值,需要「删缓存行 + 删 Redis 键 + 重建缓存」三连:
# 清除单键(以 pixelfed.open_registration 为例)
docker compose exec pixelfed php artisan tinker --execute='$r=\App\Models\ConfigCache::where("k","pixelfed.open_registration")->first(); if($r)$r->delete(); \Illuminate\Support\Facades\Cache::forget("config_cache:_v0-key:pixelfed.open_registration");'
# 重建配置/路由/视图缓存
docker compose exec pixelfed sh -c 'php artisan optimize:clear && php artisan optimize'
该机制在本文 5.2(开放注册)与 5.5(故事开关)两处有完整行为级闭环实测。
四、参数总览
按官方 .env.example 的分组顺序,v0.15.2 全量变量分组如下(默认值取自官方 .env.example,实测值取自本环境):
| 分组 | 变量(默认值 → 实测值) | 生效层级 |
|---|---|---|
| APP 基础 | APP_NAME="Pixelfed"、APP_ENV="production"、APP_KEY(必填生成)、APP_DEBUG="false"、APP_LOCALE="en-US" | 运行时 |
| 实例准入 | OPEN_REGISTRATION="false"、ENFORCE_EMAIL_VERIFICATION="false"、PF_MAX_USERS="1000"、PF_MIN_REGISTRATION_AGE="16"、OAUTH_ENABLED="true"、OAUTH_PAT_ENABLED="false" | 实例缓存 |
| 站点功能 | ENABLE_CONFIG_CACHE="true"、INSTANCE_DISCOVER_PUBLIC="true"、STORIES_ENABLED(未含于样例,默认 false → 实测 true) | 实例缓存 |
| 媒体 | IMAGE_DRIVER=vips、PF_OPTIMIZE_IMAGES="true"、IMAGE_QUALITY="80"、MAX_PHOTO_SIZE="15000"、MAX_CAPTION_LENGTH="500"、MAX_ALBUM_LENGTH="4" | 运行时 |
| 站点地址 | APP_URL、APP_DOMAIN、ADMIN_DOMAIN、SESSION_DOMAIN=null、TRUST_PROXIES="*"、FORCE_HTTPS_URLS(默认 true → 实测 false)、SESSION_SECURE_COOKIE(默认 true → 实测 false) | 运行时 |
| 数据库 | DB_CONNECTION="mysql"、DB_HOST="db"、DB_PORT="3306"、DB_DATABASE/DB_USERNAME/DB_PASSWORD(自定)、DB_ROOT_PASSWORD(编排健康检查引用) | 运行时 |
| Redis | REDIS_CLIENT="predis"、REDIS_SCHEME="tcp"、REDIS_HOST="redis"、REDIS_PASSWORD="null"、REDIS_PORT="6379" | 运行时 |
| 会话/队列 | SESSION_DRIVER="database"、CACHE_STORE="redis"、QUEUE_DRIVER="redis"、BROADCAST_DRIVER="log"、LOG_CHANNEL="stack"、HORIZON_PREFIX="horizon-" | 运行时 |
| 联邦 | ACTIVITY_PUB="false"、AP_REMOTE_FOLLOW="false"、AP_INBOX="false"、AP_OUTBOX="false"、AP_SHAREDINBOX="false" | 运行时 |
| 实验 | EXP_EMC="true"(媒体缓存扩展) | 实例缓存 |
| 邮件 | MAIL_DRIVER=log、MAIL_HOST/PORT/USERNAME/PASSWORD/ENCRYPTION、MAIL_FROM_ADDRESS="pixelfed@example.com"、MAIL_FROM_NAME="Pixelfed"、MAIL_AUTO_TLS=true | 运行时 |
| 对象存储 | PF_ENABLE_CLOUD=false、FILESYSTEM_CLOUD=s3、AWS_*(注释态) | 运行时 |
解读:标注「实例缓存」的分组受 3.3 节机制固化,改动要按三连步骤处理;「运行时」分组改 .env 重建即生效。
五、核心参数分类详解
5.1 APP 基础参数
| 变量 | 说明 |
|---|---|
| APP_KEY | 应用级加密密钥(会话/加密)。生成:docker compose exec pixelfed php artisan key:generate --show,实测输出 base64:bm8hWRcRAgQ9LFRyvDgraqvX1J23z2mSht7dKIp3n70=(每环境不同,不可照抄他人值)。更换后所有已登录会话失效 |
| APP_ENV | production / local。production 下日志精简、报错不外显 |
| APP_DEBUG | true 时错误页带堆栈,仅排障临时开启 |
| APP_LOCALE | 界面语言,en-US 默认 |
验证方式:
docker compose exec pixelfed php artisan config:show app | grep -E "env|debug"
实测回显(输出节选):
env ................................................................ production
debug ..................................................................... false
5.2 实例准入参数(含开放注册全闭环实测)
| 变量 | 说明 | 实测默认 |
|---|---|---|
| OPEN_REGISTRATION | 开放注册总开关,控制 /register 路由是否注册 | false |
| ENFORCE_EMAIL_VERIFICATION | 注册后强制邮箱验证 | false |
| PF_MAX_USERS | 实例用户总数上限 | 1000 |
| PF_MIN_REGISTRATION_AGE | 注册最小年龄限制 | 16 |
| OAUTH_ENABLED | OAuth 2.0(官方移动端/第三方客户端登录必需) | true |
| OAUTH_PAT_ENABLED | 个人访问令牌(PAT)自助签发入口 | false |
OPEN_REGISTRATION 实测闭环(三段完整行为验证):
- false 时 /register 直接 404(路由未注册):
curl -s -o /dev/null -w '%{http_code}\n' http://192.168.146.128:8135/register
实测回显:
404
- 改 .env 为 true 并按 3.3 三连清缓存后,路由注册成功:
curl -s http://192.168.146.128:8135/register | grep -oE '<title>[^<]*</title>'
实测回显:
<title>注册 · Pixelfed</title>
- 还原 false 并清缓存,恢复 404(略去回显,同第 1 步)。
⚠️ 注意:/register 路由是启动时按开关条件注册的——只清配置缓存不够,还必须
php artisan optimize:clear && php artisan optimize重建路由缓存,这是实测得出的完整生效条件。
5.3 站点地址与 Cookie 参数
| 变量 | 说明 | 实测结论 |
|---|---|---|
| APP_URL | 对外完整地址(含协议/端口) | 必须与实际访问地址一致 |
| APP_DOMAIN / ADMIN_DOMAIN | 域名约束(不含协议) | 路由按它注册,不一致整站 404 |
| FORCE_HTTPS_URLS | 强制生成 https 链接 | 默认 true;HTTP 部署必须 false |
| SESSION_SECURE_COOKIE | 会话 Cookie secure 标志 | 默认 true;HTTP 部署必须 false |
| TRUST_PROXIES | 反向代理场景的可信代理段 | "*" 表示全信任 |
APP_DOMAIN 实测闭环:配置 APP_DOMAIN="192.168.146.128" 时,用 127.0.0.1 访问登录页返回 404,而 API 正常——
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8135/login
curl -s -o /dev/null -w '%{http_code}\n' http://192.168.146.128:8135/login
实测回显:
404
200
原因:路由按 APP_DOMAIN 域名约束注册,Host 不匹配即 404。生产改域名时三处(APP_URL/APP_DOMAIN/ADMIN_DOMAIN)必须同步改。
FORCE_HTTPS_URLS 实测闭环:默认 true 时登录表单 action 被强制生成为 https:
<form method="POST" action="https://192.168.146.128:8135/login">
置 false 重建后:
<form method="POST" action="http://192.168.146.128:8135/login">
SESSION_SECURE_COOKIE 实测闭环:默认 true 时登录响应头带 secure(HTTP 下浏览器丢弃 Cookie,登录永远失败):
set-cookie: pxfs=...; path=/; httponly; samesite=lax; secure
置 false 重建后登录成功(302 → /i/web)。
5.4 媒体处理参数
| 变量 | 默认 | 说明 |
|---|---|---|
| IMAGE_DRIVER | vips | 图片处理驱动(vips/gd/imagick) |
| PF_OPTIMIZE_IMAGES | true | 上传后由队列异步优化(缩略/压缩),Horizon 停机会导致缩略图不生成 |
| IMAGE_QUALITY | 80 | JPEG 压缩质量(1-100) |
| MAX_PHOTO_SIZE | 15000 | 单图上限(KB,即 15MB) |
| MAX_CAPTION_LENGTH | 500 | 文案上限,按 Unicode 字符计数(实测 600 字符被拒、520 字符可发) |
| MAX_ALBUM_LENGTH | 4 | 单帖(相册)图片上限,可调至 10 |
MAX_CAPTION_LENGTH 实测闭环(520 字符通过 → 600 字符 422)。实测以 admin 会话复放发布接口:登录后的会话 Cookie 存入 cookies.txt、CSRF 令牌存入变量 XSRF(取值方法:登录响应头 X-XSRF-TOKEN,或浏览器开发者工具同名项):
curl -s -b cookies.txt -H "X-XSRF-TOKEN: $XSRF" -H 'Content-Type: application/json' \
-X POST http://192.168.146.128:8135/api/compose/v0/publish \
-d '{"caption":"(600 个『长』字)","media":[{"id":5,"cursor":0}],"visibility":"public"}'
实测回显:
{"message":"The caption field must not be greater than 500 characters.","errors":{"caption":["The caption field must not be greater than 500 characters."]}}
(HTTP 状态 422;验证时可先发 520 字符确认 200,再发 600 字符确认 422,两段本环境均实测。)
MAX_ALBUM_LENGTH 实测闭环(默认 4,一次提交 5 张只挂 4 张):一次 publish 请求携带 5 个 media id,实测返回 200 后核对:
docker compose exec pixelfed php artisan tinker --execute='$s=\App\Models\Status::where("caption","like","%相册上限实测%")->first(); echo "status_id=".$s->id." media_count=".\App\Models\Media::where("status_id",$s->id)->count(); echo " orphan=".join(",", \App\Models\Media::whereNull("status_id")->pluck("id")->all());'
实测回显:
status_id=1020378795510095814 media_count=4 orphan=5,10
第 5 张媒体被静默跳过并成为孤儿记录,维护窗口内可用 php artisan media:gc 清理(实测该命令仅回收超过 2 小时的孤儿媒体)。
IMAGE_DRIVER 验证:
docker compose exec pixelfed php artisan config:show pixelfed | grep -E "image_driver|image_quality"
实测回显:
image_driver ............................................................ vips
image_quality ........................................................... 80
5.5 站点功能开关(含故事开关闭环实测)
| 变量 | 默认 | 说明 |
|---|---|---|
| STORIES_ENABLED | false | 故事(Stories)功能总开关,关闭时相关路由不注册 |
| ENABLE_CONFIG_CACHE | true | 实例配置缓存(3.3 节机制) |
| INSTANCE_DISCOVER_PUBLIC | false | 发现页公开性 |
| EXP_EMC | false | 实验性媒体缓存(实测开启) |
STORIES_ENABLED 实测闭环:
- 默认 false 时上传故事直接被拒,实测响应体为空错误对象:
{"error":""}
- 改 .env 为 true、按 3.3 三连清缓存(对应键
instance.stories.enabled与pixelfed.stories.enabled)后,重新上传故事返回:
{"code":200,"msg":"Successfully added","media_id":"1020379318853533699","media_type":"photo"}
- 随后裁剪与发布两个接口均返回
{"code":200,"msg":"Successfully published"},故事出现在个人主页故事栏(GET /api/web/stories/v1/recent 返回含该故事的列表)。
💡 技术拓展:实例级开关的存储层级有三种形态——
层级 介质 生效方式 运行时 config .env → Laravel 配置 重建服务即生效 实例配置缓存 config_caches 表 + Redis(12h TTL) 需清缓存行与键 管理后台动态设置 config_caches 表(后台写入) 后台保存即时生效 同一开关可能同时出现在多层(如 OPEN_REGISTRATION 也可在管理后台切换),排查「不生效」时按「后台动态设置 → 实例缓存 → .env」顺序核对。本文方案统一走 .env + 三连清理。
5.6 数据库与 Redis 参数
docker compose exec pixelfed php artisan config:show database | grep -A2 "mysql ⇁"
实测回显(输出节选):
connections ⇁ mysql ⇁ host .............................................. db
connections ⇁ mysql ⇁ database .................................... pixelfed
| 变量 | 实测取值 | 说明 |
|---|---|---|
| DB_CONNECTION | mysql | 驱动名(MariaDB 亦用 mysql 驱动);切换 PostgreSQL 改 pgsql |
| DB_HOST / DB_PORT | db / 3306 | 编排内服务名 |
| DB_DATABASE / DB_USERNAME / DB_PASSWORD | pixelfed / pixelfed / q1w2e3r4 | 业务库凭据 |
| DB_ROOT_PASSWORD | q1w2e3r4 | 编排健康检查引用,缺失会导致数据库初始化失败 |
| REDIS_CLIENT / REDIS_SCHEME / REDIS_HOST / REDIS_PORT | predis / tcp / redis / 6379 | 编排内服务名 |
| REDIS_PASSWORD | null | 编排未设密码,字面量 null |
MySQL 9 不可用的实测结论(迁移中断):
ERROR 3763 (HY000) at line 1: Expression of generated column 'key_hash' contains a disallowed function: `md5`.
同一语句 MariaDB 11.8 实测建表成功。因此 DB 连接层面选 MariaDB 11.x;切换数据库后需重建服务并重新迁移(数据不自动迁移,跨库迁移属另一话题)。
5.7 会话、缓存与队列参数
| 变量 | 实测取值 | 说明 |
|---|---|---|
| SESSION_DRIVER | database | 会话存数据库 sessions 表(重装应用不丢登录态);可改 redis |
| CACHE_STORE | redis | 应用缓存 |
| QUEUE_DRIVER | redis | 异步队列,Horizon 消费 |
| BROADCAST_DRIVER | log | 广播(Websocket 未启用时 log) |
| LOG_CHANNEL | stack | 日志通道 |
| HORIZON_PREFIX | horizon- | Horizon 的 Redis 键前缀(多实例共用 Redis 时区分) |
队列验证(Horizon 工作器与队列通路):
docker compose exec pixelfed php artisan horizon:status
实测回显:
INFO Horizon is running.
docker compose exec pixelfed php artisan queue:failed
实测回显:
INFO No failed queue jobs found.
行为佐证:上传图片后 Media 表 processed_at 非空、缩略图生成(队列消费完成的标志,实测 3 张媒体全部 processed)。
5.8 联邦参数(ActivityPub)
| 变量 | 默认 | 说明 |
|---|---|---|
| ACTIVITY_PUB | false | 联邦总开关 |
| AP_REMOTE_FOLLOW | false | 允许远程账号关注本站用户 |
| AP_INBOX / AP_OUTBOX / AP_SHAREDINBOX | false | 收件箱/发件箱/共享收件箱端点开关 |
| INSTANCE_DISCOVER_PUBLIC | false | 实例元数据公开 |
docker compose exec pixelfed php artisan app:federation
实测回显(本环境 ACTIVITY_PUB=false,单实例形态,全文照抄):
================================================================
CONFIG
================================================================
✓ APP_ENV is production
✗ ActivityPub is disabled env=false admin setting=false
↳ Set ACTIVITY_PUB=true, then run php artisan config:cache.
! Inbox (AP_INBOX) is disabled
! Outbox (AP_OUTBOX) is disabled
! Shared inbox (AP_SHAREDINBOX) is disabled
! Remote follow (AP_REMOTE_FOLLOW) is disabled
✓ WebFinger enabled
✓ NodeInfo enabled
· Authorized fetch disabled (env=false)
· Followers sync (FEP-8fcf) enabled
· Delivery tuning timeout=30s concurrency=10 failure_threshold=5 max_backoff=604800s
✗ APP_URL is not https http://192.168.146.128:8135
↳ Actor ids are built from APP_URL and Pixelfed only accepts https ActivityPub URLs.
✓ APP_URL host matches APP_DOMAIN 192.168.146.128
✓ Cached config is newer than .env
· Cache store redis
✓ No pending migrations
================================================================
INSTANCE ACTOR
================================================================
✓ Instance actor exists http://192.168.146.128:8135/i/actor
✓ Instance actor keypair is valid 2048 bit RSA, public key derives from private key
✓ Cached private key matches the database
✓ Cached public key matches the database
· Cached actor document not cached yet
================================================================
LOCAL ENDPOINTS (outside-in)
================================================================
✓ host-meta points at /.well-known/webfinger
✓ WebFinger acct:admin@192.168.146.128 self link is http://192.168.146.128:8135/users/admin
✓ NodeInfo discovery http://192.168.146.128:8135/api/nodeinfo/2.0.json
✓ NodeInfo document pixelfed 0.15.2, protocols: activitypub
✓ Instance actor document id, inbox and publicKeyPem all match
✗ Actor @admin as application/activity+json HTTP 302, expected 200
↳ Redirects to http://192.168.146.128:8135/admin. Remote servers do not reliably follow redirects here, APP_URL should be the canonical origin.
✗ Actor @admin as application/ld+json HTTP 302, expected 200
↳ Redirects to http://192.168.146.128:8135/admin. Remote servers do not reliably follow redirects here, APP_URL should be the canonical origin.
✓ Shared inbox route reaches Laravel GET /f/inbox returned 405 as expected
================================================================
HTTP SIGNATURES
================================================================
✓ All active local profiles have a keypair 2 profiles
✓ POST signature round trip as @admin signed headers: (request-target) host date digest content-type user-agent
✓ GET signature round trip as the instance actor signed headers: (request-target) host date accept
================================================================
QUEUES
================================================================
· Queue connection redis (redis driver)
✓ Horizon is running 1 master supervisor(s)
+---------+--------+---------+------+-------------------------------------------------+
| Queue | Worker | Pending | Wait | Carries |
+---------+--------+---------+------+-------------------------------------------------+
| default | yes | 0 | 0s | outbound status delivery |
| high | yes | 0 | 0s | user inbox activities |
| shared | yes | 0 | 0s | shared inbox activities |
| follow | yes | 0 | 0s | inbound and outbound follows |
| inbox | yes | 0 | 0s | inbound actor deletes |
| delete | yes | 0 | 0s | inbound deletes |
| story | yes | 0 | 0s | story deletes |
| feed | yes | 0 | 0s | likes, home feed inserts after ingest |
| low | yes | 0 | 0s | shares, signing actor discovery, remote avatars |
| move | yes | 0 | 0s | account migration |
+---------+--------+---------+------+-------------------------------------------------+
✓ No failed federation jobs in the last 24h 0 failed jobs scanned
================================================================
DELIVERY HEALTH
================================================================
· Known instances 0 total, 0 banned
✓ No hosts with delivery failures
· Banned domain cache not cached yet
· Audience of @admin 0 inboxes on 0 hosts, 0 host(s) currently skipped
================================================================
ENVIRONMENT
================================================================
· PHP 8.5.12 (cli)
✓ Required PHP extensions and dns_get_record() are available
✗ Own domain does not pass the public IP check from this server 192.168.146.128 -> 192.168.146.128
↳ Helpers::validateLocalUrl() fails here, so inbound Follows, replies (inReplyTo) and Undos that reference local URLs are dropped. One private or reserved record (split-horizon DNS, internal resolver, ULA AAAA) is enough. Negative results are cached for 5 minutes.
✗ Outbound HTTPS to https://pixelfed.org failed ConnectionException: cURL error 28: Connection timed out after 5001 milliseconds (see https://curl.se/libcurl/c/libcurl-errors.html) for https://pixelfed.org
↳ If every outbound request fails, look at the egress firewall, DNS and the CA bundle (curl.cainfo).
================================================================
SUMMARY
================================================================
23 ok, 4 warning(s), 6 failure(s), 0 skipped
FAILURES:
✗ [config] ActivityPub is disabled
✗ [config] APP_URL is not https
✗ [endpoints] Actor @admin as application/activity+json
✗ [endpoints] Actor @admin as application/ld+json
✗ [env] Own domain does not pass the public IP check from this server
✗ [env] Outbound HTTPS to https://pixelfed.org failed
WARNINGS:
! [config] Inbox (AP_INBOX) is disabled
! [config] Outbox (AP_OUTBOX) is disabled
! [config] Shared inbox (AP_SHAREDINBOX) is disabled
! [config] Remote follow (AP_REMOTE_FOLLOW) is disabled
要点(均来自诊断器自身输出):CONFIG 节明确提示 ✗ APP_URL is not https,并注明 Actor id 由 APP_URL 构建、Pixelfed 只接受 https 的 ActivityPub URL;实例 Actor 由 instance:actor 命令创建(重复执行幂等,实测回显 Instance actor succesfully generated. You do not need to run this command again.);LOCAL ENDPOINTS 节两项 ✗(Actor JSON 探测被 302 重定向到登录页)是 APP_URL 非 https 域名的伴生现象;ENVIRONMENT 节两项 ✗(内网 IP 未通过公网解析检查、出站 HTTPS 探测 5 秒超时)是纯内网环境的预期表现。本环境为纯内网 HTTP 部署,如实保持 ACTIVITY_PUB=false 的单实例本地验证形态,联邦互通需公网 HTTPS 域名后另行启用。
六、生产配置模板
适用场景:2 核 4GB 内存、NVMe SSD 100GB、50–200 用户社区、本地磁盘存储。在官方 .env.example 基础上修改以下关键项(其余保持默认):
# ── 基础 ──
APP_NAME="社区名称"
APP_ENV="production"
APP_DEBUG="false"
APP_LOCALE="zh-CN" # 界面语言
APP_KEY=${PIXELFED_APP_KEY} # 由 php artisan key:generate --show 生成后注入(见 5.1 节实测输出)
# ── 地址(公网域名 + 反代 TLS 场景)──
APP_URL="https://pixelfed.example.com"
APP_DOMAIN="pixelfed.example.com"
ADMIN_DOMAIN="pixelfed.example.com"
TRUST_PROXIES="*" # 前置 Nginx/Caddy 时保留
FORCE_HTTPS_URLS="true" # 有 TLS 时保持默认
SESSION_SECURE_COOKIE="true" # 有 TLS 时保持默认
# ── 准入治理 ──
OPEN_REGISTRATION="false" # 人工/邀请制
ENFORCE_EMAIL_VERIFICATION="true" # 配合真实 SMTP
PF_MAX_USERS="200"
OAUTH_ENABLED="true"
# ── 媒体 ──
IMAGE_DRIVER=vips
PF_OPTIMIZE_IMAGES="true"
IMAGE_QUALITY="85"
MAX_PHOTO_SIZE="15000"
MAX_CAPTION_LENGTH="1000"
MAX_ALBUM_LENGTH="6"
STORIES_ENABLED="true"
# ── 数据层 ──
DB_CONNECTION="mysql"
DB_HOST="db"
DB_DATABASE="pixelfed"
DB_USERNAME="pixelfed"
DB_PASSWORD="q1w2e3r4" # 演示口令,生产环境务必更换
DB_ROOT_PASSWORD="q1w2e3r4" # 编排健康检查引用,生产环境务必更换
REDIS_HOST="redis"
# ── 会话/队列 ──
SESSION_DRIVER="database"
CACHE_STORE="redis"
QUEUE_DRIVER="redis"
# ── 联邦(公网 HTTPS 就绪后再开)──
ACTIVITY_PUB="true"
AP_REMOTE_FOLLOW="true"
AP_INBOX="true"
AP_OUTBOX="true"
AP_SHAREDINBOX="true"
# ── 邮件(真实 SMTP)──
MAIL_DRIVER=smtp
MAIL_HOST=smtp.example.com
MAIL_PORT=587
MAIL_USERNAME=${SMTP_USERNAME} # 由邮箱服务商获取后注入
MAIL_PASSWORD=${SMTP_PASSWORD}
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS="pixelfed@example.com"
MAIL_FROM_NAME="Pixelfed"
⚠️ 上述模板中 ${PIXELFED_APP_KEY}、${SMTP_USERNAME}、${SMTP_PASSWORD} 为环境级真实密钥,禁止照抄示例:APP_KEY 用
php artisan key:generate --show生成(5.1 节有实测输出),SMTP 凭据由邮箱服务商控制台获取后替换;数据库口令沿演示口径,生产环境必须更换。媒体量大(TB 级)时叠加 S3 组:PF_ENABLE_CLOUD=true + FILESYSTEM_CLOUD=s3 + AWS_* 七项。
七、常见问题
Q1:改了 .env 重建后行为还是旧值
按「后台动态设置 → 实例配置缓存 → .env」顺序排查:先确认管理后台没有保存过同义开关;再按 3.3 三连清实例缓存键与 config_caches 行;最后确认用 up -d 而非 restart 重建。STORIES_ENABLED 与 OPEN_REGISTRATION 两个开关本环境均复现过此链路并给出完整闭环(5.5/5.2)。
Q2:内网 HTTP 部署登录不上、表单跳 https FORCE_HTTPS_URLS 与 SESSION_SECURE_COOKIE 两个默认值均为 https 场景设计,HTTP 部署必须双双置 false(5.3 有表单 action 与响应头两级实测证据)。
Q3:文案明明没超 500 却被拒(或超了却没拒) MAX_CAPTION_LENGTH 按 Unicode 字符计数:520 个汉字实测可发,600 个汉字实测 422。若给中文社区放宽限制,直接调大该值即可。
Q4:上传成功但缩略图一直不生成
PF_OPTIMIZE_IMAGES=true 时优化在 Horizon 队列执行,先查 php artisan horizon:status;确认 Horizon 服务存活后,重试 php artisan media:optimize 补跑,实测输出 Queued 0 media candidates.(0 表示当前无待优化积压)。
Q5:想切 PostgreSQL
DB_CONNECTION=pgsql + 对应 DB_HOST/PORT/库名,重建后重新迁移(Pulse 迁移在 PG 下用 md5("key")::uuid 表达式,官方已适配);数据不自动跨库,需另行导出导入。