이번에는 저번에 이어서 docker 을 활용해서 컨테이너 기반 프로젝트에서 주로 사용되는 CI/CD 를 구축해보려고 한다.
1. EC2에 Docker 설치
먼저 EC2에 Docker 설치하고 ECR 을 세팅해야 하는데 아래 명령어를 통해 Docker을 설치한다.
sudo apt-get update && \
sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common && \
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - && \
sudo apt-key fingerprint 0EBFCD88 && \
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" && \
sudo apt-get update && \
sudo apt-get install -y docker-ce && \
sudo usermod -aG docker ubuntu && \
sudo curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose && \
sudo chmod +x /usr/local/bin/docker-compose && \
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
완료된 이후 docker 와 docker compose 설치가 잘 되었는지 확인을 위해
"docker -v; docker compose version" 를 입력하면 아래와 같이 버전을 확인할 수 있다.

2. EC2에 ECR 권한 세팅
두번째로 ECR에 이미지를 전달하기 위해서는 ECR에 접근할 수 있는 권한이 있어야 한다.
Github Actions 에 IAM 사용자를 지정해줘야 하는데, 여기서 IAM 사용자는
AWS 외부의 리소스가 AWS 리소스를 사용할 때 주로 사용되고 반대로 IAM 역할은
특정 AWS 리소스가 다른 AWS 리소스를 사용할 때 생성하는 역할을 한다.
1. ECR 에서 리포지토리를 생성
ECR > 프라이빗 레지스트리 > 리포지토리에서 [리포지토리 생성] 버튼을 눌러 생성한다.

2. EC2용 IAM 역할을 생성
IAM > 역할 > 역할 생성에서 사용 사례에 EC2를 입력한 뒤 권한 정책에서
AmazonEC2ContainerRegistryFullAccess 정책을 추가하고, 역할 이름은 ec2-ecr-role 으로 지정한다.


3. EC2인스턴스에 역할 연결
EC2에서 인스턴스 체크박스 선택하고 우측 상단 작업 > 보안 > IAM 역할 수정 버튼을 클릭한다.
이후 IAM 역할 드롭다운에서 ec2-ecr-role 을 선택한 뒤 IAM 역할 업데이트 버튼을 클릭한다.


4. Github Actions 용 IAM 사용자 생성
다음으로 IAM 콘솔에서 엑세스 관리/사용자에서 사용자 생성 버튼을 선택하고 이름 입력 후 다음 클릭한다.
이후 권한 설정에서 직접 정책 연결을 선택하고 AmazonEC2ContainerRegistryFullAccess 를 추가한다.

다음으로 생성된 사용자를 클릭하여 상세 화면으로 접근한 뒤 보안 자격 증명을 누른 뒤
엑세스 키 만들기 버튼을 누르고 엑세스 키 모범 사례 및 대안에서 CLI 선택 후 설명 태그는 생략한다.


그러면 아래와 같은 페이지가 나오는데 여기에서 노출되는 엑세스 키를 반드시 따로 저장해두어야 한다.

5. Github 저장소에 키 등록
다음으로 이렇게 저장된 값을 Github 의 Settings 에서 New repository secret 을 선택하고
아까 저장한 값을 각각 AWS_ACCESS_KEY_ID 와 AWS_SECRET_ACCESS_KEY 에 설정한다.

3. EC2에 CI/CD 구축
나는 amazon-ecr-credential-helper 를 사용해서 인증을 진행해볼 예정이다.
먼저 sudo apt install amazon-ecr-credential-helper 명령어를 입력하여 설치하고
home 디렉토리 안에 docker 라는 폴더를 만든 뒤 config.json 파일을 생성한다.

{
"credsStore": "ecr-login"
}
그리고 yml 파일을 아래와 같이 고치는데, 여기에서 "steps.login-ecr.outputs.registry" 는
ECR 의 프라이빗 리포지토리에서 URL 에 포함되는 내용이다.
name : Deploy To EC2
on:
push:
branches:
- main
jobs:
Deploy-Job:
runs-on: ubuntu-latest
steps:
- name: Github Repository 파일 불러오기 with dockerfile
uses: actions/checkout@v4
- name: JDK 17 설치
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: application.properties 파일 생성 및 EC2 배포
run: |
echo "${{ secrets.APPLICATION_PROPERTIES }}" > src/main/resources/application.properties
- name: Test and Build with Gradle
run: ./gradlew clean build
- name: AWS Recource 에 접근하도록 AWS credentials 설정
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ap-northeast-2
- name: ECR 로그인
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
# 현재 파일에 있는 Dockerfile 기반으로 rusharp-server이라는 이름의 도커 이미지 생성
- name: Docker Image 생성
run: docker build -t rusharp-server .
# docker tag 명령어를 사용해서 도커 이미지에 태그를 설정 (레포지토리 URI/rusharp-server:latest)
- name: Docker Image 태그 설정
run: docker tag rusharp-server ${{ steps.login-ecr.outputs.registry }}/rusharp-server:latest
# AWS ECR에 도커 이미지 푸시
- name: Docker Image ECR에 푸시
run: docker push ${{ steps.login-ecr.outputs.registry }}/rusharp-server:latest
# EC2에 SSH로 접속하여 기존 컨테이너 종료 및 삭제, 새 이미지로 컨테이너 실행
- name: SSH로 EC2에 접속하기
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.EC2_HOST }} # EC2의 주소
username: ${{ secrets.EC2_USERNAME }} # EC2 접속 username
key: ${{ secrets.EC2_PRIVATE_KEY }} # EC2의 Key 파일의 내부 텍스트
script_stop: true # 아래 script 중 실패하는 명령이 하나라도 있으면 실패로 처리
script: |
# 기존에 실행중인 컨테이너가 있으면 종료 및 삭제
sudo docker rm -f rusharp-server || true
# 만약 도커 이미지가 없으면 pull 받아오기
docker pull ${{ steps.login-ecr.outputs.registry }}/rusharp-server:latest
# 도커 컨테이너 실행
docker run -d --name rusharp-server -p 8080:8080 ${{ steps.login-ecr.outputs.registry }}/rusharp-server:latest
그리고 최상위 파일에 Dockerfile 을 생성하고 아래와 같은 내용을 입력한다.
# Eclipse Temurin의 OpenJDK 17 Alpine 이미지를 베이스로 사용
FROM eclipse-temurin:17-jdk-alpine
# build/libs/ 경로에 있는 JAR 파일을 컨테이너의 project.jar로 복사
COPY ./build/libs/*SNAPSHOT.jar /project.jar
# 컨테이너가 시작될 때 JAR 파일을 실행
ENTRYPOINT ["java", "-jar", "/project.jar"]
이후 git push 를 진행하면 이렇게 성공하면 해당 링크로 접근하여 웹페이지도 확인 가능하다.

이렇게 Docker와 GitHub Actions, AWS ECR을 연동하여 컨테이너 기반의 CI/CD 파이프라인 구축을 진행해봤다.
초기 설정 과정은 다소 복잡하지만, 코드 푸시만으로 배포가 자동화되어 개발 생산성이 크게 향상될 수 있다.
무엇보다 Docker 을 사용하기 전에는 기존 로컬 개발 환경과 EC2서버 환경 등이 달라서
배포할 때마다 예기치 못한 에러가 발생할 수도 있었는데, Docker 을 사용함으로써
애플리케이션 실행에 필요한 모든 환경을 격리시켜, 환경 일관성을 높이고 에러 위험을 줄일 수 있었다.
또한, EC2 서버에 각종 라이브러리를 일일이 설치하고 관리할 필요 없이 Docker 만 설치되어 있다면
언제 어디서든지 동일한 애플리케이션을 즉시 수정할 수 있어 인프라 관리가 훨씬 간결하다.
'Server&load > CI CD' 카테고리의 다른 글
| container 기반의 프로젝트 CI/CD 구축 방법 (Docker) (0) | 2026.01.11 |
|---|---|
| 일반 프로젝트에서 쓰이는 CI/CD 구축 방식 (1) | 2026.01.10 |
| 개인 프로젝트에서 쓰이는 CI/CD 구축 방법 실습하기 (0) | 2025.12.28 |
| 프로젝트 특징별 주로 사용되는 CI/CD 구축 방법 (0) | 2025.06.25 |
| Github Actions 기본 문법 및 사용 방법 정리 (0) | 2025.06.24 |