CICD

CICD란? 설정하기

whdudev 2025. 3. 30. 22:54

✅ CICD란?

CI/CD는 지속적 통합(CI)과 지속적 제공/배포(CD)를 의미하는 IT 용어입니다.

 

지속적 통합(CI) : 코드를 자동으로 합치고, 문제가 없는지 계속 확인(테스트,빌드)하는 과정
지속적 배포(CD): 코드를 자동으로 서버에 배포하는 과정

 

 

✅ CICD를 왜 사용하는가?

 

코드의 수정이 있을 때마다 각 서버에 접속하여 빌드, 테스트, 배포를 하는 것은 번거롭고 시간이 많이 소요되는 비효율적인 과정이므로 

Github Actions를 통한 CI/CD 파이프라인을 자동화하려고 합니다.

 

 

 

✅어떤 기술들로 구현할 수 있는가?

CICD는 젠킨스, github action, git labs 등으로 구현하는데

아래와 같은 특징들이 있다. Jenkins는 자체 호스팅이 필요하다는 점에서 매력적으로 다가오지 않았고, 현재 프로젝트에서 GitLab을 사용하지 않으므로 이 역시 제외 시켰다. 결국 우리는 GitHub Actions로 구현하기로 정했다.

 

  Jenkins GitHub Actions GitLab 
설치 방식 자체 호스팅 필요 GitHub 내장 GitLab 내장
설정 파일 Jenkinsfile (DSL 기반) YAML (.github/workflows/) YAML (.gitlab-ci.yml)
확장성 플러그인으로 무한 확장 가능 GitHub Marketplace 활용 GitLab 자체 기능 활용
호스팅 옵션 온프레미스, 클라우드 모두 가능 GitHub 제공 Runner GitLab 제공 Runner, 자체 Runner
러닝 커브 높음 (설치 & 설정 복잡) 낮음 (GitHub 내장, YAML 기반) 중간 (GitLab 내장, YAML 기반)
Git과의 통합 GitHub, GitLab, Bitbucket 등 지원 GitHub 전용 GitLab 전용
사용 추천 환경 기업 환경, 복잡한 CI/CD 구축 필요할 때 GitHub 기반 프로젝트 GitLab 사용 환경, 자체 호스팅 필요할 때

 

 

어떤 방식으로 구현할 것 인가?

 

✅ 장점

  • Docker 기반으로 서비스를 운영할 때, 가장 간단하게 구성할 수 있는 인프라 구조이다.

✅ 단점

  • 무중단 배포를 구현하거나 여러 EC2 인스턴스에 배포를 해야 하는 상황이라면, 직접 Github Actions에 스크립트를 작성해서 구현해야 한다. 직접 구현을 해보면 알겠지만 생각보다 꽤 복잡하다.

✅ 이 방법은 언제 주로 쓰는 지

  • 컨테이너 기반으로 인프라를 구성했을 때 이 방법을 많이 활용한다.
  • 서버를 여러 대 운영하고 있지 않을 정도의 소규모 프로젝트 일 때 주로 활용한다.

실제 구현 방법 설명

도커파일 (local에서는 application-local.yml을 사용한다.)

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


프로젝트/.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-prod.yml 파일 만들기
        run: echo "${{ secrets.APPLICATION_PROPERTIES}}" > ./src/main/resources/application-prod.yml

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

      - name: AWS Resources에 접근할 수 있게 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: 현재 디렉토리 파일 확인
        run: ls -al

      - name: 현재 경로
        run: pwd

      - name: Dockerfile 실제 위치 확인
        run: find . -name Dockerfile

      - name: Docker 이미지를 생성
        run: docker build --no-cache -t auctify-server .
        ##      - name: Docker 이미지를 생성
        #        run: docker build -t auctify-server .
      - name: Docker 이미지에 Tag 붙이기
        run: docker tag auctify-server ${{ steps.login-ecr.outputs.registry }}/auctify_server:latest

      - name: Docker 이미지 푸시
        run: docker push ${{ steps.login-ecr.outputs.registry }}/auctify_server:latest
      - name: Docker 이미지 ID 출력
        run: docker images | grep auctify-server
      - name: 컨테이너 로그 출력 (에러 디버깅용)
        run: docker logs auctify_server || echo "컨테이너가 아직 안 떠 있음"
      - name: SSH로 EC2에  접속하기
        uses: appleboy/ssh-action@v1.0.3
        with:
          host: ${{ secrets.EC2_HOST}}
          username: ${{ secrets.EC2_USERNAME}}
          key: ${{ secrets.EC2_PRIVATE_KEY }}
          port: 22  # 여기에 추가
          script_stop: true
          script: |
            docker stop auctify_server || true
            docker rm auctify_server || true
            docker pull ${{ steps.login-ecr.outputs.registry }}/auctify_server:latest
            echo "✅ EC2 이미지 목록 확인"
            docker images | grep auctify_server
            echo "✅ Docker 컨테이너 실행"
            docker run -d --name auctify_server -p 8080:8080 ${{ steps.login-ecr.outputs.registry }}/auctify_server:latest
            echo "✅ 컨테이너 상태 확인"
            docker ps -a
            echo "✅ 컨테이너 로그 출력"
            docker logs auctify_server || echo "컨테이너 로그 없음  "

AWS에서 설정

ec2만들기 (rds도 만들자)

IAM에 권한 추가

  • AmazonEC2ContainerRegistryFullAccess 권한 추가하기
  •  

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 버전 확인

ECR(Elastic Container Registry) 만들기

Ubuntu일 경우

$ sudo apt update
$ sudo apt install amazon-ecr-credential-helper

IAM Role을 활용해 EC2가 ECR에 접근할 수 있게 권한 부여하기

  • EC2에 연결되어 있는 IAM Role에 AmazonEC2ContainerRegistryFullAccess 정책 추가하기

Github Secrets and Variables

APPLICATION_PROPERTIES : allication-prod.yml 설정파일 그대로

AWS_ACCESS_KEY_ID : iam id

AWS_SECRET_ACCESS_KEY : iam pw

EC2_HOST : ec2주소

EC2_PRIVATE_KEY : pem

EC2_USERNAME : ubuntu 우분투일경우