AWS EC2实例Docker应用简易CI/CD部署方案咨询
问题场景
- 现有资源:1台运行Docker的Ubuntu系统EC2实例
- 需求:搭建简易持续部署流程,实现向GitHub仓库推送代码后,自动在EC2上拉取最新代码,依次执行
docker build、docker run完成应用更新 - 已尝试方案:使用GitHub Actions通过SSH连接EC2执行部署命令,可正常连通实例,但执行Docker相关命令后工作流卡住,拆分命令到独立shell脚本执行仍未解决问题
原有GitHub Actions配置
name: scp files on: [push] jobs: build: name: Build runs-on: ubuntu-latest steps: - uses: actions/checkout@master - name: Pull changes and run docker uses: fifsky/ssh-action@master with: command: | cd test_ec2_deployment git pull sudo docker build --network host -f Dockerfile -t test . sudo docker run -d --env-file=/home/ubuntu/.env -ti test host: ${{ secrets.HOST }} user: ubuntu key: ${{ secrets.SSH_KEY }} args: "-tt"
工作流卡住前的最后输出
Step 12/13 : RUN /usr/bin/crontab /etc/cron.d/cron-job ---> Running in 52a5a0174958 Removing intermediate container 52a5a0174958 ---> badf6fdaf774 Step 13/13 : CMD printenv > /etc/environment && cron -f ---> Running in 0e9fd12db4f7 Removing intermediate container 0e9fd12db4f7 ---> 888a2a9e5910 Successfully built 888a2a9e5910 Successfully tagged test:latest
待确认问题
- 是否可以通过AWS CodePipeline或其他AWS原生服务实现该CD架构
- 针对该轻量部署场景,搭建Jenkins是否复杂度过高
解决方案
1. 修复现有GitHub Actions配置(最轻量,优先推荐)
工作流卡住的核心原因是docker run的参数配置错误:
- 你已经加了
-d参数让容器后台运行,但同时又加了-ti参数(分配交互式伪终端),结合SSH命令的-tt强制分配终端参数,会导致Docker启动后持续持有SSH会话的终端连接,命令永远不会返回退出码,GitHub Actions就会一直等待直到超时。 - 修复方式很简单:去掉
docker run命令里的-ti参数,同时建议部署前先停掉、删除旧的同名容器,避免端口/容器名冲突,修改后的部署命令段如下:
cd test_ec2_deployment git pull sudo docker stop test || true sudo docker rm test || true sudo docker build --network host -f Dockerfile -t test . sudo docker run -d --restart=always --name test --env-file=/home/ubuntu/.env test
- 额外优化:把SSH的
args: "-tt"去掉,非交互式SSH执行命令不需要强制分配终端,能进一步避免类似的会话挂起问题。
2. AWS原生服务实现方案
如果倾向用AWS生态的服务,可以选CodePipeline+CodeDeploy的组合,不需要自己维护CI/CD服务器:
- 架构流程:GitHub代码推送触发CodePipeline拉取代码 → 可选CodeBuild完成镜像构建(也可以直接把build步骤放EC2上执行)→ CodeDeploy通过SSM或SSH发命令到EC2实例执行部署脚本
- 复杂度对比:比修好现有GitHub Actions高,需要提前配置IAM角色、EC2预装CodeDeploy Agent、部署组、应用规范文件(appspec.yml),适合后续要扩展多实例部署、需要和AWS其他服务(比如ECR存镜像、ALB做流量切换)集成的场景,单实例部署的话性价比不高。
- 更轻量的AWS原生替代:可以用EventBridge监听GitHub的webhook事件,直接触发SSM Automation文档到EC2上执行部署脚本,比CodePipeline配置简单,但还是比直接修复GitHub Actions麻烦。
3. Jenkins适配性说明
针对这个单实例轻量部署场景,搭建Jenkins的复杂度确实太高:
- 需要额外占用一台服务器(或者在现有EC2上装Jenkins,会和业务容器抢资源)
- 要做Jenkins本身的安全配置、版本维护、插件安装、权限管控
- 配置GitHub触发、SSH连接、部署流水线的工作量,远大于修复现有GitHub Actions配置的工作量,完全没有必要。
内容的提问来源于stack exchange,提问作者EnesZ
相关产品推荐
相关产品推荐

