CI/CD流水线搭建:GitHub Actions + Docker + Railway自动化部署实战
摘要:在AI应用开发中,如何确保每次代码提交都能自动完成Lint检查、单元测试并平滑部署到生产环境?本文基于一个真实的跑步教练AI项目,详细解析从零搭建CI/CD流水线的完整过程。我们将深入配置文件,结合流程图和分支策略,展示如何利用GitHub Actions实现"提交即测试"、如何通过Docker多阶段构建优化镜像体积,以及如何利用Railway平台实现零宕机发布。这套方案将版本迭代周期从2天缩短到了2小时,是工程化转型的关键一步。
一、背景:手动部署的"至暗时刻"
在项目初期,我的发布流程是这样的:
- 本地运行
pytest和flake8。 - 手动
git push。 - SSH登录服务器,
git pull。 - 手动重启 Docker 容器。
痛点:
- 漏测风险:有一次忘了跑测试就上线,导致一个API接口直接500报错。
- 环境不一致:本地Python 3.11,服务器3.9,依赖冲突频发。
- 回滚困难:一旦新版本有问题,想切回旧版本得折腾半天。
二、解决方案:Git Flow + GitHub Actions
2.1 分支管理策略
我们采用了简化的 Git Flow:
PR合并
验证通过
feature/*
功能开发
staging
预发布环境
main
生产环境
feature/*:每个新功能一个分支。staging:自动部署到测试服,供内部验收。main:只有经过验证的代码才能合入,触发生产部署。
2.2 整体流水线架构
| 阶段 | 工具 | 动作 |
|---|---|---|
| CI (持续集成) | GitHub Actions | Lint检查、运行测试、构建Docker镜像 |
| CD (持续交付) | Railway / Docker Hub | 推送镜像、自动更新线上服务 |
三、核心实现:CI Pipeline配置
文件位置:.github/workflows/ci.yml
yaml
name: CI Pipeline
on:
push:
branches: [ "main", "staging" ]
pull_request:
branches: [ "main" ]
jobs:
quality-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install dependencies
run: |
pip install -r requirements.txt
pip install flake8 pytest
# 1. 代码规范检查
- name: Lint with flake8
run: |
flake8 app/ --count --max-line-length=120 --statistics
# 2. 自动化测试
- name: Test with pytest
run: |
pytest tests/ -v --cov=app --cov-report=xml
# 3. 覆盖率门禁(低于80%则阻断)
- name: Check coverage
run: |
coverage report --fail-under=80
关键点:
--fail-under=80:强制要求测试覆盖率达到80%,否则流水线直接失败,禁止合并。- 并行执行:Lint和Test可以并行,加快反馈速度。
四、核心实现:CD Pipeline与Docker构建
4.1 Docker多阶段构建
为了减小镜像体积,我们使用了多阶段构建。
文件位置:Dockerfile.ci
dockerfile
# Stage 1: 构建依赖
FROM python:3.11-slim as builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user -r requirements.txt
# Stage 2: 运行环境
FROM python:3.11-slim
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY . .
ENV PATH=/root/.local/bin:$PATH
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0"]
效果 :镜像体积从 1.2GB 降到了 350MB,部署速度提升3倍。
4.2 自动化部署脚本
yaml
deploy:
needs: quality-check
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- name: Deploy to Railway
uses: bervProject/railway-deploy@main
with:
railway_token: ${{ secrets.RAILWAY_TOKEN }}
service: backend-api
五、完整调用链追踪
5.1 一次完整的发布流程
Production (Railway) Docker Registry Actions Runner GitHub 开发者 Production (Railway) Docker Registry Actions Runner GitHub 开发者 触发 CI Pipeline 触发 CD Pipeline alt [检查失败] [检查通过] git push origin main Checkout Code Run flake8 & pytest ❌ 发送失败通知邮件 Build Docker Image Push Image (tag: latest) 检测到新镜像 滚动更新 (Rolling Update) ✅ 部署成功
六、踩坑记录与解决方案
坑1:环境变量缺失导致测试失败
现象:本地测试全过,CI里全红。
原因 :CI环境没有加载 .env 文件。
解决方案 :在GitHub Settings -> Secrets中配置所有必要的环境变量,并在Workflow中通过 env: 注入。
坑2:数据库迁移未同步
现象:代码上线了,但PostgreSQL表结构没变,启动报错。
解决方案 :在CD流程中加入 alembic upgrade head 步骤,确保数据库结构随代码自动演进。
七、总结与展望
核心价值
- 质量门禁:杜绝了低级错误流入生产环境。
- 效率提升:开发者只需关注代码,剩下的交给流水线。
- 可追溯性:每一次部署都有对应的Commit Hash和测试结果存档。
后续优化
- 蓝绿部署:进一步实现零感知发布。
- 自动化Changelog:根据Commit信息自动生成版本更新日志。
八、完整源码
GitHub仓库 :AiRunCoachAgent
快速演示 :AiRunCoachAgent
核心文件清单:
.github/
└── workflows/
├── ci.yml # 持续集成配置
└── cd.yml # 持续部署配置
Dockerfile.ci # 生产级镜像定义
如果你觉得这篇文章对你有帮助,欢迎点赞、收藏、转发!有任何问题或建议,请在评论区留言讨论。 🏃♂️💨