PictShare 介绍与选型指南

说清 PictShare 的定位、架构与功能边界,并与同类自托管图床/文件分享工具量化对比,帮助判断是否值得引入。

PictSharePictShare文件分享自托管PHP2026/10/31

PictShare 介绍与选型指南

目标:说清 PictShare 是什么、解决什么问题、架构与功能边界如何,以及与同类自托管图床/文件分享工具的量化对比,帮助读者判断是否值得引入。基于官方仓库 HaschekSolutions/PictShare 与官方镜像实查(版本 3.7.5,查询日期 2026-10-30),并在 Ubuntu 22.04 服务器上以官方 Docker 镜像完成部署与功能实测(部署过程见《PictShare 3.7.5 Docker Compose 部署指南》https://www.quzuo.net/document/ILUkOrJVYiZD )。

一、环境信息

  • 操作系统:Ubuntu 22.04(x86_64,内核 5.15+)
  • 软件版本:PictShare 3.7.5(官方最新稳定版 tag v3.7.5,镜像 3.7.5 于 2026-10-27 推送,来源官方仓库 tags 与 Docker Hub 实查,查询日期 2026-10-30)
  • 社区活跃度:GitHub 星数 951、复刻数 137(shields.io 实查,查询日期 2026-10-30)
  • 开源许可:Apache License 2.0
  • 技术栈:PHP 8.4 + FrankenPHP(Caddy 内嵌 PHP)、内置 Redis(URL→文件映射缓存)、ffmpeg(音视频转码)
  • 官方镜像:hascheksolutions/pictshare(Docker Hub)与 ghcr.io/hascheksolutions/pictshare(GHCR)
  • 实测环境:单机 Docker Compose 部署,Web 端口 8131,自定义 bridge 子网 10.89.59.0/24

二、软件概述

2.1 项目定位

PictShare 是 Haschek Solutions 开源的自托管多媒体托管服务(self-hosted media hosting),口号是「Host your own images, gifs, mp4s, text bins and stay in control」。它把图片、GIF 动图、MP4 视频、音频、文本片段(pastebin)统一托管在自己的域名下,核心卖点是三点:

  1. 纯文件存储、零数据库:所有上传内容以内容寻址(SHA1 摘要)方式落盘为目录与文件,元数据存每个文件旁的 meta.json,部署与备份只需要拷目录;
  2. URL 即变换:缩放、旋转、滤镜、格式转换全部通过改 URL 路径实现(如 /300x200/hash.png),无需预生成多种尺寸;
  3. 隐私友好:上传时自动清除 EXIF(GPS 位置、相机型号等),重复文件自动去重不占额外空间。

项目自 2013 年前后起步(v1/v2 以传统 PHP+Nginx 形态运行),2025 年起发布的 v3 从零重构:API 全面转向 RESTful 风格、镜像底座换成 FrankenPHP(Caddy 内嵌 PHP,无需 Nginx+php-fpm 双进程)、内置 Redis 缓存、新增相册/文本仓/URL 缩短/MCP 端点等能力。官方明确提示 v3 与旧版不完全兼容(配置项 TITLE、UPLOAD_FORM_LOCATION、ALLOW_BLOATING 曾被移除后又部分回归,文件名必须位于 URL 末段等破坏性变更)。

2.2 解决的核心痛点

  • 团队/个人需要把截图、录屏、动图快速变成可外链 URL,又不想把数据交给第三方图床(Imgur 等);
  • 论坛、Wiki、IM 中贴图需要稳定的直链与按需缩略图,而不想为每种尺寸各传一份;
  • 手机照片直传后担心 EXIF 泄露位置信息;
  • 需要一次性、可删除、可审计的临时文件分享出口。

💡 技术拓展:自托管「图床/文件分享」类工具按内容生命周期可分三类——① 永久图床(Chevereto、PictShare、Zipline):文件长期保留,靠管理端与删除码治理;② 一次性/阅后即焚(Jirafeau、goploader、0x0):下载一次或到期自动销毁,适合敏感文件;③ 对象存储直传(MinIO+预签名 URL、S3):无 UI、纯 API,适合程序集成。PictShare 属第一类并带部分第二类特征(每个文件有独立删除码,可随时销毁),适合作为团队的常驻外链服务。

三、核心架构

3.1 单容器多组件架构

PictShare 3.x 官方镜像基于 dunglas/frankenphp:php8.4-alpine 构建,一个容器内集成四个组件:

组件角色说明
FrankenPHP/CaddyWeb 服务器 + PHP 运行时Caddy 直接内嵌 PHP 解释器(php_server),监听 80 端口,无 Nginx+php-fpm 两段式
PHP 8.4 应用业务逻辑内容控制器(按 MIME 分流)+ 存储控制器(按位置分流)双插件体系
RedisURL→文件映射缓存容器内以 unix socket /run/redis/redis.sock 运行,缓存 cache:byurl:*、lastaccessed:*、served:* 等键,关掉会显著变慢
ffmpeg音视频转码GIF→MP4 转码、MP4 缩放、预览帧生成(实测产物 h264 编码)

配置在容器启动时由 /etc/start.sh 从环境变量生成 src/inc/config.inc.php(define('KEY', value) 形式),改配置即改环境变量后重启容器,无独立配置文件需要维护(参数全表见《PictShare 3.7.5 配置参数详解》https://www.quzuo.net/document/K2LlXSHlRiG6 )。

3.2 内容寻址存储模型

上传文件按「哈希目录」落盘,实测 data/ 目录结构:

data/
├── mrokk1.png/                     # 一个上传文件一个目录(目录名=对外 hash)
│   ├── mrokk1.png                  # 原始文件
│   ├── 9d4e826c..._mrokk1.png      # 变换产物(md5 前缀_原名,如缩放/滤镜版本)
│   └── meta.json                   # 元数据:mime、大小、sha1、上传时间、IP、删除码
├── sha1.csv                        # sha1 → hash 映射,用于去重判断
└── naughty.csv                     # 已删除文件黑名单(v3.7.5 实测为空,见 3.3 限制)

特点(均实测验证):

  • 去重:同一文件重复上传返回相同 hash 与 "duplicate": true,服务器只存一份(依赖 sha1.csv 判断);
  • 变换即新文件:/300x200/hash.png 的结果以 300_hash.png 形态缓存在原 hash 目录下,再次访问直接命中;
  • 无数据库:备份 = 拷贝 data/ 目录,迁移 = 拷贝 + 改 URL 环境变量。

3.3 内容控制器与存储控制器

  • 内容控制器(按 MIME 决定「怎么处理」):IMAGE、SVG、TEXT、VIDEO、URL、HTML(危险,默认关)、MARKDOWN、IDENTICON(字符串生成识别图)、PLACEHOLDER(按尺寸生成占位图)、AUDIO。可用 CONTENTCONTROLLERS 白名单收缩(实测设置 IMAGE,VIDEO 后文本上传被拒)。
  • 存储控制器(按位置决定「存哪里」):本地 + 可选 ALT_FOLDER(NFS 双写)、S3 兼容(MinIO/Garage/AWS)、FTP/FTPS,外部存储可配 ENCRYPTION_KEY 做 XChaCha20 加密;本地未命中时自动到外部存储回源取回并伺服。
  • 维护 CLI:镜像内置 tools/ 下 6 个 PHP CLI 脚本(cron.php 的 uploadqueue/flushviews 子命令、ffmpeg_worker.php 转码队列等),供定时任务与排障使用。

3.4 已知限制(v3.7.5 实测)

  • README 宣称的 Markdown 渲染:实测 .md 文件按 text/plain 入库走文本仓(<pre><code> 展示),未触发独立 Markdown 渲染管线;
  • 删除文件不写 naughty.csv 黑名单(源码 deleteHash 内有 @todo: add hash to deleted list),删除后同内容重传会得到新 hash,不会被拦截;
  • 已删除文件的 URL 访问结果分两种(实测):删除前从未被访问过的文件 URL 立即 404;删除前被访问过(Redis 已缓存 URL 映射)的文件 URL 继续返回 200 但内容为空壳(1 字节空 body),做监控探测时判据用 GET /api/info/<hash>(返回 Hash not found 即已删除);
  • URL 抓取上传(/api/upload?url=)带 SSRF 防护:目标为私网 IP 时直接拒绝(实测返回 Private IP range);
  • 无多用户/账号体系:没有登录与个人空间,治理靠 UPLOAD_CODE 上传口令、删除码与管理端(/admin,ADMIN_PASSWORD 控制)。

四、功能特性

以下特性均在 3.7.5 实测环境中逐项验证(完整命令与回显见《PictShare 3.7.5 URL 参数与 HTTP API 详解》https://www.quzuo.net/document/hepbPtXpdr8g ):

功能说明实测结果
多格式上传JPG/PNG/WebP/GIF/MP4/MP3/文本等PNG/JPG/GIF/MP4 上传均返回 JSON(hash/url/delete_code)
URL 即缩放/300x200/hash.png800×600 原图缩放为 300×225(等比缩放,取宽定高)
URL 即旋转`/leftright
图像滤镜gray/sepia/pixelate/blur 等 30+gray、pixelate_10 返回 200 且体积变化
格式转换/webp/hash.jpg、JPG/PNG→WebP返回 WEBP (800,600)
GIF→MP4/mp4/hash.gifffmpeg 转码 h264,播放器页 + /raw 直流
视频缩放/320x180/hash.mp4产物 320×180 h264,poster 预览帧 JPEG 320×180
文本仓任意文本上传为 .txt直链返回渲染页,/hash.txt/raw 取原文
EXIF 清除上传时剥离元数据官方特性,phone 照片 GPS/机型被清
去重SHA1 内容寻址重复上传返回 "duplicate": true
相册多 hash 组合成不可变画廊 URLPOST /api/album 返回 058zu99c.album
删除码每文件独立 32 位删除码错误码拒绝 Invalid delete code,正确码删除成功
上传口令UPLOAD_CODE 全局上传口令无码/错码返回 Access denied,对码成功
私网白名单ALLOWED_SUBNET CIDR 限制上传与 admin生效值实测写回 config.inc.php
管理端/admin 统计与日志页ADMIN_PASSWORD 认证后显示 Stats 页
identicon/占位图/identicon/字符串、/placeholder/555x250/...返回 SVG 与 JPEG (555,250)
MCP 端点POST /mcp 供 LLM 代理调用initialize 握手返回 serverInfo PictShare 1.0.0

五、快速开始(最小可用示例)

5.1 一行启动

docker run -d -p 8080:80 -e "URL=http://<服务器IP>:8080/" hascheksolutions/pictshare:3.7.5

浏览器打开 http://<服务器IP>:8080/ 即是拖拽上传页。URL 必填且以斜杠结尾,它决定上传结果 JSON 里返回的外链前缀。

5.2 命令行上传与外链访问(实测回显)

curl -s -F "file=@test.png" http://127.0.0.1:8080/api/upload
{
    "status": "ok",
    "hash": "mrokk1.png",
    "filetype": "image\/png",
    "url": "http:\/\/192.168.146.128:8131\/mrokk1.png",
    "delete_code": "pj6q3f3i9awmp6kx7hyjt2y5idjnzhda",
    "delete_url": "http:\/\/192.168.146.128:8131\/delete_pj6q3f3i9awmp6kx7hyjt2y5idjnzhda\/mrokk1.png"
}

拿到 url 后即可外链引用;在域名后拼变换参数得到衍生版本:

curl -sI http://127.0.0.1:8131/300x200/mrokk1.png | grep -iE 'HTTP|content-type'
HTTP/1.1 200 OK
Content-Type: image/png

六、适用场景与限制

6.1 适合的场景

  1. 团队内网图床/截图外链:配合截图工具与 curl 别名,拖拽或命令行即得外链,EXIF 自动清除;
  2. 内容站点配图 CDN 前置:URL 即缩放/转 WebP,前端按需引用不同尺寸,省去预裁剪流水线;
  3. 临时素材与文本分享:文本仓 + 独立删除码,分享完即可销毁;
  4. LLM 代理集成:内置 MCP 端点,Claude Code 等 Agent 可直接 upload_from_url/get_file_info/create_album。

6.2 不适合的场景

  1. 需要多用户注册、空间配额、相册权限管理的「社区图床」(选 Chevereto);
  2. 强合规的一次性机密文件交换(选 Jirafeau/goploader,阅后即焚语义更明确);
  3. 海量对象存储场景直接当存储层用(PictShare 定位是伺服层,外部存储仅作回源/双写)。

七、同类选型对比

维度PictShare 3.7.5CheveretoJirafeau 4.7.2goploader 1.0.2Zipline
语言/运行时PHP 8.4 + FrankenPHPPHP + MariaDBPHP(无数据库)Go(服务端+客户端)Node.js
存储纯文件(可选 S3/FTP/NFS 双写+加密)文件 + 数据库纯文件纯文件数据库 + 文件/S3
视频托管/转码✅ MP4 缩放、GIF→MP4(ffmpeg)✅(商业版更强)❌ 仅文件托管❌✅
URL 即变换(缩放/滤镜/转码)✅ 核心特色,30+ 滤镜❌ 需预生成❌❌部分
去重✅ SHA1 自动去重❌❌❌❌
EXIF 清除✅ 自动✅❌❌可选
一次性/过期删除❌(仅手动删除码)❌✅ 到期自毁✅ 一次性链接❌
多用户体系❌✅ 完善❌❌✅
REST API✅ RESTful + MCP✅脚本端点✅ CLI 优先✅
星数(2026-10-30 实查)951~4k~1.3k~0.4k~2.5k

选型解读:要「改 URL 就能缩放/转码 + 零数据库运维」选 PictShare;要完整多用户图床社区选 Chevereto;要阅后即焚的一次性分享选 Jirafeau 或 goploader(两者在本平台另有专栏实测:Jirafeau 见 https://www.quzuo.net/document/9M8Fmc0Fcj39 、goploader 见 https://www.quzuo.net/document/I0STQ0XFyGOQ)。

⚠️ 注意:上表星数为 2026-10-30 经 shields.io 实查的瞬时值,仅反映相对热度,选型时建议以当时实查为准。

八、参考链接

  1. 官方仓库:https://github.com/HaschekSolutions/PictShare(v3.7.5,查询日期 2026-10-30)
  2. 官方配置手册:https://github.com/HaschekSolutions/PictShare/blob/master/rtfm/CONFIG.md
  3. 官方 API 手册:https://github.com/HaschekSolutions/PictShare/blob/master/rtfm/API.md
  4. 官方 Docker 镜像:https://hub.docker.com/r/hascheksolutions/pictshare
  5. 官网演示:https://pictshare.net
  6. 本专栏系列:《PictShare 3.7.5 Docker Compose 部署指南》(https://www.quzuo.net/document/ILUkOrJVYiZD)、《PictShare 3.7.5 配置参数详解》(https://www.quzuo.net/document/K2LlXSHlRiG6)、《PictShare 3.7.5 URL 参数与 HTTP API 详解》(https://www.quzuo.net/document/hepbPtXpdr8g)。