GitHub Actions로 CI/CD 구축 #5

artp·2024년 12월 23일

CI/CD

목록 보기
8/9
post-thumbnail

GitHub Actions로 CI/CD 구축 #4에서는 Docker와 AWS ECR을 사용하여 컨테이너 기반의 프로젝트에서 많이 사용하는 비교적 소규모 프로젝트에 적합한 CI/CD 구축 방법을 소개했습니다.

이번 글에서는 Docker, ECR, S3, CodeDeploy, EC2를 사용하여 컨테이너 기반 및 확장성을 고려한 프로젝트에서 많이 사용하는 CI/CD 구축 방법을 알아보도록 하겠습니다.

이 방식은 여러 대의 컨테이너 기반 서버를 운영하거나, 무중단 배포가 중요한 서비스를 구축할 때 주로 활용됩니다.

소스코드 수정

deploy.yml

EC2에 직접 접속하는 방식이 아닌, 프로젝트 배포 파일을 압축하여 S3로 업로드한 후, CodeDeploy를 활용하여 EC2에 배포하는 방식으로 코드를 수정합니다.

name: Deploy To EC2  # 워크플로 이름 정의, Actions 탭에서 이 이름으로 표시됨

on:
  # main 브랜치에 코드가 푸시되었을 때 워크플로가 실행됨
  push:
    branches:
      - main

jobs:
  deploy:
    # GitHub Actions에서 제공하는 최신 Ubuntu 환경 사용
    runs-on: ubuntu-latest
    steps:
      # GitHub 저장소의 코드를 가져옵니다.
      - name: GitHub Repository 파일 불러오기
        uses: actions/checkout@v4

      # Java 애플리케이션 실행을 위해 JDK 17을 설치합니다.
      - name: JDK 17버전 설치
        uses: actions/setup-java@v4
        with:
          distribution: temurin  # Temurin JDK 사용
          java-version: 17  # Java 17 버전 설치

      # GitHub Secrets에서 가져온 설정값으로 application.yml 파일을 생성합니다.
      - name: application.yml 파일 만들기
        run: echo "${{ secrets.APPLICATION_PROPERTIES }}" > ./src/main/resources/application.yml

      # Gradle을 사용해 코드를 테스트하고 빌드합니다.
      - name: 테스트 및 빌드하기
        run: ./gradlew clean build

      # AWS 서비스에 접근할 수 있도록 자격 증명을 설정합니다.
      - name: AWS Resource에 접근할 수 있게 AWS credentials 설정
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-region: ap-northeast-2  # AWS 리전 (서울 리전)
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}  # AWS Access Key
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}  # AWS Secret Key

      # AWS Elastic Container Registry(ECR)에 로그인합니다.
      - name: ECR에 로그인하기
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v2

      # Docker 이미지를 'test-server' 이름으로 빌드합니다.
      - name: Docker 이미지 빌드
        run: docker build -t test-server .  # Dockerfile 기반으로 이미지를 빌드합니다.

      # 빌드된 Docker 이미지에 ECR 레지스트리를 기반으로 태그를 추가합니다.
      - name: Docker 이미지에 Tag 붙이기
        run: docker tag test-server ${{ steps.login-ecr.outputs.registry }}/test-server:latest  # 레지스트리 주소와 함께 태그를 생성합니다.

      # 태그된 Docker 이미지를 AWS ECR로 푸시합니다.
      - name: ECR에 Docker 이미지 Push
        run: docker push ${{ steps.login-ecr.outputs.registry }}/test-server:latest  # Docker 이미지를 ECR에 업로드합니다.

      # 프로젝트 배포 파일을 tar.gz 형식으로 압축합니다.
      - name: 압축하기
        run: tar -czvf $GITHUB_SHA.tar.gz appspec.yml scripts  # 배포 관련 파일(appspec.yml, scripts)을 압축합니다.

      # 압축된 파일을 S3에 업로드합니다.
      - name: S3에 프로젝트 폴더 업로드
        run: aws s3 cp --region ap-northeast-2 ./$GITHUB_SHA.tar.gz s3://mytestserverbucket/$GITHUB_SHA.tar.gz  # S3 버킷에 tar.gz 파일을 업로드합니다.

      # CodeDeploy를 활용하여 EC2 인스턴스에 프로젝트를 배포합니다.
      - name: CodeDeploy를 활용하여 EC2에 프로젝트 코드 배포
        run: aws deploy create-deployment
          --application-name test-server # CodeDeploy 애플리케이션 이름
          --deployment-group-name Production # 배포 그룹 이름
          --deployment-config-name CodeDeployDefault.AllAtOnce # 배포 설정 이름
          --s3-location bucket=mytestserverbucket,bundleType=tgz,key=$GITHUB_SHA.tar.gz  # S3에 업로드된 배포 파일 경로 지정

1. 프로젝트 배포 파일 압축:

  • tar -czvf 명령어를 사용하여 appspec.ymlscripts 디렉토리를 포함한 프로젝트 배포 파일을 압축(tar.gz 형식)합니다.

2. 압축 파일을 S3에 업로드:

  • AWS CLI의 aws s3 cp 명령어를 사용해, 생성된 tar.gz 파일을 지정된 S3 버킷(s3://test-server)으로 업로드합니다.

3. CodeDeploy를 활용하여 EC2에 배포:

  • aws deploy create-deployment 명령어를 사용해 CodeDeploy를 통해 S3에 업로드된 파일을 EC2로 배포합니다.
  • CodeDeploy는 지정된 배포 그룹배포 설정(CodeDeployDefault.AllAtOnce)에 따라 배포를 자동으로 수행합니다.

이 방식은 S3와 CodeDeploy를 중간 매개체로 활용하여 EC2에 코드를 배포하는 것이 특징입니다. 이를 통해 EC2에 직접 접속하거나 복잡한 스크립트를 작성하지 않고도, 보다 효율적이고 확장 가능한 배포 환경을 구축할 수 있습니다.

start-server.sh

start-server.sh를 다음과 같이 수정합니다.

#!/bin/bash

echo "--------------- 서버 배포 시작 -----------------"
docker stop test-server || true
docker rm test-server || true
docker pull 381492107073.dkr.ecr.ap-northeast-2.amazonaws.com/test-server:latest
docker run -d --name test-server -p 8080:8080 381492107073.dkr.ecr.ap-northeast-2.amazonaws.com/test-server:latest
echo "--------------- 서버 배포 끝 -----------------"

1. 서버 배포 시작 메시지

echo "--------------- 서버 배포 시작 -----------------"
  • 배포 과정 시작을 알리는 메시지를 출력합니다.

2. 기존 컨테이너 중지 및 삭제

docker stop test-server || true
docker rm test-server || true
  • docker stop test-server
    • 이름이 test-server인 기존 컨테이너를 중지합니다.
    • 만약 해당 컨테이너가 존재하지 않더라도, 스크립트가 종료되지 않도록 || true를 추가해 에러를 무시합니다.
  • docker rm test-server
    • 중지된 컨테이너(또는 이름이 test-server인 컨테이너)를 삭제합니다.
    • 컨테이너가 존재하지 않을 경우에도 에러를 무시합니다.

3. 최신 Docker 이미지 가져오기

docker pull 381492107073.dkr.ecr.ap-northeast-2.amazonaws.com/test-server:latest
  • AWS ECR에서 test-server:latest 태그가 붙은 최신 Docker 이미지를 가져옵니다.
  • 381492107073.dkr.ecr.ap-northeast-2.amazonaws.com은 ECR 레지스트리 주소이며, 해당 레지스트리에 저장된 이미지를 가져옵니다.

4. 새로운 컨테이너 실행

docker run -d --name test-server -p 8080:8080 381492107073.dkr.ecr.ap-northeast-2.amazonaws.com/test-server:latest
  • docker run: 새로운 컨테이너를 실행합니다.
  • -d: 컨테이너를 백그라운드 모드에서 실행합니다.
  • --name test-server: 컨테이너 이름을 test-server로 설정합니다.
  • -p 8080:8080: 호스트의 포트 8080을 컨테이너의 포트 8080에 매핑합니다. 이를 통해 외부에서 컨테이너로 접근할 수 있습니다.
  • 381492107073.dkr.ecr.ap-northeast-2.amazonaws.com/test-server:latest: 실행할 Docker 이미지입니다. 이전 단계에서 가져온 최신 이미지를 사용합니다.

5. 서버 배포 완료 메시지

echo "--------------- 서버 배포 끝 -----------------"
  • 배포 과정 종료를 알리는 메시지를 출력합니다.

결과 확인

수정한 코드를 깃허브에 push한 후 결과를 확인해보니 다음과 같이 배포가 성공한 것을 확인할 수 있었습니다.

  • 워크플로 실행 성공
  • 배포 성공
profile
donggyun_ee

0개의 댓글