自动化部署:使用 GitHub Actions 将应用推送到 AWS EC2 完整指南
如果你曾经推送代码到 GitHub 后立即打开终端 SSH 到服务器重启应用,那么本指南将为你解决这个问题。
手动部署在第一次时还好。但当你一天内多次推送时,它就变成了开发中最繁琐的部分。本文将展示如何完全自动化整个流程:推送代码 → 构建 Docker 镜像 → 自动部署到 AWS EC2。
无需手动步骤。无需 SSH。只需推送即可上线。
项目目标
完成本指南后,你将拥有一个能够执行以下操作的流水线:
- 每次推送到
main分支时自动触发 - 构建应用程序的 Docker 镜像
- 推送至 Amazon ECR(私有 Docker 注册表)
- SSH 连接 EC2 实例并替换运行中的容器
- 清理旧镜像以节省磁盘空间
前置条件
开始之前,请确保具备以下条件:
- AWS 账户(免费套餐即可)
- GitHub 账户
- 正在运行的 EC2 实例(Amazon Linux 2023 或 Ubuntu 22.04)
- Docker 基础知识
第一步 — 配置 EC2 实例
SSH 连接到 EC2 并安装 Docker 和 AWS CLI。创建名为 initialize.sh 的文件:
#!/bin/bash
# 安装 Docker
sudo yum update -y
sudo yum install -y docker
sudo systemctl enable docker
sudo systemctl start docker
sudo usermod -aG docker ec2-user
# 安装 AWS CLI
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
sudo yum install -y unzip
unzip -q awscliv2.zip
sudo ./aws/install --update
执行脚本:
chmod +x initialize.sh
./initialize.sh
⚠️ 完成后退出并重新 SSH 登录 — 这是应用 Docker 权限组所必需的。
第二步 — 创建 ECR 存储库
Amazon ECR 是你的私有 Docker 注册表。从本地计算机创建一个:
aws ecr create-repository \
--repository-name web-application \
--region us-east-1
记下输出中的 repositoryUri。格式如下:
987654321.dkr.ecr.us-east-1.amazonaws.com/web-application
第三步 — 为 GitHub Actions 创建 IAM 用户
GitHub Actions 需要 AWS 凭据才能将镜像推送到 ECR。创建具有最小权限的专用用户。
- 进入 AWS 控制台 → IAM → 用户 → 创建用户
- 命名为
ci-cd-deployment - 创建自定义策略并粘贴以下 JSON:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["ecr:GetAuthorizationToken"],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ecr:BatchCheckLayerAvailability",
"ecr:PutImage",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload",
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage"
],
"Resource": "arn:aws:ecr:*:*:repository/*"
}
]
}
- 创建 访问密钥 并保存凭据。
第四步 — 添加 GitHub 密钥
进入 GitHub 仓库 → 设置 → 机密和变量 → Actions → 添加以下内容:
| 机密名称 | 值 |
|---|---|
AWS_ACCESS_KEY_ID |
第三步获取的值 |
AWS_SECRET_ACCESS_KEY |
第三步获取的值 |
SERVER_HOST |
EC2 公共 IP 地址 |
SERVER_SSH_PRIVATE_KEY |
.pem 密钥文件的完整内容 |
第五步 — 流水线配置文件
在仓库中创建 .github/workflows/deployment.yml:
name: 构建并部署到 AWS EC2
on:
push:
branches:
- main
env:
AWS_REGION: us-east-1
ECR_REPOSITORY: web-application
SERVER_USERNAME: ec2-user
APPLICATION_PORT: 3000
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: 检出代码
uses: actions/checkout@v4
- name: 配置 AWS 凭据
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
- name: 登录 Amazon ECR
id: authenticate-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: 构建、标记并推送镜像到 ECR
id: build-container
env:
REGISTRY_ENDPOINT: ${{ steps.authenticate-ecr.outputs.registry }}
TAG_VERSION: ${{ github.sha }}
run: |
docker build -t $REGISTRY_ENDPOINT/$ECR_REPOSITORY:$TAG_VERSION .
docker push $REGISTRY_ENDPOINT/$ECR_REPOSITORY:$TAG_VERSION
echo "container_image=$REGISTRY_ENDPOINT/$ECR_REPOSITORY:$TAG_VERSION" >> $GITHUB_OUTPUT
- name: 部署到 EC2
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ env.SERVER_USERNAME }}
key: ${{ secrets.SERVER_SSH_PRIVATE_KEY }}
script: |
aws ecr get-login-password --region ${{ env.AWS_REGION }} | \
docker login --username AWS --password-stdin \
${{ steps.authenticate-ecr.outputs.registry }}
docker pull ${{ steps.build-container.outputs.container_image }}
docker stop web-service || true
docker rm web-service || true
docker run -d \
--name web-service \
--restart unless-stopped \
-p 80:${{ env.APPLICATION_PORT }} \
${{ steps.build-container.outputs.container_image }}
docker system prune -f
第六步 — 推送并观察运行
git add .
git commit -m "添加 ci/cd 流水线"
git push origin main
前往 GitHub → Actions 标签页。观察其运行。绿色对勾表示应用已上线。✅
在浏览器中打开 EC2 公共 IP 确认。
常见错误及解决方案
ECR 登录失败 通常是 GitHub 机密中的凭据错误。仔细检查访问密钥 ID 和密钥。
SSH 连接被拒绝 EC2 安全组中未开放端口 22。为 SSH 添加入站规则。
浏览器无法加载应用 安全组未开放端口 80。或容器崩溃 — 在 EC2 上运行 docker logs web-service 查看原因。
EC2 上 Docker 权限被拒绝 未在运行 initialize.sh 后退出。退出并重新 SSH 登录。
平台错误 在 docker build 命令中添加 --platform linux/amd64。常见于 Apple M1/M2 Mac。
后续考虑
一旦此流水线运行正常,可考虑添加:
- 部署成功/失败的通知(Slack 或邮件)
- 部署后调用
/health端点的健康检查步骤 - 如果健康检查失败,使用前一镜像标签的回滚逻辑
- 不同分支的独立流水线(如预发布和生产环境)