PictShare 3.7.5 配置参数详解

梳理 PictShare 3.7.5 全部 40 个配置项的注入机制、语义与默认值,逐项实测验证并给出三套生产配置模板。

PictSharePictShare环境变量自托管PHP2026/10/31

PictShare 3.7.5 配置参数详解

目标:把 PictShare 3.7.5 的配置体系一次讲透——参数如何注入与生效、全部 40 个配置项的语义与默认值、按场景分类的逐项实测验证,以及可直接套用的生产配置模板。已在 Ubuntu 22.04 服务器上对 PictShare 3.7.5(PHP 8.4.27/FrankenPHP)实测通过,全部命令与回显均为实测原文。

一、环境信息

  • 操作系统:Ubuntu 22.04(x86_64,内核 5.15+)
  • 软件版本:PictShare 3.7.5(官方最新稳定版 tag v3.7.5,2026-10-27 发布,查询日期 2026-10-31 无更新)
  • 运行时:PHP 8.4.27 + FrankenPHP(Caddy 内嵌 PHP)、内置 Redis(unix socket)、ffmpeg
  • 主实例:http://192.168.146.128:8131/(按《PictShare 3.7.5 Docker Compose 部署指南》部署,环境变量 URL/TITLE/MAX_UPLOAD_SIZE=100/ADMIN_PASSWORD/LOG_UPLOADER=false/REDIS_CACHING=true)
  • 参数验证实例:http://192.168.146.128:8133/(同版本另起的独立实例,专用于本篇参数逐项验证)
  • 应用目录:/app/public(配置文件 /app/public/src/inc/config.inc.php,数据目录 /app/public/data,日志目录 /app/public/logs)
  • 开源许可:Apache License 2.0

二、前置条件

三、参数查看与修改方式

3.1 配置的生成机制:环境变量 → config.inc.php

PictShare 3.x 的全部配置在每次服务启动时由启动脚本从环境变量生成一份 PHP 配置文件 /app/public/src/inc/config.inc.php(define('KEY', value) 形式)。这决定了两条铁律:

  1. 改配置 = 改环境变量 + 重建服务,手工编辑 config.inc.php 会在下次重启时被覆盖;
  2. 排查生效值 = 读 config.inc.php,它就是当前运行实例的最终事实。

登录服务器查看当前生效配置(实测回显,文件由环境变量 TITLE=PictShare 测试站、ALWAYS_AVIF=true、ALLOWED_DOMAINS=127.0.0.1、SPLIT_DATA_DIR=true、LOG_VIEWS=true、ADMIN_PASSWORD=q1w2e3r4 的验证实例生成):

cat /app/public/src/inc/config.inc.php
<?php
define('URL', 'http://192.168.146.128:8133/');
define('TITLE', 'PictShare 测试站');
define('ALLOWED_SUBNET', '');
define('CONTENTCONTROLLERS', '');
define('MASTER_DELETE_CODE', '');
define('MASTER_DELETE_IP', '');
define('UPLOAD_CODE', '');
define('LOG_UPLOADER', false);
define('MAX_RESIZED_IMAGES',-1);
define('SHOW_ERRORS', false);
define('JPEG_COMPRESSION', 90);
define('PNG_COMPRESSION', 6);
define('ALT_FOLDER', '');
define('S3_BUCKET', '');
define('S3_ACCESS_KEY', '');
define('S3_SECRET_KEY', '');
define('FTP_SERVER', '');
define('FTP_PORT', 21);
define('FTP_USER', '');
define('FTP_PASS', '');
define('FTP_PASSIVEMODE', true);
define('FTP_SSL', false);
define('FTP_BASEDIR', '');
define('ENCRYPTION_KEY', '');
define('FFMPEG_BINARY', '/usr/bin/ffmpeg');
define('ALLOW_BLOATING', true);
define('ALWAYS_WEBP', false);
define('ALWAYS_AVIF', true);
define('ALLOWED_DOMAINS', '127.0.0.1');
define('CORS_ALLOW_ORIGIN', '');
define('SPLIT_DATA_DIR', true);
define('LOG_VIEWS', true);
define('REDIS_CACHING', true);
define('REDIS_SERVER', '/run/redis/redis.sock');
define('REDIS_PORT', 6379);
define('ADMIN_PASSWORD', 'q1w2e3r4');
define('PICTSHARE_VERSION', '3.7.5');
define('HTML_HOSTING_ENABLED', true);
define('HTML_UPLOAD_CODE', '');

这份文件共 38 个 define()。未显式设置的环境变量都会落成上表所示的默认值(空串/false/默认数值),因此上表同时也是一张「默认值实测表」。

另有 2 个环境变量不进 config.inc.php、由启动脚本单独处理:

变量默认值作用
MAX_UPLOAD_SIZE100上传上限(MB),启动时改写 php.ini 的 post_max_size/upload_max_filesize,并把 PHP memory_limit 抬到「上限 + 30MB」
SKIP_FILEPERMISSIONSfalse设为 true 时跳过启动时对 tmp 目录的权限整理

3.2 修改方式与生效验证

以把上传上限从默认 100MB 改为 50MB 为例(验证实例以 MAX_UPLOAD_SIZE=50 注入后启动,服务启动日志实测回显):

[i] Setting uploadsize to 50M
[i] Also changing memory limit of PHP to 80M
 [+] Creating config

日志三行的含义:

  • Setting uploadsize to 50M:php.ini 的 post_max_size/upload_max_filesize 已改写为 50M;
  • Also changing memory limit of PHP to 80M:memory_limit = 上限 + 30MB(50+30=80),解码大图需要的内存比文件本身大,这是官方预留的余量;
  • Creating config:config.inc.php 已按环境变量重新生成。

⚠️ 注意:MAX_UPLOAD_SIZE 的改写发生在每次启动时,所以后续调大调小都会即时生效;但若部署编排里同时挂载了自定义 php.ini,以启动脚本改写后的值为准。

四、参数总览

按功能域分组的全量参数速查表(默认值取自 3.1 生效文件与启动脚本,均为 3.7.5 实测值):

分类参数类型默认值一句话作用
站点基础URLstring空上传结果 JSON 里外链的前缀,必填且以斜杠结尾
站点基础TITLEstringPictShare内容页(视频/文本/相册/音频页)的 <title> 与 og:site_name
站点基础MAX_UPLOAD_SIZEint100上传上限 MB,联动改写 php.ini 与 memory_limit
站点基础ADMIN_PASSWORDstring空/admin 管理端口令,空 = 管理端整体关闭
访问控制UPLOAD_CODEstring空全局上传口令,接口需带 uploadcode 字段
访问控制ALLOWED_SUBNETCIDR空限制上传与 /admin 的来源 IP 网段
访问控制ALLOWED_DOMAINSCSV空允许访问的 Host 域名白名单(配合 SPLIT_DATA_DIR 做多域名数据分片)
访问控制MASTER_DELETE_CODEstring空万能删除码,可删任何文件
访问控制MASTER_DELETE_IPIP空该来源 IP 无需删除码即可删除
存储后端SPLIT_DATA_DIRboolfalse按域名把数据分片到 data/<域名>/ 子目录
存储后端ALT_FOLDERstring空双写目录(NFS 等共享存储),本地未命中时回源
存储后端S3_BUCKET/S3_ACCESS_KEY/S3_SECRET_KEY/S3_ENDPOINT/S3_REGIONstring空S3 兼容对象存储(MinIO/Garage/AWS)后端
存储后端FTP_SERVER/FTP_PORT/FTP_USER/FTP_PASS/FTP_BASEDIR/FTP_SSL/FTP_PASSIVEMODEstring/bool空/21/…/true/falseFTP/FTPS 外部存储后端
存储后端ENCRYPTION_KEYbase64空外部存储上文件的 XChaCha20 加密密钥
图像格式JPEG_COMPRESSIONint90JPEG 重编码质量(0-100)
图像格式PNG_COMPRESSIONint6PNG 压缩级别(0-9,只影响体积与速度不影响画质)
图像格式ALWAYS_WEBPboolfalse客户端 Accept 支持时,JPG 一律以 WebP 伺服
图像格式ALWAYS_AVIFboolfalse客户端 Accept 支持时,进一步以 AVIF 伺服
图像格式ALLOW_BLOATINGbooltrue允许放大变换(放大到超过原尺寸)
内容控制器CONTENTCONTROLLERSCSV空内容控制器白名单,空 = 全部启用
内容控制器HTML_HOSTING_ENABLEDboolfalseHTML 页托管总开关(高危功能)
内容控制器HTML_UPLOAD_CODEstring空HTML 托管专用口令,与 UPLOAD_CODE 相互独立
日志缓存LOG_UPLOADERboolfalse上传者 IP 记入 data/uploads.csv
日志缓存LOG_VIEWSboolfalse访问/上传事件写入 logs/app.log 与 logs/views.log
日志缓存REDIS_CACHINGbooltrueRedis URL→文件映射缓存,false 显著变慢
日志缓存REDIS_SERVERstring/run/redis/redis.sockRedis 地址(默认本机 unix socket)
日志缓存REDIS_PORTint6379Redis TCP 端口(socket 模式下不用)
其他CORS_ALLOW_ORIGINstring空全响应附加 Access-Control-Allow-Origin 头
其他FFMPEG_BINARYstring/usr/bin/ffmpegffmpeg 可执行文件路径
其他MAX_RESIZED_IMAGESint-1每文件变换产物数量上限(-1 不限,官方标注未实现)
其他SHOW_ERRORSboolfalse页面直接显示 PHP 错误(排障用)
其他PICTSHARE_VERSIONstringgit版本号标识,官方镜像注入 3.7.5

💡 技术拓展:ALWAYS_WEBP/ALWAYS_AVIF 涉及「现代图片格式选型」。三大格式横向对比——

格式压缩率(同等画质)浏览器支持编码耗时
JPEG基准100% 全兼容最快
WebP比 JPEG 小 25-35%全主流浏览器(2020 起)中等
AVIF比 WebP 再小 20-50%Chrome/Edge/Firefox/Safari 16+最慢

PictShare 的伺服策略是协商式:客户端 Accept 头带 image/webp 才给 WebP,带 image/avif 才给 AVIF,老客户端永远拿到原格式。本方案实测环境两个开关都打开,由客户端能力自动降级。

关键解读:表里「必填」的只有 URL——它不参与存储逻辑,只决定上传 JSON 返回的 url/delete_url 前缀;其余参数空着即可跑通默认行为。

五、核心参数分类详解

5.1 URL 与 TITLE:站点对外身份

URL 决定所有上传结果 JSON 里的外链前缀,必须以斜杠结尾;TITLE 决定内容页的浏览器标题(首页是固定模板,不受 TITLE 影响)。实测:验证实例设 TITLE=PictShare 测试站,上传一个文本片段后访问其内容页:

curl -s -F "file=@notes.txt" http://192.168.146.128:8133/api/upload
{
    "status": "ok",
    "hash": "0ifmh3.txt",
    "filetype": "text\/plain",
    "url": "http:\/\/192.168.146.128:8133\/0ifmh3.txt",
    "delete_code": "bd5v76fue4k7in9gpl16c2sc9o7k4qmk",
    "delete_url": "http:\/\/192.168.146.128:8133\/delete_bd5v76fue4k7in9gpl16c2sc9o7k4qmk\/0ifmh3.txt"
}

访问内容页看 <title>(实测回显):

curl -s http://192.168.146.128:8133/0ifmh3.txt | grep -oE '<title>[^<]*</title>'
<title>PictShare 测试站</title>

TITLE 生效于文本仓、视频播放器、相册、音频播放器等所有内容页。外链前缀验证:上例 JSON 里 url 与 delete_url 均以 URL 环境变量的值开头;把 URL 改成错误值(漏尾斜杠/写错域名)不会影响已存文件,但新上传返回的链接会指向错误地址。

5.2 UPLOAD_CODE 与 ALLOWED_SUBNET:谁能上传

两个参数是并联的两道闸(源码逻辑:先查 ALLOWED_SUBNET,命中拒绝即挡;再查 UPLOAD_CODE),任一命中即放行/拒绝。验证实例曾以 UPLOAD_CODE=s3cret 实测三态(assets-test.png 上传):

不带上传码(实测回显):

curl -s -F "file=@assets-test.png" http://192.168.146.128:8133/api/upload
{
    "status": "err",
    "reason": "Incorrect upload code specified - Access denied"
}

带错误上传码(实测回显):

curl -s -F "file=@assets-test.png" -F "uploadcode=wrong" http://192.168.146.128:8133/api/upload
{
    "status": "err",
    "reason": "Incorrect upload code specified - Access denied"
}

带正确上传码(实测回显):

curl -s -F "file=@assets-test.png" -F "uploadcode=s3cret" http://192.168.146.128:8133/api/upload
{
    "status": "ok",
    "hash": "g8ir60.png",
    "filetype": "image\/png",
    "url": "http:\/\/192.168.146.128:8133\/g8ir60.png",
    "delete_code": "3hsz0q8e0ewwgk2cpipmtz7k3ifl3x85",
    "delete_url": "http:\/\/192.168.146.128:8133\/delete_3hsz0q8e0ewwgk2cpipmtz7k3ifl3x85\/g8ir60.png"
}

ALLOWED_SUBNET 走 CIDR 匹配:验证实例以 ALLOWED_SUBNET=172.17.0.0/16 启动后,网段内来源可正常上传,且生效值如实用 define('ALLOWED_SUBNET', '172.17.0.0/16') 写进 config.inc.php(cat 实测)。注意它同时约束 /admin 管理端——网段外的 IP 即使持有口令也进不了管理页。

⚠️ 注意:UPLOAD_CODE 只管「上传」,不影响读取——外链、变换 URL、/api/info 对所有人生效。要做纯内网图床,用 ALLOWED_SUBNET 把服务面整体收进内网更彻底。

5.3 ADMIN_PASSWORD:管理端口令

ADMIN_PASSWORD 为空时 /admin 路由整体关闭;设置后 /admin?password=<口令> 登录(session 保持)。验证实例以 ADMIN_PASSWORD=q1w2e3r4 实测三态(本文按示例账号规范使用测试口令,生产请换强口令):

无口令访问(实测回显):

curl -s http://192.168.146.128:8133/admin | grep -oE 'type="password"' | head -1
type="password"

错误口令(实测回显):

curl -s 'http://192.168.146.128:8133/admin?password=wrongpass' | grep -oE 'type="password"|Stats|logout' | head -1
type="password"

正确口令(实测回显):

curl -s 'http://192.168.146.128:8133/admin?password=q1w2e3r4' | grep -oE 'Stats|logout' | head -2
logout
Stats

正确口令后进入管理页(Stats 统计、Reports 处理、/admin/stats/delete/<hash> 可在后台删文件、/admin/rebuild-meta 可重建元数据索引)。

5.4 MASTER_DELETE_CODE 与 MASTER_DELETE_IP:兜底删除

MASTER_DELETE_CODE 设置后可作为任何文件的删除码使用。验证实例以 MASTER_DELETE_CODE=topsecret 实测(上传 g8ir60.png 后):用 delete_topsecret/g8ir60.png 形态删除返回 "status": "ok", "hash": "g8ir60.png",随后 /api/info/g8ir60.png 返回 "reason": "Hash not found"(均实测)。MASTER_DELETE_IP 则让指定来源 IP 无需任何删除码即可删除,两个参数都适合运维兜底场景,但务必只用其一且值够长。

5.5 存储后端三选一:本地 / S3 兼容 / FTP

默认只有本地存储(data/ 目录)。外部存储是「双写 + 回源」模型:上传时同时写到本地与外部;读取时本地未命中自动到外部取回并伺服。

💡 技术拓展:PictShare 支持三类外部存储后端,横向对比——

后端参数组特点适用场景
ALT_FOLDER 双写ALT_FOLDER本地路径/NFS 挂载,纯目录级复制两台实例共享同一份数据(官方 SCALING.md 推荐形态)
S3 兼容S5 组五个 S3_* 参数对接 MinIO/Garage/AWS,容量弹性最好多实例横向扩展、异地容灾
FTP/FTPSFTP_* 组七个参数老式协议,慢且默认明文配合 ENCRYPTION_KEY 才可接受的传统 NAS

本方案实测环境用默认本地存储;多实例扩展场景官方文档推荐 ALT_FOLDER(NFS)或 S3 兼容后端。

ENCRYPTION_KEY(base64)对外部存储上的文件做 XChaCha20 加解密,上传/下载自动进行,本地明文不受影响;密钥丢失 = 外部存储数据不可解。S3 组五个参数与 FTP 组七个参数均需要真实外部服务才能验证,本文按官方 CONFIG.md 语义收录、默认值以 3.1 生效文件为准,未做本地实测的部分已在表格注明。

5.6 SPLIT_DATA_DIR 与 ALLOWED_DOMAINS:多域名数据分片

两者配合实现「一台实例服务多个域名、各域名数据隔离」:ALLOWED_DOMAINS 是 Host 白名单(CSV),SPLIT_DATA_DIR=true 时每个白名单域名的上传落到 data/<域名>/ 子目录。验证实例以 ALLOWED_DOMAINS=127.0.0.1 + SPLIT_DATA_DIR=true 启动,上传后查看数据目录(实测回显):

curl -s -F "file=@assets-test.png" http://127.0.0.1:8133/api/upload > /dev/null
ls /app/public/data /app/public/data/127.0.0.1
/app/public/data:
127.0.0.1

/app/public/data/127.0.0.1:
fy09ct.png
naughty.csv
sha1.csv

上传内容确实落到了 data/127.0.0.1/ 分片目录。白名单外的 Host 访问(实测回显):

curl -s -H 'Host: evil.example.com' http://192.168.146.128:8133/api/info/fy09ct.png
{
    "status": "err",
    "reason": "Hash not found"
}

非白名单域名解析不到分片目录里的文件,等效隔离。注意:单独用 ALLOWED_DOMAINS 不开 SPLIT_DATA_DIR 也合法,此时只是收窄可访问域名,数据仍集中在 data/。

5.7 CONTENTCONTROLLERS 与 HTML 托管开关:内容类型面

CONTENTCONTROLLERS 是内容控制器白名单(空 = 全部启用)。验证实例以 CONTENTCONTROLLERS=IMAGE,VIDEO 启动后,文本上传被拒(实测回显):

curl -s -F "file=@notes.txt" http://192.168.146.128:8133/api/upload
{
    "status": "err",
    "reason": "Unsupported mime type: text\/plain"
}

可用值:IMAGE、SVG、TEXT、VIDEO、URL、HTML(HTML 还需 HTML_HOSTING_ENABLED,另有 MARKDOWN、IDENTICON、PLACEHOLDER、AUDIO 控制器随主开关启用)。生产环境若只用图床,收缩白名单能直接砍掉文本仓/URL 抓取等滥用面。

HTML 托管是高危功能(在他人的浏览器里于你的域名下执行任意 JS),双开关设计:HTML_HOSTING_ENABLED=true + 独立的 HTML_UPLOAD_CODE,两者缺一即整体禁用。只开开关不设码时每次启动都有显式告警(验证实例启动日志实测回显):

[!] HTML_HOSTING_ENABLED is true but HTML_UPLOAD_CODE is not set - HTML hosting stays DISABLED until you set a code.

5.8 ALWAYS_WEBP 与 ALWAYS_AVIF:协商式格式伺服

两开关都依赖客户端 Accept 头。验证实例以 ALWAYS_AVIF=true 启动,上传 JPEG(实测回显 hash: gd1jmt.jpg),带 AVIF 能力请求:

curl -s -o /dev/null -D - http://192.168.146.128:8133/gd1jmt.jpg -H 'Accept: image/avif,image/webp,image/*' | grep -iE '^HTTP|content-type'
HTTP/1.1 200 OK
Content-Type: image/avif

不带 AVIF 能力的普通请求(实测回显):

curl -s -o /dev/null -D - http://192.168.146.128:8133/gd1jmt.jpg | grep -iE '^HTTP|content-type'
HTTP/1.1 200 OK
Content-Type: image/jpeg

ALWAYS_WEBP=true 行为同理(官方 CONFIG.md 与 3.7.5 实测一致:带 image/webp Accept 的客户端拿到 image/webp,其余拿原格式)。两个开关只影响 JPG 的伺服格式,PNG/GIF 原样伺服;想强制转码某个 URL 用路径变换 /webp/(见《PictShare 3.7.5 URL 参数与 HTTP API 详解》)。

5.9 JPEG_COMPRESSION / PNG_COMPRESSION:重编码质量

这两个值只作用于需要重新编码的场景(旋转/滤镜/缩放产物、URL 强转格式),原文件本身永不被重编码。默认 JPEG 90、PNG 6(GD 库语义:PNG 级别只影响体积与编解码速度,不影响画质;WEBP_COMPRESSION 在官方文档有记载但不在启动脚本生成清单里,Compose 部署形态下实际固定为源码默认 80,改环境变量不生效)。验证实例保持默认值上传 800×600 PNG 并做灰度变换,产物 200 正常返回(实测回显 HTTP/1.1 200 OK, Content-Type: image/png),确认默认管线可用。

5.10 LOG_UPLOADER 与 LOG_VIEWS:两级日志开关

LOG_UPLOADER=true 把上传者 IP 记入 data/uploads.csv(验证实例实测回显,两行上传记录):

1793408155;;g8ir60.png;172.17.0.1
1793408170;;qoab1d.jpg;172.17.0.1

LOG_VIEWS=true 打开应用日志:上传/缓存事件进 logs/app.log,访问事件进 logs/views.log(验证实例实测回显):

31.10.26 01:16	[http://192.168.146.128:8133/] | 172.17.0.1 uploaded fy09ct.png (image/png)
31.10.26 01:16	[http://192.168.146.128:8133/] | Caching URL 	gd1jmt.jpg	hash: gd1jmt.jpg	to content controller: ImageController
31.10.26 01:16	[http://192.168.146.128:8133/] | 172.17.0.1	viewed	gd1jmt.jpg	It was locally found. Agent:	curl/8.5.0	ref:	
31.10.26 01:16	[http://192.168.146.128:8133/] | 172.17.0.1	viewed	gd1jmt.jpg	From cache. Agent:	curl/8.5.0	ref:	

views.log 每条记录含时间、站点、来源 IP、hash、命中方式(本地/缓存)、User-Agent 与 Referer。官方标注 LOG_VIEWS 资源开销较大,建议仅排障期临时开启;隐私敏感部署保持 LOG_UPLOADER=false(默认),不开上传者 IP 留痕。

5.11 REDIS_CACHING / REDIS_SERVER / REDIS_PORT:缓存链路

Redis 缓存的是 URL→文件映射(cache:byurl:*)、访问计数(served:*、lastaccessed:*)等热键,默认以 unix socket /run/redis/redis.sock 连接本机实例,REDIS_SERVER/REDIS_PORT 用于把缓存指向外部 Redis(ffmpeg worker 队列也依赖它)。REDIS_CACHING=false 可整体关闭但官方明言「显著变慢」——每个请求都要落盘扫目录。主实例以 REDIS_CACHING=true 部署,启动日志出现 [i] Redis steps + [+] Configuring Redis save intervals 即为正常(见《PictShare 3.7.5 Docker Compose 部署指南》4.3 节日志判读)。

5.12 CORS_ALLOW_ORIGIN:跨域外链

设置后每个响应都附加 Access-Control-Allow-Origin 头。验证实例以 CORS_ALLOW_ORIGIN=https://example.com 启动实测,上传响应与文件 GET 响应均带头(实测回显):

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://example.com

需要把外链嵌进前端 <canvas>/WebGL 纹理(跨域读取像素)时必开;值建议精确到你的前端域名而非 *,避免为任意站点放开读取权。

5.13 其余单项:FFMPEG_BINARY / MAX_RESIZED_IMAGES / SHOW_ERRORS / PICTSHARE_VERSION / ALLOW_BLOATING

  • FFMPEG_BINARY:ffmpeg 路径,默认 /usr/bin/ffmpeg;GIF→MP4、视频缩放全靠它,路径错则视频变换全部失效。
  • MAX_RESIZED_IMAGES:官方 CONFIG.md 标注 NOT IMPLEMENTED,代码默认 -1(不限),留空即可。
  • SHOW_ERRORS=true:页面直接输出 PHP 错误,排障临时开启,生产保持 false。
  • PICTSHARE_VERSION:版本标识,官方镜像注入 3.7.5,管理页与接口回显引用,无需手工设置。
  • ALLOW_BLOATING=true(默认):允许「放大」类变换(如把 300×200 拉到 1000×800 的 forcesize);关掉后超原尺寸的放大请求被拒,可防止恶意生成超大图耗 CPU。

六、生产配置模板

6.1 小团队内网图床(2GB 内存 / 普通磁盘 / 10-50 人)

environment:
  - URL=http://192.168.146.128:8131/
  - TITLE=Team CDN
  - MAX_UPLOAD_SIZE=100
  - ADMIN_PASSWORD=q1w2e3r4
  - LOG_UPLOADER=false
  - REDIS_CACHING=true

默认行为 + 管理口令,内网可信环境不开上传口令,保持拖拽即传的体验。

6.2 公网开放 + 防滥用(4GB 内存 / SSD / 对外服务)

environment:
  - URL=https://img.example.com/
  - TITLE=Example Images
  - MAX_UPLOAD_SIZE=50
  - UPLOAD_CODE=team-upload-2026
  - MASTER_DELETE_CODE=change-me-to-a-long-random-string
  - ALWAYS_WEBP=true
  - ALWAYS_AVIF=true
  - CORS_ALLOW_ORIGIN=https://www.example.com
  - ADMIN_PASSWORD=q1w2e3r4
  - LOG_VIEWS=false

上传收口令、留万能删除码、自动协商 WebP/AVIF 省带宽、CORS 只对自家前端放开;公网实例建议再前置 Nginx/Caddy 限速。

6.3 多域名分片 + S3 外部存储(8GB 内存 / 对象存储 / 多实例扩展)

environment:
  - URL=https://img.example.com/
  - SPLIT_DATA_DIR=true
  - ALLOWED_DOMAINS=img.example.com,cdn.example.com
  - S3_BUCKET=${S3_BUCKET}
  - S3_ACCESS_KEY=${S3_ACCESS_KEY}
  - S3_SECRET_KEY=${S3_SECRET_KEY}
  - S3_ENDPOINT=https://s3.internal:9000
  - S3_REGION=us-east-1
  - ENCRYPTION_KEY=${ENCRYPTION_KEY}
  - ADMIN_PASSWORD=q1w2e3r4

S3 凭据与加密密钥属系统级敏感值,用 ${VAR} 占位,启动前在部署环境导出(export S3_SECRET_KEY=... 或写入部署编排的 secrets 注入);ENCRYPTION_KEY 用 openssl rand -base64 32 生成,生成后妥善保存——密钥丢失则外部存储上的历史数据无法解密。

三套模板的共同点:都显式设置 URL 与 ADMIN_PASSWORD;差异在访问面(内网全开 → 口令收口 → 域名白名单分片)与存储层(本地 → 本地+S3 双写)。按「谁会上传、数据存哪、是否多域名」三问对号入座。

七、常见问题(FAQ)

Q1:改了环境变量为什么没生效? config.inc.php 在每次启动时由环境变量重新生成,只改文件不重启必被覆盖;改完环境变量后重建服务,并用 cat /app/public/src/inc/config.inc.php 复核生效值(见 3.1)。

Q2:HTML_HOSTING_ENABLED=true 了,HTML 页还是传不上? 还缺 HTML_UPLOAD_CODE(两者是独立的双开关,缺一即禁用),且请求要带 htmluploadcode 字段;若同时收缩过 CONTENTCONTROLLERS,白名单里还要加 HTML。启动日志的 [!] 告警行(见 5.7)就是给这种情况准备的。

Q3:上传大文件报 413 或半途断开? 确认 MAX_UPLOAD_SIZE 是在启动前就注入的(它联动改写 php.ini 的 post_max_size/upload_max_filesize 并抬高 memory_limit,见 3.2 的启动日志三行);若有反向代理,其 client_max_body_size 也要同步放大。

Q4:设置了 ALLOWED_DOMAINS 之后接口报 Hash not found? 请求的 Host 不在白名单里。ALLOWED_DOMAINS 按 Host 头精确匹配(不带端口),分片数据目录按域名命名(见 5.6);用 curl -H 'Host: 你的域名' 自测。

Q5:文件删除后外链还能打开? 分两种情况(3.7.5 实测):删除前从未被访问过的文件,URL 立即 404;删除前被访问过(Redis 已缓存 URL 映射)的文件,URL 会继续返回 200 但内容为空壳,直到缓存过期。监控判据一律用 GET /api/info/<hash>(返回 Hash not found 即已删除),不要用外链状态码。完整删除流程实测见《PictShare 3.7.5 URL 参数与 HTTP API 详解》。

Q6:WEBP_COMPRESSION 设了没用? 它不在启动脚本的环境变量生成清单里(对比 3.1 的 38 个 define),Compose 部署形态下实际固定为源码默认 80;需要调 WebP 质量只能改源码或等官方把它纳入生成清单。

八、参考链接

  1. 官方配置手册:https://github.com/HaschekSolutions/PictShare/blob/master/rtfm/CONFIG.md(v3.7.5,查询日期 2026-10-31)
  2. 官方加密说明:https://github.com/HaschekSolutions/PictShare/blob/master/rtfm/ENCRYPTION.md
  3. 官方扩展部署说明:https://github.com/HaschekSolutions/PictShare/blob/master/rtfm/SCALING.md
  4. 官方仓库:https://github.com/HaschekSolutions/PictShare(最新稳定版 v3.7.5,2026-10-27 发布,查询日期 2026-10-31)
  5. 本专栏系列:《PictShare 介绍与选型指南》、《PictShare 3.7.5 Docker Compose 部署指南》、《PictShare 3.7.5 URL 参数与 HTTP API 详解》。