본문 바로가기

퍼블릭 클라우드

AWS EC2에서 NGINX 애플리케이션을 Docker 이미지로 빌드하고 Docker Hub에 업로드하는 방법

반응형

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
반응형