回滚部署本质是 Git 版本切换,即通过 git reset --hard 切换到指定 tag 或 commit,再重启服务并手动判断是否需执行 migrate:rollback;Laravel 无内置回滚命令,artisan rollback 不存在,migrate:rollback 仅操作数据库。

回滚部署本质是 Git 版本切换,不是 Laravel 自带功能
Laravel 本身不提供“一键回滚部署”命令,所谓回滚,实际是把线上代码切回到上一个 Git commit 或 tag。Laravel 的 php artisan down、php artisan up 只控制维护模式,和代码版本无关。真要回滚,得靠 Git + 部署流程配合。
常见错误现象:php artisan rollback 报错“Command 'rollback' is not defined”,因为这个命令根本不存在(除非你自定义了);或者误以为 php artisan migrate:rollback 能回退整个应用版本——它只回退数据库迁移,不碰代码。
- 必须确保部署目录是 Git 仓库(
.git存在且可操作) - 推荐用 tag 管理发布版本(如
v1.2.0),比靠HEAD~1更可靠——合入 hotfix 后HEAD~1可能不是上个正式版 - 回滚前务必检查当前环境是否已执行过新版本的迁移:如果
php artisan migrate已运行,仅切代码会导致代码与数据库 schema 不匹配
用 Git reset + 重启服务是最直接的回滚方式
适用于手动部署或简单脚本部署场景,不需要额外工具。核心动作就三步:切代码、重装依赖(可选)、重启服务。
使用场景:线上出 bug 需紧急恢复,且你有服务器 SSH 权限、Git 仓库完整、Composer 依赖没大改。
- 进入部署目录:
cd /var/www/myapp - 确认当前版本:
git log --oneline -n 5,记下想回退到的 commit hash 或 tag(如v1.1.5) - 硬重置到目标版本:
git reset --hard v1.1.5(注意:这会丢弃本地未提交改动,确保无重要临时修改) - 如果
composer.json有变动,运行composer install --no-dev --optimize-autoloader - 清缓存:
php artisan config:clear && php artisan cache:clear && php artisan view:clear - 重启 PHP-FPM 或 Web 服务(如
sudo systemctl restart php8.2-fpm)
部署脚本里加回滚钩子,避免手抖出错
手动敲命令容易漏步骤(比如忘了清 config 缓存),把回滚逻辑写进部署脚本,才能真正“一键”。关键不是多炫技,而是让每一步可重复、可验证。
参数差异:rollback.sh v1.1.5 和 rollback.sh HEAD~1 行为不同——前者明确指向发布版本,后者依赖当前分支状态,CI/CD 中慎用 HEAD~1。
- 脚本开头加校验:
if [ ! -d ".git" ]; then echo "Not a git repo"; exit 1; fi - 用
git describe --tags --abbrev=0获取最新 tag,再用git rev-parse $TAG^拿上一个 tag,比硬写HEAD~1更稳 - 执行
git reset后,用git status --porcelain检查是否干净,非空则中止后续操作 - 最后输出当前 commit:
echo "Rolled back to $(git rev-parse --short HEAD)",方便核对
数据库迁移不自动回滚,必须人工判断是否要 run migrate:rollback
这是最容易被忽略的点:代码切回去了,但数据库 migration 已执行,新字段/表还在,旧代码读不到或报错。Laravel 不会、也不能自动决定要不要回退 DB。
性能 / 兼容性影响:盲目执行 php artisan migrate:rollback 可能删数据(比如 down() 方法里写了 drop),或破坏外键约束。必须看迁移文件内容再决定。
- 先查当前 migration 状态:
php artisan migrate:status,对比新旧版本的 migration 文件列表 - 只对“在新版本中新增、且旧版本不需要”的 migration 执行
php artisan migrate:rollback --step=1 - 如果新增 migration 包含破坏性变更(如删除字段),更安全的做法是写兼容 SQL,在旧代码里加判空处理,而不是强求 DB 回退
- 上线前用
php artisan migrate:fresh --seed在测试环境跑通整套回滚路径,别等线上才试
复杂点在于代码、配置、数据库、缓存四者版本必须对齐。少清一次 config:cache,或漏掉一个 env 变量变更,都可能让回滚后的应用静默失败。回滚不是按下按钮就完事,是重新走一遍发布 checklist。


















