
GitHub Actions로 CI/CD 구축 #4에서는 Docker와 AWS ECR을 사용하여 컨테이너 기반의 프로젝트에서 많이 사용하는 비교적 소규모 프로젝트에 적합한 CI/CD 구축 방법을 소개했습니다.
이번 글에서는 Docker, ECR, S3, CodeDeploy, EC2를 사용하여 컨테이너 기반 및 확장성을 고려한 프로젝트에서 많이 사용하는 CI/CD 구축 방법을 알아보도록 하겠습니다.
이 방식은 여러 대의 컨테이너 기반 서버를 운영하거나, 무중단 배포가 중요한 서비스를 구축할 때 주로 활용됩니다.
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에 업로드된 배포 파일 경로 지정
tar -czvf 명령어를 사용하여 appspec.yml과 scripts 디렉토리를 포함한 프로젝트 배포 파일을 압축(tar.gz 형식)합니다.aws s3 cp 명령어를 사용해, 생성된 tar.gz 파일을 지정된 S3 버킷(s3://test-server)으로 업로드합니다.aws deploy create-deployment 명령어를 사용해 CodeDeploy를 통해 S3에 업로드된 파일을 EC2로 배포합니다.CodeDeployDefault.AllAtOnce)에 따라 배포를 자동으로 수행합니다.이 방식은 S3와 CodeDeploy를 중간 매개체로 활용하여 EC2에 코드를 배포하는 것이 특징입니다. 이를 통해 EC2에 직접 접속하거나 복잡한 스크립트를 작성하지 않고도, 보다 효율적이고 확장 가능한 배포 환경을 구축할 수 있습니다.
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 "--------------- 서버 배포 끝 -----------------"
echo "--------------- 서버 배포 시작 -----------------"
docker stop test-server || true
docker rm test-server || true
docker stop test-server|| true를 추가해 에러를 무시합니다.docker rm test-servertest-server인 컨테이너)를 삭제합니다.docker pull 381492107073.dkr.ecr.ap-northeast-2.amazonaws.com/test-server:latest
test-server:latest 태그가 붙은 최신 Docker 이미지를 가져옵니다.381492107073.dkr.ecr.ap-northeast-2.amazonaws.com은 ECR 레지스트리 주소이며, 해당 레지스트리에 저장된 이미지를 가져옵니다.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 이미지입니다. 이전 단계에서 가져온 최신 이미지를 사용합니다.echo "--------------- 서버 배포 끝 -----------------"
수정한 코드를 깃허브에 push한 후 결과를 확인해보니 다음과 같이 배포가 성공한 것을 확인할 수 있었습니다.

