Psono v7.5.3 Docker Compose 部署指南
Psono v7.5.3 Docker Compose 部署实测:组合镜像与 PostgreSQL 18 双服务编排、密钥生成、首管理员创建、健康检查三项自检、time_sync 400 排障实录与可选 Redis 缓存增强,全部命令与回显实测于 2026-10-24。
Psono v7.5.3 Docker Compose 部署指南
目标:在一台 Ubuntu 22.04 服务器上,用 Docker Compose 从零部署 Psono 社区版 v7.5.3(组合镜像 + PostgreSQL 18 + 可选 Redis 缓存),完成密钥生成、数据库初始化、首个管理员创建与 Web/管理门户登录验证。全文命令与回显均在 Ubuntu 22.04 + Docker 29.8.1 环境实测于 2026-10-24。
一、环境信息
本文实测环境与部署规划如下,读者按自己的服务器调整 IP 与端口即可:
- 操作系统:Ubuntu 22.04(x86_64)
- Docker:29.8.1(含 Compose v2 插件)
- Psono:v7.5.3(Build 5638426c,
psono/psono-combo:latest实测回显) - PostgreSQL:postgres:18-alpine(官方安装文档指定)
- Redis(可选):redis:8-alpine(缓存与限流计数后端)
- 服务器 IP:192.168.146.128(示例,替换为你的服务器地址)
- Web 端口:8153(映射到组合镜像内部 80)
- 部署目录:
/opt/docker/psono/(配置)与/opt/docker/psono/pgdata/(数据库数据) - Compose 项目名:
psono-7.5.3-stack(显式命名,避免多栈环境下被同名项目误删)
二、镜像选型说明
Psono 官方在 Docker Hub 发布多个镜像,选型依据官方安装文档(doc.psono.com「Install Psono CE」,2026-10-24 实查):
| 镜像 | 内容 | 适用 |
|---|---|---|
psono/psono-combo | 服务端 + Web 客户端 + 管理门户 + Nginx | 推荐默认,一个服务搞定全部 Web 面 |
psono/psono-server | 仅服务端(Daphne ASGI) | 静态资源独立部署/多实例扩展 |
psono/psono-client | 仅 Web 客户端静态文件 | 自建 CDN/独立站点 |
postgres:18-alpine | 数据库(官方安装文档指定版本) | 唯一强依赖存储 |
关键差异与如何选型:combo 与「分离部署」的功能完全一致,差异只在打包方式。首次部署、单机部署、无 CDN 需求,一律选 psono/psono-combo;只有当 Web 静态资源需要单独扩容或接入 CDN 时才拆分。本文采用 combo + PostgreSQL 双服务形态,Redis 作为可选增强(第六章)。镜像版本策略:本文实测时 latest 即 v7.5.3(服务端 /server/info/ 回显 "version": "7.5.3 (Build 5638426c)"),生产环境建议固化到具体版本标签,避免 latest 隐式升级。
三、前置条件
- Ubuntu 22.04 服务器,已安装 Docker 与 Compose 插件:
docker version --format '{{.Server.Version}}'
docker compose version
实测回显:
29.8.1
Docker Compose version v2.39.2
- 服务器时间与 NTP 可达性:Psono 健康检查会校验时间同步(默认对
time.google.com),境内网络需提前确认替代 NTP 源可达(第五章实测排障)。 - 规划端口:本文用 8153(确认未被占用):
ss -ltn | grep 8153 || echo "8153 空闲"
实测回显:
8153 空闲
- 创建部署目录:
mkdir -p /opt/docker/psono/pgdata
cd /opt/docker/psono
四、部署步骤
4.1 生成服务端密钥
Psono 安装的第一步是生成 7 个服务端密钥。官方命令通过组合镜像执行内置脚本 generateserverkeys.py:
docker run --rm -ti psono/psono-combo:latest python3 ./psono/generateserverkeys.py
实测回显(密钥为本次实测环境随机生成,读者执行会得到不同值;ADMIN_RECOVERY_PRIVATE_KEY 是恢复私钥,必须离线打印保存,严禁写入 settings.yaml 或留在服务器):
# Copy paste this content into your settings.yml and replace existing occurrences
#
# WARNING: Do this only for a fresh installation!
# Changing those variables afterwards will break the program e.g.:
# Activation links will not work, Server will not be able to read user emails, ...
SECRET_KEY: 'rIZ7Jqj20eS72dTcfTaFToQ4m928r8DI4G72nTtEhch2Q7yrefxdPF41W6UB1t8e'
ACTIVATION_LINK_SECRET: 'UXwBVwJ8NGzkQom6rseTijcVNAVgkcHTk0S0Vdksl7HvAyoP31NsfWYHtGgNkuXq'
DB_SECRET: 'RE0bhLwLAlwTU2Yz4QRS54dgfaNOjCgZ3tdA6QdchtBLecgJl3GsOYRiRxjos8H8'
EMAIL_SECRET_SALT: '$2b$12$Fsmqo9X3928MUmaQNETElu'
PRIVATE_KEY: '450197ac4b435a0ef69340213aef0fc354cb00347f23d3514dd5c735dae7f364'
PUBLIC_KEY: 'b97434da89fe500ee68410af75d4d41c99eb50975e99c9eec064d522601f7845'
ADMIN_RECOVERY_PUBLIC_KEY: '9238938b674a00effc2d610842c81bd5dbf93f606cacabd54590962486349d44'
# ============================================================================
# OFFLINE ADMIN RECOVERY PRIVATE KEY
#
# IMPORTANT: Print this private key and store the printout securely offline.
# Do NOT copy it into settings.yml or keep it on the server.
# Anyone with this key may be able to decrypt protected recovery data.
# ============================================================================
ADMIN_RECOVERY_PRIVATE_KEY: 'c0641f94e3ba4878558e50c87cc3595e631aa5e5422b592a1201cb9e5b60a1e9'
⚠️ 注意:该脚本在非交互终端(如自动化脚本)中执行时,
-ti参数会报错cannot attach stdin to a TTY-enabled container because stdin is not a terminal,去掉-t只保留-i或两者都去掉即可。
4.2 编写 settings.yaml
在 /opt/docker/psono/ 创建 settings.yaml,将 4.1 生成的密钥填入前 7 行,数据库口令替换为你的强口令:
SECRET_KEY: 'rIZ7Jqj20eS72dTcfTaFToQ4m928r8DI4G72nTtEhch2Q7yrefxdPF41W6UB1t8e'
ACTIVATION_LINK_SECRET: 'UXwBVwJ8NGzkQom6rseTijcVNAVgkcHTk0S0Vdksl7HvAyoP31NsfWYHtGgNkuXq'
DB_SECRET: 'RE0bhLwLAlwTU2Yz4QRS54dgfaNOjCgZ3tdA6QdchtBLecgJl3GsOYRiRxjos8H8'
EMAIL_SECRET_SALT: '$2b$12$Fsmqo9X3928MUmaQNETElu'
PRIVATE_KEY: '450197ac4b435a0ef69340213aef0fc354cb00347f23d3514dd5c735dae7f364'
PUBLIC_KEY: 'b97434da89fe500ee68410af75d4d41c99eb50975e99c9eec064d522601f7845'
ADMIN_RECOVERY_PUBLIC_KEY: '9238938b674a00effc2d610842c81bd5dbf93f606cacabd54590962486349d44'
# Web 客户端地址(不含尾斜杠)
WEB_CLIENT_URL: 'http://192.168.146.128:8153'
# NTP 时间服务器(默认 time.google.com,境内不可达时替换)
TIME_SERVER: 'ntp.aliyun.com'
# 反向代理层数(组合镜像内置 Nginx 一层 + 若前面还有反代则再加)
NUM_PROXIES: 2
# 生产环境必须为 False
DEBUG: False
ALLOWED_HOSTS: ['*']
# 用户名域名部分(登录页展示的域名后缀)
ALLOWED_DOMAINS: ['example.com']
# 服务器对外地址(激活链接等以此生成)
HOST_URL: 'http://192.168.146.128:8153/server'
# 发信邮箱(未配置邮件时可用命令行创建用户,不影响部署验证)
EMAIL_FROM: 'psono@example.com'
EMAIL_HOST: 'smtp.example.com'
EMAIL_HOST_USER: ''
EMAIL_HOST_PASSWORD: ''
EMAIL_PORT: 25
EMAIL_SUBJECT_PREFIX: ''
EMAIL_USE_TLS: False
EMAIL_USE_SSL: False
EMAIL_SSL_CERTFILE:
EMAIL_SSL_KEYFILE:
EMAIL_TIMEOUT: 10
# 管理门户 API(门户必需,默认 False)
MANAGEMENT_ENABLED: True
# PostgreSQL 连接(HOST 为 compose 服务名 psono-db)
DATABASES:
default:
'ENGINE': 'django.db.backends.postgresql_psycopg2'
'NAME': 'psono'
'USER': 'psono'
'PASSWORD': 'q1w2e3r4'
'HOST': 'psono-db'
'PORT': '5432'
TEMPLATES: [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': ['/root/psono/templates'],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
逐项说明:7 个密钥决定加密与链接签名行为,一经使用不可更改(官方警告:改了会导致激活链接失效、邮件解密失败);WEB_CLIENT_URL/HOST_URL 必须是用户浏览器可达的地址;ALLOWED_DOMAINS 决定用户名的域名部分(如 root@example.com);NUM_PROXIES: 2 对应「组合镜像内置 Nginx + 外层反向代理」的默认链路,若直接裸暴露 8153 不再套外层反代,可设为 1。配置参数全集与调优见本专栏《Psono v7.5.3 配置参数详解》。
4.3 编写 docker-compose.yml
创建 /opt/docker/psono/docker-compose.yml:
name: psono-7.5.3-stack
services:
psono-db:
image: postgres:18-alpine
restart: unless-stopped
environment:
POSTGRES_USER: psono
POSTGRES_PASSWORD: q1w2e3r4
POSTGRES_DB: psono
volumes:
- ./pgdata:/var/lib/postgresql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U psono -d psono"]
interval: 10s
timeout: 5s
retries: 5
networks:
- psono-net
psono-server:
image: psono/psono-combo:latest
restart: unless-stopped
sysctls:
net.core.somaxconn: 65535
volumes:
- ./settings.yaml:/root/.psono_server/settings.yaml:ro
- ./config.json:/usr/share/nginx/html/config.json:ro
- ./config.json:/usr/share/nginx/html/portal/config.json:ro
ports:
- "8153:80"
depends_on:
psono-db:
condition: service_healthy
networks:
- psono-net
networks:
psono-net:
driver: bridge
name: psono-753-net
ipam:
config:
- subnet: 10.89.58.0/24
配置要点逐项说明:name: 显式固定项目名,多套 compose 栈并存时防止 docker compose down 误伤其他项目;数据库密码必须与 settings.yaml 的 DATABASES.PASSWORD 一致;健康检查让 psono-server 等数据库真正就绪后再启动,避免首启迁移失败;somaxconn=65535 是官方启动命令中的原样参数;子网显式指定为 10.89.58.0/24(创建前先 docker network ls 确认该网段空闲,冲突时换一段)。
再创建组合镜像所需的 Web 客户端配置 /opt/docker/psono/config.json(同时挂给用户端与门户端):
{
"backend_servers": [
{
"title": "Psono Self-Hosted",
"url": "http://192.168.146.128:8153/server"
}
],
"base_url": "http://192.168.146.128:8153/",
"allow_custom_server": true,
"allow_registration": true,
"allow_lost_password": true,
"disable_download_bar": false,
"remember_me_default": false,
"trust_device_default": false,
"authentication_methods": [
"AUTHKEY"
],
"saml_provider": []
}
说明:backend_servers[].url 指向服务端地址,title 显示在登录页服务器选择器中;authentication_methods 默认 AUTHKEY(口令认证),接入 SAML/LDAP 后在此追加。
4.4 启动与自动迁移
组合镜像的启动入口自带数据库迁移(先执行 manage.py migrate 再拉起 ASGI 服务),直接启动即可:
cd /opt/docker/psono
docker compose up -d
实测回显:
Container psono-753-stack-psono-db-1 Started
Container psono-753-stack-psono-db-1 Waiting
Container psono-753-stack-psono-db-1 Healthy
Container psono-753-stack-psono-server-1 Starting
Container psono-753-stack-psono-server-1 Started
确认两个服务的健康状态:
docker compose ps --format 'table {{.Name}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}'
实测回显:
NAME IMAGE STATUS PORTS
psono-753-stack-psono-db-1 postgres:18-alpine Up 35 seconds (healthy) 5432/tcp
psono-753-stack-psono-server-1 psono/psono-combo:latest Up 25 seconds (health: starting) 0.0.0.0:8153->80/tcp, [::]:8153->80/tcp
服务端健康检查通过后(约 30–60 秒)状态变为 (healthy)。
4.5 验证服务版本与健康状态
打开服务信息端点(返回签名 JSON,验证部署版本):
curl -s "http://127.0.0.1:8153/server/info/"
实测回显(节选,完整响应含 signature/verify_key 签名字段):
{"info":"{\"version\": \"7.5.3 (Build 5638426c)\", \"api\": 1, \"log_audit\": false, \"public_key\": \"b97434da89fe500ee68410af75d4d41c99eb50975e99c9eec064d522601f7845\", \"admin_recovery_public_key\": \"9238938b674a00effc2d610842c81bd5dbf93f606cacabd54590962486349d44\", \"authentication_methods\": [\"AUTHKEY\"], \"web_client\": \"http://192.168.146.128:8153\", \"management\": true, \"files\": true, \"allowed_file_repository_types\": [\"azure_blob\", \"gcp_cloud_storage\", \"aws_s3\", \"do_spaces\", \"backblaze\"], \"favicon_service_url\": \"https://favicon.psono.com/v1/icon/\", \"allowed_second_factors\": [\"yubikey_otp\", \"webauthn\", \"google_authenticator\", \"duo\"], \"multifactor_enabled\": false, \"type\": \"CE\", ...}","signature":"69147b26…","verify_key":"b4eb25cc…"}
关键信息:version 确认版本与构建号;type: "CE" 确认社区版;management: true 确认管理门户 API 已开。
健康检查端点(数据库读写 + 时间同步三项自检):
curl -s -w "\nHTTP=%{http_code}\n" "http://127.0.0.1:8153/server/healthcheck/"
实测回显:
{"db_read":{"healthy":true},"db_sync":{"healthy":true},"time_sync":{"healthy":true},"_info":{"ip":"10.89.58.1"}}
HTTP=200
三项全 true 且 HTTP 200 即部署成功。首次部署若 time_sync 为 false,见第七章 7.1 排障。
4.6 创建首个管理员
未配置邮件时的标准做法:命令行创建用户并提权。必须在 compose 网络内执行(docker compose exec),否则单发命令解析不了数据库主机名(见第七章 7.2):
docker compose exec psono-server python3 ./psono/manage.py createuser root@example.com q1w2e3r4 admin@example.com
实测回显:
Created user "root@example.com" with password "******" and email "admin@example.com"
docker compose exec psono-server python3 ./psono/manage.py promoteuser root@example.com superuser
实测回显:
Promoted user "root@example.com" to "superuser"
说明:createuser 三个参数依次是「用户名(必须形如邮箱,域名部分须在 ALLOWED_DOMAINS 内)、密码、联系邮箱」;演示口令为 q1w2e3r4,生产环境务必改强口令;promoteuser 仅首个管理员需要,之后可在门户内管理。
4.7 Web 客户端与管理门户登录验证
浏览器打开三个地址逐一验证(实测均返回 HTTP 200):
curl -s -o /dev/null -w "webclient HTTP=%{http_code}\n" "http://192.168.146.128:8153/"
curl -s -o /dev/null -w "portal HTTP=%{http_code}\n" "http://192.168.146.128:8153/portal/"
curl -s -o /dev/null -w "info HTTP=%{http_code}\n" "http://192.168.146.128:8153/server/info/"
实测回显:
webclient HTTP=200
portal HTTP=200
info HTTP=200
http://192.168.146.128:8153/:用户端 Web 保险库,用root@example.com/q1w2e3r4登录。http://192.168.146.128:8153/portal/:管理门户,同一账号登录后可管理用户、分组、策略与合规设置。
⚠️ 注意:以上为 HTTP 验证路径。生产环境必须按官方反代文档前置 Nginx 做 TLS 卸载(官方提供含 CSP 头的完整 server 块,
client_max_body_size 256m),并将WEB_CLIENT_URL/HOST_URL/config.json全部改为 HTTPS 域名。
五、数据持久化说明
| 数据 | 落盘路径(宿主机) | 挂载点(服务内) | 备份要点 |
|---|---|---|---|
| PostgreSQL 全部数据 | /opt/docker/psono/pgdata/ | /var/lib/postgresql | 密码库唯一真实数据源 |
| settings.yaml | /opt/docker/psono/settings.yaml | /root/.psono_server/settings.yaml | 含解密所需密钥,与数据库同等保密级别 |
| Web/门户 config.json | /opt/docker/psono/config.json | /usr/share/nginx/html/config.json(及 portal/config.json) | 可随时重建 |
数据目录验证:
ls /opt/docker/psono/pgdata/ | head -8
实测回显:
PG_VERSION
pg_hba.conf
pg_ident.conf
postgresql.auto.conf
postgresql.conf
备份/恢复双件套:数据库(pg_dumpall 或物理备份 pgdata/)+ settings.yaml(离线保存)。丢失 settings.yaml 中的密钥等于丢失全部密码库——服务端密钥参与数据加密与链接签名,官方备份文档将两者并列为完整备份的必要条件。
升级与回滚:改 docker-compose.yml 中镜像标签到目标版本 → docker compose pull && docker compose up -d;组合镜像每次启动自动执行 migrate,升级前先备份数据库与 settings.yaml,回滚即把镜像标签改回旧版本重新 up -d(数据库迁移一般向后兼容一个次版本,跨大版本回滚需按官方 Update 文档核对)。
六、环境变量表(可选 Redis 缓存增强)
官方支持用环境变量替代 settings.yaml 全量配置(前缀 PSONO_,官方「Environment Variables」文档实查,2026-10-24),常用项如下:
| 环境变量 | 对应 settings.yaml 键 | 说明 |
|---|---|---|
PSONO_SECRET_KEY | SECRET_KEY | 必填,主密钥 |
PSONO_PRIVATE_KEY / PSONO_PUBLIC_KEY | PRIVATE_KEY / PUBLIC_KEY | 必填,服务器签名密钥对 |
PSONO_ACTIVATION_LINK_SECRET | ACTIVATION_LINK_SECRET | 必填,激活链接签名 |
PSONO_DB_SECRET | DB_SECRET | 必填,数据库字段加密 |
PSONO_EMAIL_SECRET_SALT | EMAIL_SECRET_SALT | 必填,邮件加密盐 |
PSONO_HOST_URL | HOST_URL | 必填,对外服务地址 |
PSONO_DATABASE_URL | DATABASES | 必填,URL 形式数据库连接 |
PSONO_ALLOWED_DOMAINS | ALLOWED_DOMAINS | 用户名域名白名单 |
PSONO_NUM_PROXIES | NUM_PROXIES | 反代层数 |
PSONO_ALLOW_REGISTRATION | ALLOW_REGISTRATION | 开放注册开关 |
PSONO_THROTTLE_RATE_LOGIN | 同名限流组 | 登录限流速率 |
PSONO_MANAGEMENT_COMMAND_ACCESS_KEY | — | 管理命令访问密钥 |
Redis 缓存增强:在 compose 中追加 psono-cache 服务(官方 settings.yaml 注释原文:「Cache enabled without belows Redis may lead to unexpected behaviour」——开启缓存必须同时配置 Redis)。追加 docker-compose.redis.yml:
name: psono-7.5.3-stack
services:
psono-cache:
image: redis:8-alpine
restart: unless-stopped
command: ["redis-server", "--maxmemory", "256mb", "--maxmemory-policy", "allkeys-lru"]
volumes:
- ./redisdata:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
networks:
- psono-net
networks:
psono-net:
external: true
name: psono-753-net
同时在 settings.yaml 追加三行(官方默认用 13 号库,避开 0/1):
CACHE_ENABLE: True
CACHE_REDIS: True
CACHE_REDIS_LOCATION: 'redis://psono-cache:6379/13'
启动并验证缓存生效:
docker compose -f docker-compose.yml -f docker-compose.redis.yml up -d psono-cache
docker compose restart psono-server
实测验证:限流计数键已写入 Redis(Psono 的限流器以 Redis 为后端):
docker compose exec psono-cache redis-cli -n 13 dbsize
docker compose exec psono-cache redis-cli -n 13 keys '*:1:*'
实测回显:
3
b97434da89fe500ee68410af75d4d41c99eb50975e99c9eec064d522601f7845:7.5.3_(Build_5638426c):1:throttle_health_check_10.89.58.1
b97434da89fe500ee68410af75d4d41c99eb50975e99c9eec064d522601f7845:7.5.3_(Build_5638426c):1:throttle_user_10.89.58.1
b97434da89fe500ee68410af75d4d41c99eb50975e99c9eec064d522601f7845:7.5.3_(Build_5638426c):1:throttle_anon_10.89.58.1
重启后健康检查复验仍为 200(db_read/db_sync/time_sync 全 true),缓存接入无副作用。Redis 里的键名结构为「服务端公钥前缀 + 版本构建号 + 限流组 + 客户端 IP」,据此可直接观察各限流组的实际计数。
七、常见问题(实测排障实录)
7.1 健康检查返回 400:time_sync unhealthy
现象:首次部署后健康检查回显如下(HTTP 400,其余两项正常):
{"db_read":{"healthy":true},"db_sync":{"healthy":true},"time_sync":{"healthy":false},"_info":{"ip":"10.89.58.1"}}
HTTP=400
定位:官方安装文档「Installation behind Firewall」章节明示 Psono 依赖对 time.google.com:123(NTP/UDP)的时间同步校验(用于 TOTP、YubiKey、限流与重放保护)。在服务内实测三个 NTP 源连通性:
time.google.com: FAIL TimeoutError timed out
ntp.aliyun.com: OK offset=0.043s server_time=2026-10-24 05:51:51
ntp.ubuntu.com: OK offset=0.303s server_time=2026-10-24 05:51:51
解决方案(二选一):
- settings.yaml 增加可达 NTP 源后重启服务(推荐):
TIME_SERVER: 'ntp.aliyun.com',实测重启后回显{"db_read":{"healthy":true},"db_sync":{"healthy":true},"time_sync":{"healthy":true},...}、HTTP 200。 - 确认服务器时间本身可靠时,官方允许直接关闭该校验:settings.yaml 设
HEALTHCHECK_TIME_SYNC_ENABLED: False。
7.2 单发管理命令报数据库主机解析失败
现象:用 docker run --rm 单发执行 manage.py createuser 时报错(节选):
django.db.utils.OperationalError: failed to resolve host 'psono-db': [Errno -3] Try again
定位:docker run --rm 单发命令默认不在 compose 定义的网络里,解析不了服务名 psono-db。解决方案:一律改用 docker compose exec psono-server python3 ./psono/manage.py … 在栈内执行;确需单发时给 docker run 显式加 --network psono-753-net 并挂载 settings.yaml。
7.3 非交互终端执行官方命令报 TTY 错误
现象:docker run --rm -ti psono/psono-combo:latest python3 ./psono/generateserverkeys.py 在自动化脚本/远程执行中报:
cannot attach stdin to a TTY-enabled container because stdin is not a terminal
解决方案:去掉 -t(改为 -i 或两者都去掉)。这类一次性命令本就不需要交互终端。
7.4 首启后 30 秒内访问报连接被拒
现象:docker compose up -d 后立刻 curl 8153 端口连接失败。定位:组合镜像启动入口先执行数据库迁移再拉起 Web 服务,psono-server 状态为 health: starting。等待约 30–60 秒后复验即 200。验证手段:docker compose ps 观察 STATUS 变为 (healthy) 后再测端点。
八、参考链接
- 官方安装文档(Install Psono CE):https://doc.psono.com/admin/installation/install-psono-ce.html (密钥生成、settings.yaml、启动命令、防火墙白名单,2026-10-24 实查)
- 官方数据库安装文档:https://doc.psono.com/admin/installation/install-postgres-db.html (postgres:18-alpine 形态)
- 官方反代文档:https://doc.psono.com/admin/installation/install-reverse-proxy.html (Nginx TLS + CSP 配置)
- 官方环境变量文档:https://doc.psono.com/admin/other/environment-variables.html (PSONO_* 全清单)
- 官方健康检查文档:https://doc.psono.com/admin/other/healthcheck.html (三项自检语义)
- 本专栏配置篇:见《Psono v7.5.3 配置参数详解》(settings.yaml 全参数逐项解读)
- 本专栏安全篇:见《Psono v7.5.3 安全加固指南》(TLS/限流/审计/密钥治理)
- 同类产品部署对照:《Passbolt 5.16.0 Docker Compose 部署指南》、《Vaultwarden 1.37.4 Docker Compose 部署指南》