那个让我连续加班三个月的噩梦
四年前,我接手了一个日活5万的论坛站点,那时候的部署流程堪称原始时代——FTP上传代码,SSH进服务器手动执行命令,数据库迁移全靠手打SQL,每个月总有那么一两天,凌晨三点被报警短信炸醒,爬起来修服务器。
最惨的一次,我手滑把线上数据库表删了,那晚我对着屏幕上的drop table像被人浇了一盆冷水,手指发抖地翻了三小时备份文件,从那之后,我下定决心:要么用自动化工具把自己从苦海里捞出来,要么就等着被老板炒掉。
持续集成部署踩坑实录,从月月修服务器到躺平收钱,我只用了这三招
CI/CD不是玄学,是救命稻草
持续集成部署这四个字听着高大上,说白了就是:代码改完自动测试、自动打包、自动部署到服务器,我用的是最简单的方案:GitHub + GitHub Actions + 阿里云ECS。
踩坑的第一个点:代码放到哪里? 很多人上来就纠结GitLab还是Jenkins,我告诉你,个人站或小团队,GitHub Actions就够用了,别学大厂造轮子,浪费的时间够你喝半年咖啡。
具体配置我吃过不少亏,gitlab-ci.yml文件里,我一开始把branches写成了branch,结果每次推送代码,流水线都不触发,蹲在服务器前等了半小时才反应过来,还有一次,actions脚本里忘了设置cache,每次构建都要重新下载依赖,一个简单的WordPress站点,构建时间从2分钟拖到15分钟。
推荐的实用方案:
name: Deploy to Server
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Deploy via rsync
uses: easingthemes/ssh-deploy@v2
with:
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
ARGS: "-avz --delete"
SOURCE: "./"
REMOTE_HOST: ${{ secrets.HOST }}
REMOTE_USER: "root"
TARGET: "/var/www/html"
这个配置看起来简单,但暗藏杀机。--delete参数有个坑:如果你本地的/dist目录是空的,它会把你服务器上的所有文件都删光,我第一次用这个参数,差点把整个服务器的Nginx配置都清空了,幸亏提前做了快照。
服务器和域名——那些年我交的智商税
域名和服务器是CI/CD的基础,但这里踩坑的人最多。
域名解析TTL:我见过太多人把TTL设置成3600秒(1小时),这意味着你改完DNS,要等一个小时才生效,如果你像我一样在深夜改域名,那全站离线的一小时足够让你被用户骂到怀疑人生,把TTL设成60秒,改完等两分钟,测试通过再调回默认值。
SSL证书:Let's Encrypt的免费证书很好用,但千万别手动续期,我第二年因为忘记续期,整个站挂了整整两天,用acme.sh脚本配合cron自动续期,设置每天凌晨3点检查一次,比什么都靠谱。
服务器内存:1GB内存的轻量云服务器看起来够用,但如果你跑CI/CD的构建任务,内存会被GitHub Actions的runner吃光,我最后选了2核4G的配置,多花的钱远少于半夜爬起来重启服务器浪费的时间。
程序层面的劫后余生
数据库迁移:这是CI/CD里最容易翻车的地方,我见过最惨的案例:某人把线上数据库的连接字符串写进了database.php,提交代码时忘了加密,结果整个数据库被公开,解决方案很简单:用环境变量。.env文件永远不要提交到Git仓库,而是通过CI/CD的secrets管理。
配置文件冲突:本地开发环境和线上环境肯定不一样,我踩过的坑是:本地用MySQL,线上用MariaDB,数据库驱动名字不一样,一上线就报错,解决方案:在CI/CD流水线里加一个编译步骤,把配置文件按照环境变量自动生成。
静态资源缓存:图片、CSS、JS文件更新后,用户浏览器还是旧版本,整个站点瞬间变成“90年代风格”,我在Nginx里配置了文件版本号,每次部署自动生成新版本号,再配合CDN缓存清理,总算解决了这个问题。
长期维护——比建站更难的守业
监控告警:别以为CI/CD部署完就能躺平,我吃过最大的亏是:流水线运行失败时,GitHub只往我的邮箱发通知,而我每天要看几百封邮件,直接忽略了,后来改成微信群机器人+钉钉通知,失效率从30%降到0。
日志切割:服务器硬盘被日志撑爆是什么体验?我遇到过,整个站显示“No space left on device”,吓得赶紧去阿里云扩容,结果发现只是/var/log里的日志占了30GB,配置logrotate,按天切割,保留7天,成了我维护列表里的铁律。
备份策略:CI/CD自动部署之后,最容易让人松懈的就是备份,我见过有人把备份脚本和CI/CD绑在一起,结果流水线失败,备份也跟着停了,还是那句老话:三条备份规则:本地一份、服务器一份、云存储一份,缺一不可。
给新手的三条建议
-
从小做起:别一开始就想着全自动化,先用手动部署跑通整个流程,再慢慢加自动化步骤,我第一个CI/CD项目只做了“自动scp文件到服务器”这一步,用了三个星期才研究明白。
-
理解失败:第一次跑通CI/CD流水线,别高兴太早,我那个论坛的流水线第一次跑成功,结果部署上去发现所有中文都变成乱码了——PHP的
default_charset设置没配,多测试几次,把各种可能失败的情况都模拟一遍。 -
留有余地:永远保留手动部署的能力,我见过最狠的情况:CI/CD平台挂了,整个团队没法上线任何代码,我在服务器上留了一个
deploy.sh脚本,用SSH直接执行,虽然原始,但至少能救命。
最后说一句:持续集成部署不是终点,而是起点,真正好的运维,是让你忘了运维的存在,别急着追求高大上的工具链,把基础打扎实了,比什么都强。



发表评论