实验: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
修复
确保 build 和 push 阶段使用 相同 的 $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 中添加以下变量(未受保护,可见):
| Key | Value |
|---|---|
EC2_HOST | EC2 公网 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?”你可以这样回答:
- 为应用程序创建一个
Dockerfile。 - 配置一个多阶段的
.gitlab-ci.yml流水线(build、push、deploy)。 - 构建 Docker 镜像并推送到 GitLab Container Registry。
- 将 EC2 的 SSH 私钥和主机 IP 保存为 CI/CD 变量。
- 在 deploy 阶段,SSH 登录到 EC2 实例,登录注册表,拉取镜像,停止/删除已有容器,并在 80 端口运行新容器。
- 处理常见问题(变量缺失、端口冲突、已有服务),确保部署具备幂等性,适合生产环境。