[TIL] CI/CD (2)

오진선·2024년 4월 3일
0

TIL

목록 보기
27/29

Today I Learned

배포 여정기

1. 배포를 위한 선택들

1) Github Actions? Jenkins?

결정의 이유

  • CI/CD 구축을 위한 시간이 부족하고 빠른 pipeline 구축이 필요함
  • Github을 사용하고 있음
  • 하나의 서버를 사용하는 소규모 프로젝트

결정

  • 배울 것이 많은 Jenkins보다는 Github Actions를 채택

2) AWS? NCP?

결정의 이유

  • ncp는 저번 프로젝트에서 다뤄보았는데 10만 크레딧이 생각보다 일찍 차감
  • 자료가 많이 부족함
  • 아직은 익숙하지 않기 때문에 문제가 발생할 확률이 높음

결정

  • 조금은 더 익숙한 AWS로 클라우드 서비스 채택

3) Elastic Beanstalk? EC2?

결정의 이유

  • Elastic Beanstalk의 경우 자동화를 통해 더 간편하게 처리할 수 있다는 장점이 있지만 세부적인 사용자 정의 설정이 불가능함
  • EC2의 경우 서버 내에서 사용자의 제어가 자유롭고 확장이 가능

결정

  • 복잡한 커스텀 사항이 없기는 하지만 차후를 대비해 EC2에서 설정을 해주기로 결정

4) ECR 사용? Docker로만 관리?

결정의 이유

  • ECR은 docker의 container 관리를 편리하게 해주는 Registry로 버저닝에 효과적
  • 프로젝트의 주제가 게임이기 때문에 버전 관리가 필요

결정

  • ECR을 사용해 관리하기로 결정

5) Nginx도 Docker로 관리? 서버에 install?

결정의 이유

  • mysql과 redis의 경우 애플리케이션과 직접적인 연관이 있음
  • nginx의 경우 애플리케이션과는 독립적
  • 애플리케이션과 서버를 분리하여 관리하는 경우 docker가 다운되어도 서버 유지가능
  • 보안리스크 분산 가능

결정

  • nginx는 docker로 띄우지 않고 ec2 서버에 직접 설치

6) https? http?

결정의 이유

  • HTTPS는 HTTP에 SSL/TLS 보안 프로토콜을 추가하여 데이터를 암호화
  • 데이터의 보안과 무결성 보장
  • SEO에서 더 높은 평가 가능

결정

  • Https 적용

2. 배포

험난하고도 길었던ㅠ 배포 여정...

1) Github Actions 적용

name: Deploy to AWS EC2

on:
  push:
    branches:
      - develop
  pull_request:
    branches:
      - develop
# 사용할 인프라의 이름을 변수 형태로 저장
jobs:
  build-and-deploy:
    # 실행 환경 지정
    runs-on: ubuntu-latest

    # Task sequence 명시
    steps:
      - uses: actions/checkout@v2
      - name: Set up JDK 17
        uses: actions/setup-java@v1
        with:
          java-version: 17

      # Github Actions 워크플로우가 실행되는 가상 환경내에 application-dev 설정
      - name: Generate application-secret.yml
        run: |
          echo "${{ secrets.APPLICATION_SECRET_CONTENT }}" > ./src/main/resources/yml/application-secret.yml

      # Github Actions 워크플로우가 실행되는 가상 환경내에 application-dev 설정
      - name: Generate application-oauth.yml
        run: |
          echo "${{ secrets.APPLICATION_OAUTH }}" > ./src/main/resources/yml/application-oauth.yml

      # Gradle 빌드 할 때, 이미 저장한 데이터를 캐싱하여 빌드시 이를 사용하도록함.
      - name: Gradle Caching
        uses: actions/cache@v3
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper
          key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
          restore-keys: |
            ${{ runner.os }}-gradle-

      # Github Actions 워크플로우 가상환경이 grdlew 실행할 수 있도록 ./gradlew 파일에 실행 권한을 부여
      - name: Grant execute permission for gradlew
        run: chmod +x ./gradlew
        shell: bash

      # Gradle build (Test 제외)
      - name: Build with Gradle
        run: ./gradlew clean build -x test

      # Docker 이미지 빌드
      - name: Build Docker image
        run: docker build -f Dockerfile -t myapp:${{ github.sha }} .

      # ECR에 docker image push
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ap-northeast-2

	  # ECR에 Login
      - name: Log in to Amazon ECR
        run: |
          aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin ${{ secrets.AWS_ECR_REPOSITORY_URL }}

	  # ECR에 이미지 push
      - name: Push image to Amazon ECR
        run: |
          docker tag myapp:${{ github.sha }} ${{ secrets.AWS_ECR_REPOSITORY_URL }}:latest
          docker push ${{ secrets.AWS_ECR_REPOSITORY_URL }}:latest
	  
      # EC2에 ssh로 접속 후 ECR에서 docker로 이미지 pull & docker container 
      - name: Deploy to EC2
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.HOST }}
          username: ${{ secrets.USERNAME }}
          key: ${{ secrets.SSH_KEY }}
          port: 22
          script: |
            sudo docker login -u AWS -p $(aws ecr get-login-password --region ap-northeast-2) ${{ secrets.AWS_ECR_REPOSITORY_URL }}
            sudo docker pull ${{ secrets.AWS_ECR_REPOSITORY_URL }}:latest
            sudo docker-compose down
            sudo docker-compose up -d
            sudo docker image prune -f

2) AWS 설정

  • IAM 사용자 등록 후 권한 설정
  • EC2 인스턴스 생성 후 보안 인바운드 규칙 설정 (당신이 Spring이라면 꼬옥 t2.small로...)
  • 가비아에서 구입한 도메인 Route53에 등록 후 EC2 인스턴스 연결
  • Elastic Container Registry에 리포지토리 생성

3) Nginx 설치 후 Proxy 설정 & HTTPS 적용

  • nginx 설치 후 Certbot으로 Let's Encrypt SSL 인증서 발급, 적용
  • Proxy 설정
profile
₍ ᐢ. ̫ .ᐢ ₎

0개의 댓글