实验:GitLab CI/CD Docker 部署到 AWS EC2

发布: (2026年2月21日 GMT+8 08:02)
4 分钟阅读
原文: Dev.to

Source: Dev.to

🎯 实验目标

构建完整的 CI/CD 流水线,使其能够:

  • 将 GitLab 连接到 Mac 终端
  • 构建 Docker 镜像
  • 将镜像推送到 GitLab Registry
  • SSH 登录 EC2
  • 部署容器
  • 处理真实生产环境中的错误

🏗️ 架构

Mac Terminal

GitLab Repo

GitLab CI/CD Pipeline

Docker Image Build

Push to GitLab Container Registry

SSH to AWS EC2

Docker Pull & Run

Application Live on Port 80

🔹 步骤

STEP 1 — GitLab Pages 基础流水线

.gitlab-ci.yml

image: busybox

pages:
  stage: deploy
  script:
    - echo "The site will be deployed"
  artifacts:
    paths:
      - public
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

触发流水线:

git commit --allow-empty -m "Trigger pipeline"
git push origin master

STEP 2 — 添加 Docker 构建阶段

在项目根目录创建 Dockerfile

FROM nginx:alpine
COPY public /usr/share/nginx/html
EXPOSE 80

更新 .gitlab-ci.yml

stages:
  - build
  - push
  - deploy

variables:
  IMAGE_NAME: registry.gitlab.com/$CI_PROJECT_PATH:latest

build_image:
  stage: build
  image: docker:24
  services:
    - docker:24-dind
  script:
    - docker build -t $IMAGE_NAME .

STEP 5 — 推送到 GitLab 容器注册表

添加推送任务:

push_image:
  stage: push
  image: docker:24
  services:
    - docker:24-dind
  script:
    - echo $CI_REGISTRY_PASSWORD | docker login -u $CI_REGISTRY_USER --password-stdin $CI_REGISTRY
    - docker push $IMAGE_NAME

🔴 错误与修复

错误 #1 — 未找到镜像

错误

An image does not exist locally with the tag

修复
确保 buildpush 阶段使用 相同$IMAGE_NAME

步骤 6 — 部署到 AWS EC2

Deploy job:

deploy_ec2:
  stage: deploy
  image: alpine
  before_script:
    - apk add --no-cache openssh
  script:
    - echo "$EC2_KEY" > key.pem
    - chmod 600 key.pem
    - ssh -o StrictHostKeyChecking=no -i key.pem ubuntu@$EC2_HOST "
        docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY &&
        docker pull $IMAGE_NAME &&
        docker stop web || true &&
        docker rm web || true &&
        docker run -d -p 80:80 --name web $IMAGE_NAME
      "

错误 #2 — SSH 主机名未解析

原因
CI/CD 变量未设置。

修复
Settings → CI/CD → Variables 中添加以下变量(未受保护,可见):

KeyValue
EC2_HOSTEC2 公网 IP 地址
EC2_KEY.pem 文件的完整内容

错误 #3 — 端口 80 已被占用

流水线错误

failed to bind host port 80
address already in use

调查

ssh -i key.pem ubuntu@$EC2_HOST
sudo lsof -i :80

结果显示 nginx 正在监听 80 端口。

修复

sudo systemctl stop nginx
sudo systemctl disable nginx

重新运行流水线 → 成功

🔹 最终结果

应用程序可通过以下地址访问:

http://

🧠 实际 DevOps 故障排除经验

问题使用工具
SSH 被拒绝ssh-add
缺少流水线变量GitLab CI/CD 变量
Docker 标签不匹配检查 $IMAGE_NAME
SSH 主机名错误验证变量
端口冲突lsof -i :80
Nginx 冲突systemctl stop

这些是典型的生产级调试步骤。

🎓 Interview Explanation Version

如果面试官问:“如何使用 GitLab CI/CD 部署到 EC2?”你可以这样回答:

  1. 为应用程序创建一个 Dockerfile
  2. 配置一个多阶段的 .gitlab-ci.yml 流水线(build、push、deploy)。
  3. 构建 Docker 镜像并推送到 GitLab Container Registry。
  4. 将 EC2 的 SSH 私钥和主机 IP 保存为 CI/CD 变量。
  5. deploy 阶段,SSH 登录到 EC2 实例,登录注册表,拉取镜像,停止/删除已有容器,并在 80 端口运行新容器。
  6. 处理常见问题(变量缺失、端口冲突、已有服务),确保部署具备幂等性,适合生产环境。
0 浏览
Back to Blog

相关文章

阅读更多 »

Subnetting 详解

什么是 Subnetting?可以把它想象成把一栋大型公寓楼拆分成不同的楼层。每层 subnet 拥有自己的编号主机(hosts),以及建筑……