반응형
AWS EC2에서 NGINX 애플리케이션을 Docker 이미지로 빌드하고 Docker Hub에 업로드하는 방법
1. AWS EC2 인스턴스 설정
- Docker 설치
- Git 설치
전체 워크플로
더보기
---
vim deploy.yml
name: Build, Deploy, and Health Check NGINX Application
on:
push:
branches:
- main
env:
AWS_REGION: us-east-1
SECURITY_GROUP_ID: sg-07f3e
EC2_CONTAINER_BASE_DIR: "/app/docker-container"
APPLICATION_PORT: 80
DOCKER_IMAGE_NAME: springboot-app
jobs:
build:
name: Build and Push Docker Image to Docker Hub
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Get GitHub Runner Public IP
id: ip
uses: haythem/public-ip@v1.3
- name: Configure AWS Credentials
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: Authorize Runner IP in Security Group
run: |
aws ec2 authorize-security-group-ingress \
--group-id ${{ env.SECURITY_GROUP_ID }} \
--protocol tcp \
--port 22 \
--cidr ${{ steps.ip.outputs.ipv4 }}/32 || echo "IP already exists"
- name: Deploy Docker Image
uses: appleboy/ssh-action@v1.2.0
with:
host: ${{ vars.AWS_EC2_HOST }}
username: ${{ vars.AWS_EC2_USER }}
key: ${{ secrets.AWS_EC2_SSH_KEY }}
script: |
git clone https://${{ vars.MY_GITHUB_USERNAME }}:${{ secrets.MY_GITHUB_TOKEN }}@github.com/${{ vars.MY_GITHUB_USERNAME }}/${{ vars.MY_GITHUB_NAMESPACE }}.git
cd ${{ vars.MY_GITHUB_NAMESPACE }}
git pull origin main || { echo "Failed to pull changes"; exit 1; }
echo "<html><head><meta charset='UTF-8'></head><body>날짜 및 시간 : $(date '+%Y년 %m월 %d일 %H시 %M분 %S초')</body></html>" > test.html
echo "${{ secrets.DOCKERHUB_TOKEN }}" | docker login -u "${{ vars.DOCKERHUB_USERNAME }}" --password-stdin
docker buildx rm mybuilder || true
docker buildx create --name mybuilder --driver docker-container --use
docker buildx build \
--platform linux/amd64,linux/arm64 \
--tag anti1346/playground:latest \
--push .
- name: Revoke Runner IP from Security Group
run: |
aws ec2 revoke-security-group-ingress \
--group-id ${{ env.SECURITY_GROUP_ID }} \
--protocol tcp \
--port 22 \
--cidr ${{ steps.ip.outputs.ipv4 }}/32 || echo "Failed to remove IP"
deploy:
name: Deploy Docker Image to EC2
runs-on: ubuntu-latest
needs: build
steps:
- name: Get GitHub Runner Public IP
id: ip
uses: haythem/public-ip@v1.3
- name: Configure AWS Credentials
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: Authorize Runner IP in Security Group
run: |
aws ec2 authorize-security-group-ingress \
--group-id ${{ env.SECURITY_GROUP_ID }} \
--protocol tcp \
--port 22 \
--cidr ${{ steps.ip.outputs.ipv4 }}/32 || echo "IP already exists"
- name: Deploy Docker Image
uses: appleboy/ssh-action@v1.2.0
with:
host: ${{ vars.AWS_EC2_HOST }}
username: ${{ vars.AWS_EC2_USER }}
key: ${{ secrets.AWS_EC2_SSH_KEY }}
script: |
mkdir -p ${{ env.EC2_CONTAINER_BASE_DIR }}
cd ${{ env.EC2_CONTAINER_BASE_DIR }}
docker compose down -v
docker rmi -f $(docker images | grep ${{ env.DOCKER_IMAGE_NAME }} | awk '{print $3}' | uniq) || true
docker pull anti1346/playground:latest
cat <<EOF > ${{ env.EC2_CONTAINER_BASE_DIR }}/docker-compose.yml
services:
${{ env.DOCKER_IMAGE_NAME }}:
image: anti1346/playground:latest
container_name: ${{ env.DOCKER_IMAGE_NAME }}
restart: unless-stopped
ports:
- "${{ env.APPLICATION_PORT }}:${{ env.APPLICATION_PORT }}"
EOF
docker compose up -d || echo "Failed to start the container"
- name: Revoke Runner IP from Security Group
run: |
aws ec2 revoke-security-group-ingress \
--group-id ${{ env.SECURITY_GROUP_ID }} \
--protocol tcp \
--port 22 \
--cidr ${{ steps.ip.outputs.ipv4 }}/32 || echo "Failed to remove IP"
health_check:
name: Health Check of Deployed Application
runs-on: ubuntu-latest
needs: deploy
steps:
- name: Get GitHub Runner Public IP
id: ip
uses: haythem/public-ip@v1.3
- name: Configure AWS Credentials
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: Authorize Runner IP in Security Group
run: |
aws ec2 authorize-security-group-ingress \
--group-id ${{ env.SECURITY_GROUP_ID }} \
--protocol tcp \
--port 22 \
--cidr ${{ steps.ip.outputs.ipv4 }}/32 || echo "IP already exists"
- name: Check Application Health
uses: appleboy/ssh-action@v1.2.0
with:
host: ${{ vars.AWS_EC2_HOST }}
username: ${{ vars.AWS_EC2_USER }}
key: ${{ secrets.AWS_EC2_SSH_KEY }}
script: |
curl -fsSL "http://localhost:${{ env.APPLICATION_PORT }}/test.html"
- name: Revoke Runner IP from Security Group
run: |
aws ec2 revoke-security-group-ingress \
--group-id ${{ env.SECURITY_GROUP_ID }} \
--protocol tcp \
--port 22 \
--cidr ${{ steps.ip.outputs.ipv4 }}/32 || echo "Failed to remove IP"
---
코드 블록 설명
Deploy Docker Image
- GitHub 저장소에서 최신 코드를 받아옵니다.
- Docker 이미지를 빌드하여 Docker Hub에 푸시합니다.
- name: Deploy Docker Image
uses: appleboy/ssh-action@v1.2.0
with:
host: ${{ vars.AWS_EC2_HOST }}
username: ${{ vars.AWS_EC2_USER }}
key: ${{ secrets.AWS_EC2_SSH_KEY }}
script: |
git clone https://${{ vars.MY_GITHUB_USERNAME }}:${{ secrets.MY_GITHUB_TOKEN }}@github.com/${{ vars.MY_GITHUB_USERNAME }}/${{ vars.MY_GITHUB_NAMESPACE }}.git
cd ${{ vars.MY_GITHUB_NAMESPACE }}
git pull origin main || { echo "Failed to pull changes"; exit 1; }
echo "<html><head><meta charset='UTF-8'></head><body>날짜 및 시간 : $(date '+%Y년 %m월 %d일 %H시 %M분 %S초')</body></html>" > test.html
echo "${{ secrets.DOCKERHUB_TOKEN }}" | docker login -u "${{ vars.DOCKERHUB_USERNAME }}" --password-stdin
docker buildx rm mybuilder || true
docker buildx create --name mybuilder --driver docker-container --use
docker buildx build \
--platform linux/amd64,linux/arm64 \
--tag anti1346/playground:latest \
--push .
Deploy Docker Image
- Docker Compose를 사용하여 기존 컨테이너를 중단하고 새로운 이미지를 풀한 후 실행합니다.
- name: Deploy Docker Image
uses: appleboy/ssh-action@v1.2.0
with:
host: ${{ vars.AWS_EC2_HOST }}
username: ${{ vars.AWS_EC2_USER }}
key: ${{ secrets.AWS_EC2_SSH_KEY }}
script: |
mkdir -p ${{ env.EC2_CONTAINER_BASE_DIR }}
cd ${{ env.EC2_CONTAINER_BASE_DIR }}
docker compose down -v
docker rmi -f $(docker images | grep ${{ env.DOCKER_IMAGE_NAME }} | awk '{print $3}' | uniq) || true
docker pull anti1346/playground:latest
cat <<EOF > ${{ env.EC2_CONTAINER_BASE_DIR }}/docker-compose.yml
services:
${{ env.DOCKER_IMAGE_NAME }}:
image: anti1346/playground:latest
container_name: ${{ env.DOCKER_IMAGE_NAME }}
restart: unless-stopped
ports:
- "${{ env.APPLICATION_PORT }}:${{ env.APPLICATION_PORT }}"
EOF
docker compose up -d || echo "Failed to start the container"
Check Application Health
- 애플리케이션의 건강 상태를 확인하기 위해 curl을 사용하여 test.html 페이지에 접근합니다. 해당 페이지는 build 작업에서 날짜 및 시간이 포함된 HTML로 생성됩니다.
- name: Check Application Health
uses: appleboy/ssh-action@v1.2.0
with:
host: ${{ vars.AWS_EC2_HOST }}
username: ${{ vars.AWS_EC2_USER }}
key: ${{ secrets.AWS_EC2_SSH_KEY }}
script: |
curl -fsSL "http://localhost:${{ env.APPLICATION_PORT }}/test.html"
AWS EC2에서 NGINX 애플리케이션을 Docker로 빌드하여 Docker Hub에 푸시하고 해당 이미지를 사용하여 애플리케이션을 배포하며 최종적으로 애플리케이션의 상태를 확인하는 GitHub Actions 워크플로우를 자동화하는 과정입니다.
728x90
반응형
'퍼블릭 클라우드' 카테고리의 다른 글
Spring Boot 애플리케이션을 Docker 이미지로 빌드하고 Docker Hub에 배포한 뒤 AWS EC2에 배포하는 방법 (0) | 2025.01.18 |
---|---|
AWS 보안 그룹에 GitHub Actions IP 추가 및 삭제하는 방법 (0) | 2025.01.11 |
SecureCRT 클라이언트에서 AWS EC2 서버에 SSH 접속 시 오류가 발생하는 경우 (0) | 2025.01.10 |
Spring Boot 프로젝트를 GitHub Actions를 이용해 배포 자동화하는 방법 (0) | 2025.01.09 |
Amazon RDS에서 스냅샷 복원을 하는 방법 (0) | 2025.01.06 |