上线前最后一小时,我盯着这份清单才没把测试数据打包进生产包
上周帮朋友公司救急,他们新项目上线当晚就炸了——后台菜单全白,用户端能直接访问 /admin/install,数据库配置里还躺着 root/123456。我远程连上去一看,好家伙,.env 文件权限 777,路由缓存里混着本地调试的闭包,OSS _bucket 名写的是 test-bucket-2024。这事儿给我敲了个警钟,回来就把我自己项目的上线前检查流程重新捋了一遍,今天分享出来,权当抛砖引玉。
一、文件权限:别等被扫了才想起来改
我现在的习惯是部署脚本里硬编码三条 chmod,但手工检查依然要过一遍:
• .env 及其备份文件 → 600,所属用户必须是运行 PHP 的那个(www 或 www-data),组和其他人一律不给读
• runtime/、uploads/、log/ 这类可写目录 → 755 封顶,能 750 绝不 755
• 应用入口 index.php → 644 足够,别手贱给执行权限
有个细节容易漏:如果你用 Git 部署,.env.example 里如果带了真实密钥,记得检查 .gitignore 到底生没生效。我见过有人把 .env 写进 ignore 但文件已经 tracked 了,push 上去裸奔半年。
二、路由:缓存清了吗?闭包清了吗?
ThinkPHP 6 的路由缓存是个双刃剑。本地开发图省事写一堆闭包路由,上线前必须全部换成控制器方法,否则 route:cache 直接报错。我的检查步骤:
1. 先 php think route:clear 清干净
2. 再 route:cache 生成新的,看能不能成功
3. 重点扫一遍 route/app.php 和路由目录,搜索 function( 和 Closure,发现一个杀一个
4. 最后把生成的 runtime/route.php 权限改成 644,别让它意外可写
另外多应用模式下,应用映射要确认。我有一次把 admin 映射成了 backend,结果线上菜单全 404,排查半小时才发现是 nginx 重写规则和路由映射对不上。
三、菜单与权限:数据初始化比代码更危险
后台菜单我现在的做法是:数据库里只存菜单骨架,具体权限节点由代码里的注解或配置文件生成。上线前必查:
• 超级管理员账号密码是不是测试用的 admin/admin,是的话立刻改,同时检查有没有遗留的 test/test、demo/demo
• 权限表数据初始化脚本有没有跑,role_id = 1 的权限范围对不对
• 菜单里有没有指向本地环境的链接,比如 http://localhost:8080 或者 127.0.0.1:9527 这种前端开发地址
• 如果用了数据字典缓存,记得 clear 再预热,否则新菜单项可能不显示
有个血泪教训:之前项目用了第三方登录,上线前忘记把微信回调域名从测试环境切过来,用户扫码完跳回 localhost,体验直接崩盘。
四、配置:.env 里的坑,十个有九个在这儿
我现在维护一份 env.production 模板,每次上线前 diff 对比。重点盯这些字段:
• APP_DEBUG:必须是 false,日志级别从 debug 切到 error 或 info
• 数据库连接:host 不能是 127.0.0.1(除非你数据库和应用同机,但云环境下基本不是),charset 和 prefix 确认对版
• 缓存驱动:本地用的 file 还是 redis?如果是 redis,host/port/auth 对不对,select 的库号有没有和别的项目冲突
• 邮件/短信/云存储:所有第三方服务的 key 和 secret 必须切到生产账号,bucket 名、region 节点逐个核对
• 域名相关:如果配置了 CDN 回源地址、OSS 自定义域名、微信 JS 接口安全域名,确保都是生产域名
特别提醒:ThinkPHP 的 .env 解析有点特殊,值里如果带 # 号会被当成注释截断。我有一次数据库密码末尾是 #x9,连上去一直认证失败,排查到怀疑人生。
五、我现在的最后一步:模拟一次全新部署
清单再全,也可能有惯性盲区。我现在上线前会在测试服务器上做一次"干净安装"——从 Git 拉最新代码,按文档走一遍安装流程,看能不能跑通。这个步骤帮我抓到过两次问题:一次是安装脚本里写死了旧版 PHP 路径,一次是 composer.lock 和实际依赖对不上导致 autoload 缺失。
你们上线前有什么必查项?或者因为漏了哪一步被坑过?欢迎补充,我这份清单还能再厚一点。

