Missing write permissions to the following directories: pub/static 看起来是权限不足,但把目录改成 777 仍可能报错。Magento 会递归检查目录中的文件和符号链接;旧 release 留下的失效软链、文件属主混乱、只读挂载,都可能让整个检查失败。先找出具体是哪一个节点不可写,比整站放开权限可靠得多。

先确认现在是谁在执行命令

id
ps -eo user,group,cmd | rg 'php-fpm|apache2|httpd'
namei -l pub/static
find pub/static -maxdepth 3 \( ! -user deploy -o ! -group www-data \) -ls | head -50

示例里的 deploy 和 www-data 要换成服务器真实用户。重点是发布用户能创建文件,PHP-FPM 用户能读取;如果运行时也需要生成静态文件,则双方要通过同一组获得写权限。不要混用 root、部署账号和 Web 用户轮流跑 Magento 命令,否则下一次发布还会反复变属主。

777也无效时,检查失效软链和挂载

find -L pub/static -type l -print
findmnt -T pub/static
getfacl -p pub/static | sed -n '1,40p'

旧版本或开发模式可能留下指向已删除源文件的软链。权限检查递归走到这里会失败,即使父目录是 777 也没用。容器环境还要看 pub/static 是否被只读 volume 覆盖,宿主机权限和容器内 uid 是否一致。

确认可以重建后再清静态产物

pub/static 属于生成内容,但 .htaccess 在 Apache 环境中可能仍需要保留。不要无脑删除整个目录。可以先备份并仅清生成内容:

find pub/static -mindepth 1 ! -name '.htaccess' -delete
find var/view_preprocessed -mindepth 1 -delete

如果目录里混入了人工上传文件,先停下来确认发布流程,不能因为它“理论上可生成”就直接清空。

把属主和组一次修到发布模型上

常见做法是代码归部署用户、可写目录归共享组,并设置 setgid 让新文件继承组:

chown -R deploy:www-data pub/static var generated
find pub/static var generated -type d -exec chmod 2775 {} +
find pub/static var generated -type f -exec chmod 0664 {} +

上面只是模型,具体权限要按主朸隔离策略调整。修完后用部署用户依次跑 setup:upgrade 和静态资源部署,再用 PHP-FPM 用户做一次只读访问验证。问题解决的标准不是命令暂时通过,而是下一次发布不会再次产生 root 属主文件。