vendor/autoload.php找不到是因为deployer默认只同步源码,未自动执行composer install;必须显式添加after('deploy:update_code', 'deploy:vendors')并确保远程已全局安装composer。

exec 调用失败、deploy:prepare 权限拒绝、vendor/autoload.php 找不到 —— 这些不是配置没写对,而是部署链路上几个关键节点没对齐:PHP进程权限、Git环境一致性、Composer执行时机、符号链接切换逻辑。学自动化部署,本质是学「谁在什么时候以什么身份干了什么事」。
为什么 exec('git pull') 在浏览器里总失败
Web 服务器(如 Apache 或 Nginx)启动的 PHP 进程默认以低权限用户(如 www-data)运行,它很可能:
• 没有读写项目目录的权限(chmod -R g+w /var/www/myapp 不够,还得确认组归属)
• 找不到 git 命令(which git 返回空,需在 exec 中指定全路径,如 /usr/bin/git)
• 无法读取 SSH 私钥(Web 用户家目录下无 ~/.ssh/id_rsa,且 ssh-agent 不可用)
• 被 PHP 的 disable_functions 拦截(检查 phpinfo() 输出中 disable_functions 是否含 exec、shell_exec 等)
真正能跑通的最小验证方式是:切到 Web 用户身份手动执行一遍命令:sudo -u www-data bash -c "cd /var/www/myapp && /usr/bin/git pull origin main"
dep deploy 卡在 deploy:prepare 怎么破
Deployer 默认不走 sudo,所有操作都以你配置的 SSH 用户身份执行。报 Permission denied 通常是因为:
• 目标路径(如 /var/www/myapp)不存在,或所属组不是该用户所在组
• 该用户对父目录(如 /var/www)只有 rx 权限,缺 w(mkdir 需要父目录可写)
• deploy_path 设的是 /var/www/myapp,但 Deployer 实际会在其下建 releases、shared 子目录 —— 它需要对 /var/www/myapp 本身有写权限
解决办法三步:
• 提前创建目录并设组:sudo mkdir -p /var/www/myapp && sudo chgrp deploy /var/www/myapp && sudo chmod g+rws /var/www/myapp
• 确保 SSH 用户 deploy 已加入该组:sudo usermod -aG deploy www-data(按实际组名调整)
• 在 deploy.php 中显式设置 set('writable_mode', 'chown');,避免依赖 chmod 时的权限继承问题
部署完页面 500,vendor/autoload.php 为啥找不到
Deployer 默认只同步源码,composer install 是独立任务,默认未启用。常见误区:
• 认为 dep deploy 自动装依赖(其实不会,除非你显式调用 deploy:vendors 或自定义 task)
• 在远程服务器上没装 Composer,或装在用户目录下但未加入 $PATH(run('which composer') 应返回路径)
• 忘了加 --no-dev --optimize-autoloader,导致线上加载慢甚至失败
必须做的配置:
• 在 deploy.php 中添加:after('deploy:update_code', 'deploy:vendors');
• 确保远程机器已全局安装 Composer:curl -sS https://getcomposer.org/installer | php && sudo mv composer.phar /usr/local/bin/composer
• 如果项目用了自定义 composer.phar 路径,得重写 deploy:vendors task,显式指定 run('{{composer_cmd}} install ...')
用 git hook 自动拉取,为什么推完代码没更新
post-receive 钩子执行时,工作环境极简:没有用户 shell 初始化(~/.bashrc 不加载)、$PATH 极短、SSH agent 不可用。最常踩的坑:
• git --work-tree=... checkout -f 报错 “not a git repository”,其实是 --git-dir 路径写错了(应指向 .git 目录,不是裸仓库路径)
• 钩子脚本里用 cd /path && git pull,但当前工作目录是 hooks 目录,cd 失败后命令静默跳过
• 没校验推送分支:if [[ $ref == refs/heads/main ]] 写成 =(bash 中单等号不支持模式匹配)
安全写法示例:
#!/bin/bash
GIT_DIR="/var/repo/myapp.git"
WORK_TREE="/var/www/myapp"
BRANCH="main"
while read oldrev newrev ref; do
if [[ $ref == refs/heads/$BRANCH ]]; then
git --git-dir=$GIT_DIR --work-tree=$WORK_TREE checkout -f $BRANCH 2>&1
fi
done记得给钩子加可执行权限:chmod +x post-receive,且确保 $WORK_TREE 目录存在、属主与钩子执行用户一致
部署最难的从来不是写哪行代码,而是搞清每个环节背后那个“看不见的执行者”——它是 Web 用户、SSH 用户、还是 Git Hook 的系统用户?权限、路径、环境变量,三者只要一个没对齐,整条链就断在那儿。php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











