本文是 Lychee 自建相册系列的一部分。
简短结论:在 Xserver 这类没有 root 权限的共享主机上,Lychee 用 Imagick 生成 placeholder 会全部失败。把图片处理后端切换为 GD 后,问题解决,不需要修改系统文件。
问题现象
运行 lychee:generate_thumbs placeholder 后,从第 0 张照片开始就持续报错,没有一张成功。
small、medium 等其他尺寸的缩略图生成正常,只有 placeholder 失败。
这并不影响照片的正常显示,只是缺少加载时的模糊占位图(类似 Instagram 大图加载前先出现的模糊色块),加载过渡会不够顺滑。
环境
- Lychee:[Version6]
- PHP:8.4
- ImageMagick:6(系统自带)
- 主机:Xserver 共享主机,无 sudo 权限
原因推测
全部失败,而不是个别照片失败,说明问题出在 placeholder 这个步骤本身。我检查了 ImageMagick 的策略文件:
cat /etc/ImageMagick-6/policy.xml | grep -i "rights\|pattern"<policy domain="path" rights="none" pattern="@*" />它禁止 ImageMagick 读取以 @ 开头的路径。我推测 Lychee 在生成 placeholder 时,Imagick 扩展用到了类似的读取方式,从而触发了这条限制。small 和 medium 走的是不同的读取路径,所以没有受影响。
需要说明的是,这只是推测。我最终没有修改这条规则,所以并没有验证它就是根本原因。
没走通的方案:修改 policy.xml
最直接的办法是注释掉这条规则:
sudo sed -i 's|<policy domain="path" rights="none" pattern="@\*" />|<!-- <policy domain="path" rights="none" pattern="@*" /> -->|' /etc/ImageMagick-6/policy.xml但共享主机上 /etc/ 通常是只读的,而且没有 sudo 权限:
sudo sed -i 's|<policy domain="path" rights="none" pattern="@\*" />|<!-- <policy domain="path" rights="none" pattern="@*" /> -->|' /etc/ImageMagick-6/policy.xml-bash: /usr/bin/sudo: 許可がありません所以这个办法在共享主机上行不通。如果是 VPS 或自己的服务器,可以直接用。
解决办法:改用 GD
Lychee 支持 Imagick 和 GD 两种图片处理后端。既然改不了系统配置,就在 Lychee 里切换后端。
1. 修改数据库中的配置项(把尖括号部分替换成实际名称):
mysql -u <DB_USER> -p <DB_NAME> -e "UPDATE configs SET value=0 WHERE \`key\`='imagick';"2. 确认修改成功:
mysql -u <DB_USER> -p <DB_NAME> -e "SELECT \`key\`, value FROM configs WHERE \`key\`='imagick';"输出中 value 为 0 即表示已切换到 GD:
+---------+-------+
| key | value |
+---------+-------+
| imagick | 0 |
+---------+-------+3. 清除缓存并重新生成:
php artisan config:clear
php artisan cache:clear
php -d max_execution_time=0 artisan lychee:generate_thumbs placeholder 1475最后一个参数 1475 是我的照片数量,请按自己的实际数量调整。
验证结果
所有照片都显示 created,不再报错:

GD 和 Imagick 的差异
GD 在 RAW 格式支持和部分滤镜上不如 Imagick 全面。但在 Lychee 日常的缩略图生成场景里,我切换后没有发现明显的画质或速度差异。如果你需要处理 RAW 文件,建议先测试一下。
常见问题
没有 placeholder 会影响照片显示吗?
不会。只是少了加载时的模糊过渡,原图依然正常显示。
共享主机没有 sudo,还能解决吗?
可以。本文的办法只修改 Lychee 自己的数据库配置,不涉及系统文件。
以后想切回 Imagick 怎么办?
把 value 改回 1,再清缓存即可。