Plainpad 1.2.0 配置参数详解
Plainpad 1.2.0 三层配置面实测详解:.env 15 键与 compose 环境变量映射、settings 表 9 键、用户偏好 6 键逐项说明,APP_KEY 优先级与加密开关批量重加密闭环验证、生产配置模板与六条常见问题(2026-11-02)。
Plainpad 1.2.0 配置参数详解
目标:把 Plainpad 1.2.0 的全部可调参数面——
.env键、进程环境变量、应用级 Settings 与每用户偏好——逐项讲清含义、默认值与生效验证方法,关键参数全部在跑着的部署上实测闭环。部署过程见 《Plainpad 1.2.0 Docker Compose 部署实战》 篇(本栏 B2),本文沿用同一套运行环境取证。
一、环境信息
本文全部参数与回显取自 2026-11-02 实测的一套运行中部署(B2 篇产物):
- 操作系统:Ubuntu 26.04.1 LTS(Resolute Raccoon),x86_64
- 部署形态:Docker Compose 项目
plainpad-1.2.0-stack,应用服务plainpad(官方镜像 alextselegidis/plainpad:latest,应用版本 1.2.0)+ 数据库服务mysql(mysql:8.0) - 对外访问:
http://localhost:8139;API 基址http://localhost:8139/api.php/v1 - 数据库凭据:root/secret,库名 plainpad
- 管理员账号:admin@example.org / 12345678(官方播种,id
7a17c8fd-b84f-4f2c-8ba3-2a484c1a0e1e)
运行栈与版本用 Laravel 自带的 about 命令一次性取证:
cd /opt/data/quzuo/tmp/plainpad/stack
docker compose exec plainpad php artisan about
实测回显(2026-11-02):
PHP Deprecated: Constant PDO::MYSQL_ATTR_SSL_CA is deprecated since 8.5, use Pdo\Mysql::ATTR_SSL_CA instead in /var/www/html/config/database.php on line 62
Environment ................................................................
Application Name .................................................. Plainpad
Laravel Version .................................................... 12.69.0
PHP Version ......................................................... 8.5.12
Composer Version ......................................................... -
Environment ..................................................... production
Debug Mode ............................................................. OFF
URL ......................................................... localhost:8139
Maintenance Mode ....................................................... OFF
Timezone ............................................................... UTC
Locale ............................................................... en-US
Cache ......................................................................
Config .......................................................... NOT CACHED
Events .......................................................... NOT CACHED
Routes .......................................................... NOT CACHED
Views ........................................................... NOT CACHED
Drivers ....................................................................
Broadcasting .......................................................... null
Cache ................................................................. file
Database ............................................................. mysql
Logs ................................................................. daily
Mail .......................................................................
Queue ................................................................. sync
Session ............................................................... file
Storage ....................................................................
public/storage .................................................. NOT LINKED
回显要点:应用跑在 production、Debug OFF;数据库驱动 mysql;会话与缓存都是 file 驱动(存在应用文件系统内,重建即失效);首行的 PHP Deprecated 是应用 config/database.php 使用了 PHP 8.5 已废弃常量的无害提示(见 B2 篇排障记录)。
💡 技术拓展:
about显示的各项驱动在 Laravel 中均可换实现,Plainpad 默认值的取舍——
驱动面 本文实测值 常见可选项 Plainpad 用默认值的后果 Session file cookie / database / redis 重建应用即在线登录失效,无需额外中间件 Cache file redis / database / array 无缓存穿透风险,但换机需带 storage/目录Queue sync database / redis 任务同步执行,不装 worker 也不丢消息 Logs daily single / syslog 按天滚动,位于 storage/logs/这些键虽在
.env体系内可写,但官方.env.example并未暴露它们(见第四章总览),常规部署保持默认即可。
二、前置条件
- 已按 B2 篇完成部署且服务健康:
cd /opt/data/quzuo/tmp/plainpad/stack
docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
plainpad-1.2.0-app alextselegidis/plainpad:latest "docker-entrypoint.sh" plainpad 14 minutes ago Up 14 minutes 0.0.0.0:8139->80/tcp, [::]:8139->80/tcp
plainpad-1.2.0-db mysql:8.0 "docker-entrypoint.s…" mysql 25 minutes ago Up 25 minutes 3306/tcp, 33060/tcp
-
具备进入应用服务执行命令的通道(本文用
docker compose exec plainpad <命令>,等价于在应用安装目录/var/www/html下操作)。 -
走 API 修改应用级/用户级参数时,需要一个管理员 Bearer Token。获取方法(实测回显):
curl -s -X POST http://localhost:8139/api.php/v1/sessions \
-H 'Content-Type: application/json' \
-d '{"email":"admin@example.org","password":"12345678"}'
# {"user_id":"7a17c8fd-b84f-4f2c-8ba3-2a484c1a0e1e","expires_at":"2026-11-02 12:20:47","token":"FE5Is0r75P5jZoalOwHKpWi0NlAsAJwNGRWsRqqFNcwtwD9kWCLQk5RDEPxS"}
export TOKEN=FE5Is0r75P5jZoalOwHKpWi0NlAsAJwNGRWsRqqFNcwtwD9kWCLQk5RDEPxS
本文 API 命令中的 $TOKEN 即取上述真实返回值;令牌过期后重新登录换取即可。
三、参数查看与修改方式
Plainpad 的可调参数分布在三个配置面上,各自的查看与修改入口不同——这是理解本文的关键:
| 配置面 | 存储位置 | 查看方式 | 修改方式 | 生效时机 |
|---|---|---|---|---|
环境变量 / .env | 应用根目录 /var/www/html/.env | docker compose exec plainpad cat .env | compose 服务 environment: + 重建 | 服务重启 |
| 应用级设置 | 数据库 settings 表(键值行) | 应用内 Settings 页 / API / 查库 | 应用内 Settings 页 / API PUT /v1/settings | 即时 |
| 用户偏好 | 数据库 users 表列 | 应用内 Profile 页 / API / 查库 | 应用内 Profile 页 / API PUT /v1/users/{ID} | 即时 |
3.1 环境变量与 .env
.env 共 15 个键(官方 .env.example 模板 + 注释,实测全文节选):
docker compose exec plainpad cat .env
APP_NAME=Plainpad
APP_ENV=production
APP_KEY={KEY}
APP_DEBUG=false
APP_URL=http://localhost:8139
APP_REPOSITORY=https://cdn.alextselegidis.com/plainpad/updates/stable
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=plainpad
DB_USERNAME=root
DB_PASSWORD=secret
(原文件每个键上方带一段英文注释,此处按键值摘录。)注意 APP_KEY={KEY} 仍是模板占位符——这是官方镜像的正常形态:应用实际使用进程环境变量里的密钥,优先级验证见 5.1。
修改方式的正确姿势:在 compose 文件 plainpad 服务的 environment: 列表增删改,然后:
docker compose up -d plainpad
入口脚本会在每次启动时把 BASE_URL/DEBUG_MODE/DB_* 环境变量 sed 回写进 .env(脚本原文实测摘录见 5.2/5.3),直接手工编辑 .env 的这几个键会在下次重启时被环境变量覆盖(见第七章 7.1)。
3.2 应用级设置(settings 表)
数据库里以「一行一键」存储,实测全表:
docker compose exec mysql mysql -uroot -psecret -e 'select name,value from plainpad.settings;'
name value
mail_from_address notes@quzuo.net
mail_port 1025
mail_password
mail_from_name Plainpad
default_locale zh-CN
mail_driver smtp
mail_host 10.89.58.1
mail_encryption
mail_username
(表中值是本实验改过的状态,播种默认值见 5.5。)修改入口有两个:应用内 Settings 页面(Mail / Language 两栏),或管理员走 API:
curl -s http://localhost:8139/api.php/v1/settings -H "Authorization: Bearer $TOKEN"
# {"mail_from_address":"notes@quzuo.net","mail_port":"1025","mail_password":"","mail_from_name":"Plainpad","default_locale":"zh-CN","mail_driver":"smtp","mail_host":"10.89.58.1","mail_encryption":"","mail_username":""}
改法与逐项含义见 5.5。
3.3 用户偏好(users 表列)
偏好不是键值对而是表列,合法取值以数据库约束为准,实测列定义:
docker compose exec mysql mysql -uroot -psecret -e 'describe plainpad.users;'
Field Type Null Key Default
id varchar(255) NO PRI NULL
created_at timestamp YES NULL
updated_at timestamp YES NULL
name varchar(255) NO NULL
email varchar(255) NO MUL NULL
password varchar(255) NO NULL
locale varchar(255) NO en-US
view enum('comfortable','compact') NO compact
line enum('full','narrow') NO full
sort enum('modified','created','alphabetical') NO modified
theme enum('light','dark') NO light
encrypt tinyint(1) NO 0
admin tinyint(1) NO 0
修改入口:应用内 Profile 页(每个用户改自己的),或管理员走 API PUT /v1/users/{ID}(实测见 5.6)。
3.4 artisan 命令面
应用自定义的 artisan 命令只有两个(框架命令除外),实测:
docker compose exec plainpad php artisan list | grep -E '^\s+(refresh|cleanup)'
cleanup Removed unnecessary system files.
refresh Refresh the Plainpad installation after an update.
refresh 用于升级后刷新安装(迁移+缓存),cleanup 清理系统冗余文件,均无参数、静默执行。它们不修改配置值,但 refresh 是「改了 compose 环境变量重建后」推荐的收尾动作(B2 篇 10.4)。
四、参数总览
4.1 .env 15 键总览
| 键 | 官方默认值(.env.example) | 作用 | compose 环境变量可覆盖 |
|---|---|---|---|
| APP_NAME | Plainpad | 应用名(通知/框架文案用) | 否(入口脚本不处理) |
| APP_ENV | production | 运行环境 | 否 |
| APP_KEY | {KEY}(占位) | 加密密钥派生种子 | 是(APP_KEY,环境变量优先) |
| APP_DEBUG | false | 调试模式,出错显示堆栈 | 是(DEBUG_MODE=TRUE/FALSE) |
| APP_URL | {URL}(占位) | 应用访问前缀(生成链接/console 用) | 是(BASE_URL) |
| APP_REPOSITORY | https://cdn.alextselegidis.com/plainpad/updates/stable | 自动更新源 | 否(需挂载改 .env,见 5.4) |
| DB_CONNECTION | mysql | 数据库驱动 | 否(官方部署路径仅 MySQL,见 5.3) |
| DB_HOST | localhost(镜像内默认 db) | 数据库主机 | 是(DB_HOST) |
| DB_PORT | 3306 | 数据库端口 | 否 |
| DB_DATABASE | {DATABASE}(镜像内默认 plainpad) | 库名 | 是(DB_NAME) |
| DB_USERNAME | {USERNAME}(镜像内默认 root) | 数据库用户 | 是(DB_USERNAME) |
| DB_PASSWORD | {PASSWORD}(镜像内默认 secret) | 数据库口令 | 是(DB_PASSWORD) |
(表内「镜像内默认值」来自官方镜像 ENV 实查,传统 PHP 主机安装时以 .env.example 占位符为准。)
4.2 官方镜像环境变量总览
官方 Docker 部署只认这 7 个环境变量(来源:官方 Docker 文档 + 入口脚本实测):
| 环境变量 | 映射到 .env 键 | 说明 |
|---|---|---|
| APP_KEY | APP_KEY | 不写进 .env,以环境变量直接生效(5.1) |
| BASE_URL | APP_URL | 生产写真实域名 |
| DEBUG_MODE | APP_DEBUG | 仅接受 TRUE/FALSE(大小写均识别) |
| DB_HOST | DB_HOST | 等于数据库服务名 |
| DB_NAME | DB_DATABASE | 库名 |
| DB_USERNAME | DB_USERNAME | 用户名 |
| DB_PASSWORD | DB_PASSWORD | 口令 |
⚠️ 注意:镜像 ENV 里另有
MAIL_SMTP_*/MAIL_FROM_*一批默认值,入口脚本并不处理它们——邮件配置不走环境变量(实测入口脚本全文无 MAIL 相关分支,见 5.5)。
4.3 应用级与用户级参数总览
| 层 | 参数 | 默认值(播种/表定义) | 修改入口 |
|---|---|---|---|
| settings | default_locale | en-US | Settings 页 / API |
| settings | mail_driver / mail_host / mail_port / mail_username / mail_password / mail_encryption / mail_from_address / mail_from_name | smtp / smtp.mailtrap.io / 2525 / 空 / 空 / tls / hello@example.org / Plainpad | Settings 页 Mail / API |
| users | locale | en-US(合法值见 5.6) | Profile 页 / API |
| users | view | compact | Profile 页 / API |
| users | line | full | Profile 页 / API |
| users | sort | modified | Profile 页 / API |
| users | theme | light | Profile 页 / API |
| users | encrypt | 0(关) | Profile 页 / API |
| users | admin | 0 | 仅管理员经 API/用户管理界面 |
五、核心参数分类详解
5.1 APP_KEY:加密命脉
APP_KEY 是 Laravel encrypter 的主密钥,Plainpad 用它派生每个用户笔记的加密密钥。官方文档与镜像注释反复强调:一次生成、永久复用,丢失即灾难。
实测优先级验证——.env 里 APP_KEY={KEY} 是占位符,而应用实际生效的是 compose 注入的环境变量值:
docker compose exec plainpad php artisan tinker --execute="echo config('app.key');"
# base64:vB6IesmBqpSCj5ruR1H0PjcSecgiBVNtdBjCNdRaeI0=
与 compose 文件里 APP_KEY=base64:vB6IesmBqpSCj5ruR1H0PjcSecgiBVNtdBjCNdRaeI0= 完全一致。入口脚本的密钥逻辑(官方镜像脚本原文摘录):
if grep -q "APP_KEY=$" /var/www/html/.env || grep -q "APP_KEY={KEY}" /var/www/html/.env; then
cd /var/www/html && php artisan key:generate --force
fi
即:.env 里密钥为空或仍是 {KEY} 占位时尝试生成;若环境变量已提供 APP_KEY,key:generate 会拒绝覆写并打出 ERROR Unable to set application key. APP_KEY is already present in the environment.——这条 ERROR 正是「固定密钥」在按预期工作(B2 篇 11.3)。
生成方法(新部署时执行一次并永久保存):
echo "base64:$(openssl rand -base64 32)"
💡 技术拓展:APP_KEY 加密笔记的落盘格式是 Laravel encrypter 的 JSON 载荷,实测(5.6 加密闭环)形如
{"iv":"...","value":"...","mac":"..."},算法由config/app.php固定为'cipher' => 'AES-256-CBC'(实查)并附 HMAC 防篡改。常见对称加密模式对比——
模式 特点 代表 AES-128/256-CBC + HMAC 密文不可链式篡改需另配 MAC Laravel encrypter 默认(本文所用) AES-256-GCM 自带认证标签,一次遍历完成加密+校验 现代 TLS/存储加密主流 XSalsa20/ChaCha20 无硬件加速环境性能好 NaCl/libsodium 系 Plainpad 跟随 Laravel 默认 AES-256-CBC,密钥即 APP_KEY,因此换 APP_KEY = 全部密文报废。
5.2 BASE_URL / DEBUG_MODE:访问前缀与调试开关
入口脚本对这两个键的改写逻辑(官方镜像脚本原文摘录):
if [ -n "$BASE_URL" ]; then
sed -i "s|APP_URL=.*|APP_URL=${BASE_URL}|g" /var/www/html/.env
fi
if [ -n "$DEBUG_MODE" ]; then
if [ "$DEBUG_MODE" = "TRUE" ] || [ "$DEBUG_MODE" = "true" ]; then
sed -i "s|APP_DEBUG=.*|APP_DEBUG=true|g" /var/www/html/.env
else
sed -i "s|APP_DEBUG=.*|APP_DEBUG=false|g" /var/www/html/.env
fi
fi
实测对应关系:compose 设 BASE_URL=http://localhost:8139 → .env 内 APP_URL=http://localhost:8139(3.1 全文回显)→ artisan about 的 URL 行显示 localhost:8139(第一章回显),三处一致即映射生效。DEBUG_MODE=FALSE → APP_DEBUG=false → about 显示 Debug Mode ... OFF。
- BASE_URL:应用生成绝对链接(如邮件内链接)的前缀,生产必须写真实域名(如
https://notes.example.com),否则通知邮件里的链接指向错误主机。 - DEBUG_MODE:仅排障时临时 TRUE——出错页面会带堆栈与配置细节,公网环境常开等于信息泄露。
5.3 DB_*:数据库连接五键
compose 环境变量 DB_HOST/DB_NAME/DB_USERNAME/DB_PASSWORD 由入口脚本逐一 sed 进 .env(脚本原文与 5.2 同段,逻辑相同:if [ -n "$DB_HOST" ]; then sed ...)。实测生效链:compose DB_HOST=mysql → .env DB_HOST=mysql(3.1 回显)→ artisan about 的 Drivers 区 Database ... mysql(第一章回显)→ 数据读写正常(3.2 查库回显)。
后端支持范围:应用 config/database.php 保留了 Laravel 的 sqlite/mysql/pgsql/sqlsrv 四套连接模板(实查行号 38/46/66/81),但官方部署路径只支持 MySQL/MariaDB——入口脚本等待数据库就绪的 PDO 探测硬编码 mysql:host=,.env.example 也固定 DB_CONNECTION=mysql,官方文档示例同样只有 MySQL。把 DB_CONNECTION 改成 pgsql 会绕过入口脚本的等待逻辑且不被官方支持,生产勿试。
DB_PORT 固定 3306(.env 键存在但 compose 环境变量列表不含它;同网段服务名直连时默认端口足够)。
5.4 APP_REPOSITORY:自动更新源
.env 键 APP_REPOSITORY=https://cdn.alextselegidis.com/plainpad/updates/stable,实查其唯一消费点在自动更新服务提供者:
docker compose exec plainpad grep -rn "APP_REPOSITORY" app/
# app/Providers/AutoUpdateServiceProvider.php:21: $autoUpdateService->setUpdateUrl(env('APP_REPOSITORY'));
它决定应用内 Settings→Update 与 API 根资源(GET /v1 的 updates 列表、PUT /v1 触发更新)从哪个源解析更新包;1.2.0 起发布包带 Ed25519 签名(.sig)校验,校验不过即拒绝(来源:官方 1.2.0 Release Notes,见 《Plainpad 1.2.0 介绍与选型指南》 篇三)。实测当前源无新版本时的行为:
curl -s -X PUT http://localhost:8139/api.php/v1 -H "Authorization: Bearer $TOKEN" -w '\nHTTP %{http_code}\n'
# HTTP 404
404 即「没有可安装的更新」(源码逻辑:检查源后无新版本直接回 404)。若内网隔离环境想自建更新源,需修改 .env 该键——但入口脚本不映射它,只能挂载自定义 .env 或进应用目录改文件,且 Docker 形态下官方不建议应用内自动更新(更新写入文件系统,重建即丢,见 B2 篇第五节),该键主要服务于传统 PHP 主机安装。
5.5 应用级设置(settings 表 9 键)
播种默认值来自官方 SettingsSeeder(实查源码),与 3.2 实测表对照即知哪些被改过:
| 键 | 播种默认 | 作用 |
|---|---|---|
| default_locale | en-US | 新用户默认界面语言 |
| mail_driver | smtp | 邮件传输方式 |
| mail_host | smtp.mailtrap.io | SMTP 主机 |
| mail_port | 2525 | SMTP 端口 |
| mail_username | 空 | SMTP 账号 |
| mail_password | 空 | SMTP 口令 |
| mail_encryption | tls | SMTP 加密方式 |
| mail_from_address | hello@example.org | 发件人地址 |
| mail_from_name | Plainpad | 发件人名称 |
修改走管理员 API(非管理员调用返回 401,实测见 《Plainpad 1.2.0 API 使用详解》 篇)。下面是一次真实的 PUT 回写(值即当前生效状态)与 GET 复核:
curl -s -X PUT http://localhost:8139/api.php/v1/settings \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"default_locale":"zh-CN","mail_driver":"smtp","mail_host":"10.89.58.1","mail_port":"1025","mail_username":"","mail_password":"","mail_encryption":"","mail_from_address":"notes@quzuo.net","mail_from_name":"Plainpad"}' \
-w '\nHTTP %{http_code}\n'
# HTTP 200(成功时响应体为空)
curl -s http://localhost:8139/api.php/v1/settings -H "Authorization: Bearer $TOKEN"
# {"mail_from_address":"notes@quzuo.net","mail_port":"1025","mail_password":"","mail_from_name":"Plainpad","default_locale":"zh-CN","mail_driver":"smtp","mail_host":"10.89.58.1","mail_encryption":"","mail_username":""}
两个要点:
- 邮件配置只存在于 settings 表,与镜像 ENV 里的
MAIL_SMTP_*默认值无关(入口脚本不处理它们,官方文档明确 "Mail is not configured through environment variables")。忘记 SMTP 口令时改库或走 API,不要去翻环境变量。 - default_locale 只决定新用户/未设置偏好者的语言,已有用户各自
locale列优先(3.3 表定义),所以改完 default_locale 老用户界面不变是预期行为(见 7.6)。
💡 技术拓展:
mail_driver可选的 Laravel 邮件传输方式——
驱动 行为 适用 smtp 连 SMTP 服务器投递 生产标准(本文实测用) log 邮件内容写日志不投递 调试/审计 sendmail 交给本机 sendmail 程序 主机已有 MTA array / null 收件箱置内存/丢弃 测试 Plainpad 播种默认 smtp;无邮件服务器时找回/通知邮件会静默失败(API 仍回 200),生产建议配真实 SMTP 或明确接受「无邮件」。
5.6 用户偏好(6 键)与加密开关闭环
偏好键与合法值(数据库 enum 约束实测 + 源码实查 app/Models/User.php 的 public const LOCALES = ['en-US', 'de-DE', 'fr-FR', 'sv-SE', 'zh-CN'];):
| 键 | 合法值 | 默认 | 作用 |
|---|---|---|---|
| locale | en-US / de-DE / fr-FR / sv-SE / zh-CN | en-US | 界面语言 |
| view | comfortable / compact | compact | 列表密度 |
| line | full / narrow | full | 行宽 |
| sort | modified / created / alphabetical | modified | 笔记默认排序 |
| theme | light / dark | light | 主题 |
| encrypt | 0 / 1 | 0 | 服务端加密开关(见下) |
修改实测(管理员 PUT 用户,成功回显返回整个用户对象):
curl -s -X PUT http://localhost:8139/api.php/v1/users/7a17c8fd-b84f-4f2c-8ba3-2a484c1a0e1e \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"name":"Admin","email":"admin@example.org","locale":"en-US","view":"compact","line":"full","sort":"modified","theme":"light","admin":true,"encrypt":true}'
# {"id":"7a17c8fd-b84f-4f2c-8ba3-2a484c1a0e1e","created_at":"2026-11-02T00:20:21.000000Z","updated_at":"2026-11-02T00:47:23.000000Z","name":"Admin","email":"admin@example.org","locale":"en-US","view":"compact","line":"full","sort":"modified","theme":"light","encrypt":true,"admin":true}
⚠️ 注意:PUT 是全量提交语义——payload 必须带齐 name/email/locale/view/line/sort/theme/admin/encrypt 全部字段,漏字段即被重置或校验失败(1.2.0 之前「编辑用户丢失加密标志导致笔记不可读」正是这类事故的官方修复,来源:1.2.0 Release Notes)。
encrypt 开关闭环实测(本次取证的核心):
第一步,开启 encrypt 后新建笔记,API 返回明文、但数据库落密文:
curl -s -X POST http://localhost:8139/api.php/v1/notes \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"title":"加密测试标题","content":"这是会被服务端加密的正文内容。","pinned":false}'
# 输出节选:{"id":"01c33676-f0ec-49a5-a7eb-32b1e8afe0c8",...,"title":"\u52a0\u5bc6\u6d4b\u8bd5\u6807\u9898","content":"\u8fd9\u662f\u4f1a\u88ab\u670d\u52a1\u7aef\u52a0\u5bc6\u7684\u6b63\u6587\u5185\u5bb9\u3002",...}
docker compose exec mysql mysql -uroot -psecret -e "select left(title,60) as t,left(content,60) as c from plainpad.notes;"
t c
eyJpdiI6Im1FZnRMZzJ0MUZYZnJjZFNwS2lxU2c9PSIsInZhbHVlIjoiZ0hx eyJpdiI6IjA2YzZpUGoyMTZsalQ2UXdWa0hBYkE9PSIsInZhbHVlIjoiV2hw
base64 解开头即 {"iv":...,"value":...}——标题与正文均以 Laravel encrypter 密文入库(5.1 拓展表),这正是官网「你写的日记 vs 数据库里的密文」演示的落地形态。
第二步,把开关切回关闭,既有笔记被批量解密回明文——实测先建一条明文基线笔记,再开开关,笔记立即变密文;再关开关,DB 直接查回明文:
docker compose exec mysql mysql --default-character-set=utf8mb4 -uroot -psecret -e "select left(title,30) as t,left(content,30) as c from plainpad.notes;"
t c
明文基线 关闭状态下的正文
即:开关切换 = 对该用户全部笔记做一次完整的解密/加密重写,API 读取始终透明返回明文。这带来两个运维含义:数据量大的账号切换开关耗时随笔记数线性增长;切换中途失败会留下混合状态(1.2.0 已修复此缺陷,来源:官方 Release Notes),切换前务必备份数据库(B2 篇 10.3)。
六、生产配置模板
综合前三章,生产环境(真实域名 + HTTPS 反代之后)的 compose 配置模板:
name: plainpad-prod
services:
plainpad:
image: alextselegidis/plainpad:latest
depends_on:
- mysql
ports:
- '127.0.0.1:80:80' # 只监听回环,由 Nginx/Caddy 反代终结 TLS
environment:
- APP_KEY=base64:你的固定密钥-openssl-rand-base64-32生成后存入密码管理器
- BASE_URL=https://notes.example.com
- DEBUG_MODE=FALSE
- DB_HOST=mysql
- DB_NAME=plainpad
- DB_USERNAME=plainpad
- DB_PASSWORD=换强口令与mysql服务一致
networks:
- plainpad-net
mysql:
image: mysql:8.0
command: --default-authentication-plugin=mysql_native_password
environment:
- MYSQL_ROOT_PASSWORD=换强口令
- MYSQL_DATABASE=plainpad
- MYSQL_USER=plainpad
- MYSQL_PASSWORD=与上方DB_PASSWORD一致
volumes:
- db_data:/var/lib/mysql
networks:
- plainpad-net
volumes:
db_data:
networks:
plainpad-net:
driver: bridge
相对实验版(B2 篇)的三处生产化改动及理由:
- BASE_URL 写真实域名:5.2——邮件内链接与生成 URL 的唯一来源;
- 数据库改用普通账号:不再 root 直连,
MYSQL_USER/MYSQL_PASSWORD与DB_USERNAME/DB_PASSWORD对应即可(入口脚本只认这 5 个 DB 键,5.3); - 端口只绑 127.0.0.1:PWA 安装与「加密传输」前提都要求 HTTPS,TLS 交给反向代理(官方文档:安装为应用需要 HTTPS)。
上线后按序验证与加固(每步都有实测方法):
curl -s -o /dev/null -w 'HTTP %{http_code}\n' https://notes.example.com/ # 期望 200
- 用默认管理员
admin@example.org / 12345678首登,立即在 Profile 改邮箱与密码(官方播种值人人可知); - Settings→Mail 填真实 SMTP(5.5),发一封找回密码邮件验证投递;
- Settings 改
default_locale为团队语言; - 每个账号在 Profile 按需开
encrypt(5.6,开前备份)。
七、常见问题
7.1 直接编辑了 .env,重启后改动被吞
现象:进应用目录改了 .env 的 APP_URL/DB_HOST 等,docker compose restart 后改回原值。原因:入口脚本每次启动按环境变量 sed 覆写这些键(5.2/5.3 脚本原文)。解决:改动一律落到 compose environment: 再 docker compose up -d plainpad;入口脚本不覆写的键(如 APP_REPOSITORY)直接改 .env 才有效,但重建应用文件系统时 .env 若未挂载会按模板重建——长期定制建议挂载持久化或接受「环境变量 + 应用内设置」的官方面。
7.2 重启日志出现 "ERROR Unable to set application key"
ERROR Unable to set application key. APP_KEY is already present in the environment.
无害(B2 篇 11.3):.env 内 APP_KEY 是 {KEY} 占位、触发入口脚本的 key:generate --force,而环境变量已有固定密钥,Laravel 拒绝覆写——这正是 5.1 描述的「环境变量优先、密钥固定」在正常工作。可忽略。
7.3 想用 MAIL_SMTP_* 环境变量配邮件,改了没反应
镜像 ENV 里的 MAIL_SMTP_*/MAIL_FROM_* 是残留默认值,入口脚本不处理(4.2 注意项),官方文档明确邮件不走环境变量。解决:应用内 Settings→Mail 或 API PUT /v1/settings(5.5 实测)。
7.4 换了 APP_KEY,加密笔记全部无法打开
APP_KEY 是笔记密文的派生密钥(5.1),换 key 后旧密文永久不可解。恢复方法只有一个:把 APP_KEY 改回原值。预防:密钥生成即入密码管理器,compose 文件纳入备份;这也是官方文档反复强调「固定复用」的原因。
7.5 开启/关闭 encrypt 后应用短暂无响应
开关切换会重写该用户全部笔记的密文/明文(5.6 实测语义),笔记量大时耗时线性增长。操作前备份数据库(B2 篇 10.3),避开高峰执行。
7.6 改了 default_locale,老用户界面语言没变
预期行为:default_locale 只作用于新用户(5.5),每个用户的 locale 列优先。让老用户各自在 Profile 改语言,或管理员经 API PUT /v1/users/{ID} 代改(5.6 实测,注意全量字段)。
八、参考链接
- 官方 Docker 文档(环境变量表出处):https://plainpad.org/docs/admin/docker/ (2026-11-02 实查)
- 官方安装文档:https://plainpad.org/docs/admin/installation/ (2026-11-02 实查)
- GitHub 仓库(
.env.example/SettingsSeeder/User::LOCALES源码):https://github.com/alextselegidis/plainpad (1.2.0) - 站内同栏:《Plainpad 1.2.0 介绍与选型指南》、《Plainpad 1.2.0 Docker Compose 部署实战》、《Plainpad 1.2.0 API 使用详解》