컨테이너 기반의 프로젝트에서 많이 쓰는 CI/CD 구축 방법 (Docker)

유동우·2025년 1월 13일
0

CI/CD

목록 보기
5/5
post-thumbnail

언제 사용?

  • 컨테이너 기반으로 인프라를 구성했을 때
  • 서버를 여러대 운영하지 않는 소규모 프로젝트 일 경우

작업 흐름

1️⃣ Ubuntu에서 Docker, Docker Compose 설치

$ 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 -v # Docker 버전 확인
$ docker compose version # Docker Compose 버전 확인

2️⃣ Github Actions의 IAM에 권한 추가

IAM의 사용자 권한 정책에 AmazonEC2ContainerRegistryFullAccess 를 추가한다


3️⃣ ECR(Elastic Container Registry) 생성
aws 검색창에 elastic container registry에 들어가서 instagram-server 로 이름을 설정하여 Private Repository를 생성한다

❗️AWS ECR 이란?
도커 이미지들 저장하고 있는곳을 Docker hub 라고 한다
깃허브는 프로젝트 코드들을 저장하고 있는 저장소인 것처럼..

AWS ECR도 마찬가지로 도커의 이미지를 저장하고 보관하는 용도이다
ECR과 Docker hub의 차이는 같은 역할이지만 다른 브랜드라고 이해하자


4️⃣ Docker 기반으로 프로젝트 수정

Dockerfile

FROM eclipse-temurin:17-jdk-alpine
COPY ./build/libs/*SNAPSHOT.jar project.jar
ENTRYPOINT ["java", "-jar", "project.jar"]

5️⃣ EC2가 3️⃣에서 생성한 Private ECR에 접근할 수 있도록 세팅
Amazon ECR Docker Credential Helper 설치하기
amazon-ecr-credential-helper

# Ubuntu일 경우
$ sudo apt update
$ sudo apt install amazon-ecr-credential-helper

우분투 서버에서 Configuration 설정
~ 경로에서 .docker라는 폴더 만들고, config.json 파일 만들어서 작성

~/.docker/config.json

{
	"credsStore": "ecr-login"
}

6️⃣ Docker 기반 CI/CD 구축
Github Actions 파일 작성
.github/workflows/deploy.yml**

name: Deploy To EC2

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Github Repository 파일 불러오기
        uses: actions/checkout@v4

      - name: JDK 17버전 설치
        uses: actions/setup-java@v4
        with:
          distribution: temurin
          java-version: 17

      - name: application.yml 파일 만들기
        run: echo "${{ secrets.APPLICATION_PROPERTIES }}" > ./src/main/resources/application.yml

      - name: 테스트 및 빌드하기
        run: ./gradlew clean build

      - name: AWS Resource에 접근할 수 있게 AWS credentials 설정
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-region: ap-northeast-2
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

      - name: ECR에 로그인하기
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v2
        
      - name: Docker 이미지 생성
        run: docker build -t instagram-server .

      - name: Docker 이미지에 Tag 붙이기
        run: docker tag instagram-server ${{ steps.login-ecr.outputs.registry }}/instagram-server:latest

      - name: ECR에 Docker 이미지 Push하기
        run: docker push ${{ steps.login-ecr.outputs.registry }}/instagram-server:latest

      - name: SSH로 EC2에 접속하기
        uses: appleboy/ssh-action@v1.0.3
        with:
          host: ${{ secrets.EC2_HOST }}
          username: ${{ secrets.EC2_USERNAME }}
          key: ${{ secrets.EC2_PRIVATE_KEY }}
          script_stop: true
          script: |
            docker stop instagram-server || true
            docker rm instagram-server || true
            docker pull ${{ steps.login-ecr.outputs.registry }}/instagram-server:latest
            docker run -d --name instagram-server -p 8080:8080 ${{ steps.login-ecr.outputs.registry }}/instagram-server:latest

코드 설명
ECR에 로그인하는 과정부터 설명

ECR에 로그인

  • AWS ECR에 로그인하여 Docker 이미지를 푸시할 수 있도록 인증
  • login-ecr의 outputs.registry에 ECR 레지스트리 주소(예: 123456789012.dkr.ecr.ap-northeast-2.amazonaws.com)를 저장

    박스로 가린 필드 전체 URI가 ECR 레지스트리의 주소이다

Docker 이미지 생성

  • . 키워드를 통해 DockerFile에 정의된 애플리케이션과 종속성을 기반으로 이미지를 빌드
  • docker build -t instagram-server .
    • 현재 디렉토리(.)를 기준으로 이미지를 빌드 및 instagram-server 라는 태그를 생성

Docker 이미지에 태그 붙이기
이미지를 ECR에 푸시하기 위해 ECR 레지스트리 주소를 포함한 태그를 추가하기 위함

  • docker tag: 기존 이미지 (intagram-server)에 새로운 태그를 추가
  • ${{ steps.login-ecr.outputs.registry }}/instagram-server:latest
  • 위 태그 형식 풀이: {레지스트리 주소}/instagram-server:latest

ECR에 Docker 이미지 푸시
태그가 붙은 Docker 이미지를 ECR 레지스트리에 업로드

  • docker push: 이미지를 지정된 ECR 주소로 푸시
  • 결과적으로 ECR에 instagram-server:latest 이미지가 저장된다

SSH로 EC2에 접속 및 Docker 실행
EC2 인스턴스에 SSH를 통하여 접속하여 Docker 명령어를 실행

  • 기존 컨테이너 정리하는 코드
docker stop instagram-server || true
docker rm instagram-server || true
  • docker pull: Docker 이미지 Pull
  • docker run: 새로운 컨테이너를 실행
  • -d: 백그라운드 모드로 실행
  • -name instagram-server: 컨테이너 이름을 instagram-server 로 지정
  • -p 8080:8080: 로컬 8080 포트를 컨테이너의 8080 포트에 매칭

배포 흐름

  1. 이미지 빌드 및 태깅 작업:
  • Github Actions가 Docker 이미지를 빌드하여 ECR에 업로드
  1. 이미지 배포:
  • EC2에 SSH로 접속하여 최신 이미지를 Pull
  • 기존 컨테이너 종료 및 새로운 컨테이너 실행
profile
효율적이고 꾸준하게

0개의 댓글

관련 채용 정보