빙응의 공부 블로그

[CI/CD]AWS + EC2 + Docker 배포해보기 본문

CICD

[CI/CD]AWS + EC2 + Docker 배포해보기

빙응이 2024. 9. 6. 16:21

📝개요

혼자 진행한 프로젝트를 본격적으로 배포해봅시다!

📝[CI] GitHub Actions 작성하기 

저의 프로젝트는 Gradle, SpringBoot, Java이기에 GitHub Action에서 Gradle을 골랐습니다.

 

name: CI/CD

on:
  push:
    branches:
      - main  # main 브랜치에 푸시될 때 이 워크플로우가 트리거됩니다.

jobs:
  build:
    runs-on: ubuntu-latest 
    permissions:
      contents: read  # 리포지토리의 내용을 읽을 수 있는 권한을 부여합니다.

    steps:
    - name: Checkout code
      uses: actions/checkout@v4  # 리포지토리의 코드를 체크아웃합니다.

    - name: Set up JDK 17
      uses: actions/setup-java@v4  # JDK 17을 설정합니다.
      with:
        java-version: '17'  # 사용할 JDK 버전을 설정합니다.
        distribution: 'temurin'  # AdoptOpenJDK의 Temurin 배포판을 사용합니다.

    - name: Gradle Caching
      uses: actions/cache@v3  # Gradle 캐싱을 설정합니다.
      with:
        path: |
          ~/.gradle/caches
          ~/.gradle/wrapper
        key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}  
        restore-keys: |
          ${{ runner.os }}-gradle-  # 캐시 복원 키를 설정합니다.

    - name: Create application.yml from secret
      run: |
        mkdir -p ./src/main/resources  # 필요한 디렉토리를 생성합니다.
        echo "${{ secrets.APPLICATION }}" | base64 --decode > ./src/main/resources/application.yml
      shell: bash  # bash 쉘에서 스크립트를 실행합니다.

    - name: Make gradlew executable
      run: chmod +x ./gradlew  # gradlew 파일에 실행 권한을 부여합니다.

    - name: Build with Gradle Wrapper
      run: ./gradlew build  # Gradle Wrapper를 사용하여 프로젝트를 빌드합니다.


    - name: Build with Gradle Wrapper
      run: ./gradlew build

또한 GitHub Secret을 통해 Application.yml을 저장하여 동적으로 생성하였습니다. 

자세한 사항은 요기

[GitHub Actions]Github actions과 Github Secrets (tistory.com)

 

[GitHub Actions]Github actions과 Github Secrets

📝개요서비스를 개발하면서 DB 계정 정보, JWT 시크릿 키, AWS IAM 정보 등 외부에 절대 공개해서는 안되는 값들을 Application.yml에 저장한다.... 우리는 통상 개발을 하면서 yml 파일에 모든 것을 저

quddnd.tistory.com

 

이제 CD에 대해 할건데 자세한 플로우는 다음과 같습니다.

📝[CD] AWS EC2와 도커 설정하기

EC2 인스턴스를 만드는 것은 많은 자료가 있으므로 생략하겠습니다. 

 

📌EC2에 도커 설치하기

SSH를 이용해서 일단 EC2에 접속한 다음 도커를 설치합시다.!!

sudo yum update -y //시스템 패키지 업데이트
sudo amazon-linux-extras install docker -y // 도커 설치
sudo service docker start //도커 시작

sudo systemctl enable docker //도커 자동시작 설정
docker --version //도커 버전확인

📌EC2와 Docker 엑세스를 위한 키 설정하기 

EC2의 SSH 키와 Docker의 AccessKey + username을 GitHub Secret에 저장해줍니다.

 

 

📝 Dockerfile 설정 및 workflow 다시 설정하기 

프로젝트 폴더 내부에 Dockerfile을 만들어줍니다. 

FROM amazoncorretto:17
# Amazon Corretto 17 이미지를 사용 (Java 17 환경)

ARG JAR_FILE=build/libs/*.jar
# 빌드된 JAR 파일의 경로를 지정하는 변수 (Gradle 빌드의 기본 출력 경로)

COPY ${JAR_FILE} app.jar
# 빌드된 JAR 파일을 컨테이너의 app.jar로 복사

ENTRYPOINT ["java","-jar","/app.jar"]
# 컨테이너가 시작될 때 app.jar 파일을 실행하도록 설정

RUN ln -snf /usr/share/zoneinfo/Asia/Seoul /etc/localtime
# 컨테이너의 타임존을 서울(Asia/Seoul)로 설정

 

📝Docker Compose 설정하기 

Docker compose란, 여러 개의 컨테이너를 정의하고 동시에 실행할 수 있도록 도와주는 도구이다.
이를 통해서 EC2에 배포된 도커 컨테이너를 자동으로 실행되게 할 수 있다.

📌EC2에 Docker Compose 설치

sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)"
-o /usr/local/bin/docker-compose

sudo chmod +x /usr/local/bin/docker-compose //도커 바이너리 실행 권한 부여
docker-compose --version

 

📌Docker Compose 파일 설정하기 

version: '3'
services:
  app:
    image: quddaz/myapp:latest
    ports:
      - "80:8080"
    environment:
      - TZ=Asia/Seoul
    restart: always

간단하게 도커 파일을 설정한 것이다. 해당 파일은 도커의 이미지 컨테이너를 지정해서 실행할 수 있게 해준다.

해당 파일이 있는 곳에서 아래의 명령어를 통해 시작할 수 있다.

docker-compose up -d

 

 

📝Github Actions Workflow 작성

name: Deploy to EC2  # 워크플로우 이름

# 워크플로우 트리거 설정
on:
  push:
    branches:
      - main  # main 브랜치에 푸시될 때 워크플로우 실행

jobs:
  # Docker 이미지를 빌드하고 Docker Hub에 푸시하는 작업
  build-and-push-docker:
    runs-on: ubuntu-latest  # 최신 우분투 환경에서 실행

    steps:
    - name: Check out code
      uses: actions/checkout@v3  # GitHub 저장소의 코드를 체크아웃

    - name: Log in to Docker Hub
      uses: docker/login-action@v2  # Docker Hub에 로그인
      with:
        username: ${{ secrets.DOCKER_USERNAME }}  # GitHub Secrets에 저장된 Docker Hub 사용자명
        password: ${{ secrets.DOCKER_PASSWORD }}  # GitHub Secrets에 저장된 Docker Hub 비밀번호

    - name: Build and push Docker image
      run: |
        docker build -t your-dockerhub-username/your-image-name:latest .  # Docker 이미지를 빌드
        docker push your-dockerhub-username/your-image-name:latest  # Docker Hub에 이미지를 푸시

  # EC2에 배포하는 작업
  deploy-to-ec2:
    runs-on: ubuntu-latest  # 최신 우분투 환경에서 실행
    needs: build-and-push-docker  # 이 작업은 Docker 이미지를 푸시한 후에 실행됨

    steps:
    - name: Set up SSH
      uses: webfactory/ssh-agent@v0.5.4  # SSH 에이전트를 설정하여 EC2에 접근
      with:
        ssh-private-key: ${{ secrets.EC2_SSH_KEY }}  # GitHub Secrets에 저장된 EC2 인스턴스 접근용 SSH 키

    - name: Install Docker Compose on EC2
      run: |
        ssh -o StrictHostKeyChecking=no ec2-user@${{ secrets.EC2_HOST }} << 'EOF'
        sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
        sudo chmod +x /usr/local/bin/docker-compose
        EOF
      # EC2 인스턴스에서 Docker Compose 설치 및 실행 권한 부여

    - name: Deploy Docker Compose on EC2
      run: |
        ssh -o StrictHostKeyChecking=no ec2-user@${{ secrets.EC2_HOST }} << 'EOF'
        cd /path/to/your/app  # 프로젝트 경로로 이동
        docker-compose down  # 기존 Docker Compose 서비스를 종료
        docker-compose pull  # 최신 이미지를 풀
        docker-compose up -d  # 백그라운드에서 Docker Compose 서비스 시작
        EOF
      # EC2에서 Docker Compose로 애플리케이션을 업데이트하고 재시작

 

 

해당 워크플로우는 아래의 순서를 따른다.

  • main 브랜치에 푸시될 경우 실행
# 워크플로우 트리거 설정
on:
  push:
    branches:
      - main  # main 브랜치에 푸시될 때 워크플로우 실행
  • Doker 이미지를 만들고 Docker Repository에 푸시 
  # Docker 이미지를 빌드하고 Docker Hub에 푸시하는 작업
  build-and-push-docker:
    runs-on: ubuntu-latest  # 최신 우분투 환경에서 실행

    steps:
    - name: Check out code
      uses: actions/checkout@v3  # GitHub 저장소의 코드를 체크아웃

    - name: Log in to Docker Hub
      uses: docker/login-action@v2  # Docker Hub에 로그인
      with:
        username: ${{ secrets.DOCKER_USERNAME }}  # GitHub Secrets에 저장된 Docker Hub 사용자명
        password: ${{ secrets.DOCKER_PASSWORD }}  # GitHub Secrets에 저장된 Docker Hub 비밀번호

    - name: Build and push Docker image
      run: |
        docker build -t your-dockerhub-username/your-image-name:latest .  # Docker 이미지를 빌드
        docker push your-dockerhub-username/your-image-name:latest  # Docker Hub에 이미지를 푸시
  • EC2를 연결하게 배포 
  # EC2에 배포하는 작업
  deploy-to-ec2:
    runs-on: ubuntu-latest  # 최신 우분투 환경에서 실행
    needs: build-and-push-docker  # 이 작업은 Docker 이미지를 푸시한 후에 실행됨

    steps:
    - name: Set up SSH
      uses: webfactory/ssh-agent@v0.5.4  # SSH 에이전트를 설정하여 EC2에 접근
      with:
        ssh-private-key: ${{ secrets.EC2_SSH_KEY }}  # GitHub Secrets에 저장된 EC2 인스턴스 접근용 SSH 키
  • EC2 인스턴스에서 Docker Compose 작업 
   - name: Install Docker Compose on EC2
      run: |
        ssh -o StrictHostKeyChecking=no ec2-user@${{ secrets.EC2_HOST }} << 'EOF'
        sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
        sudo chmod +x /usr/local/bin/docker-compose
        EOF
      # EC2 인스턴스에서 Docker Compose 설치 및 실행 권한 부여

    - name: Deploy Docker Compose on EC2
      run: |
        ssh -o StrictHostKeyChecking=no ec2-user@${{ secrets.EC2_HOST }} << 'EOF'
        cd /path/to/your/app  # 프로젝트 경로로 이동
        docker-compose down  # 기존 Docker Compose 서비스를 종료
        docker-compose pull  # 최신 이미지를 풀
        docker-compose up -d  # 백그라운드에서 Docker Compose 서비스 시작
        EOF
      # EC2에서 Docker Compose로 애플리케이션을 업데이트하고 재시작

정상 작동되고 맞는 퍼블릭 IP에 접속이 가능하면 성공이다.!!

'CICD' 카테고리의 다른 글

[GitHub Actions]Github actions과 Github Secrets  (2) 2024.09.03