[Reach Rich 개발기] GitHub Action, Docker를 사용한 CD 구축

wannabeking·2023년 3월 9일
0

Reach Rich 개발기

목록 보기
4/10

이번 시간에는 GitHub Action과 Docker를 사용한 CD를 구축하겠습니다.

Deploy는 EC2 Linux 서버에 진행됩니다.

하나의 서버에 각 Micro Service Container를 띄우는 형식의 MSA를 구축할 것이므로 앞단에 SSL(TLS)을 적용하고 각 컨테이너에 요청을 분배하는 무언가를 붙여야되지만, 우선 사용자 애그리거트를 개발할 예정이므로 다른 것은 신경쓰지 않고 User Micro Server를 띄우는 것을 목표로 합니다!



Secret

Secret에는 Docker Hub 계정 정보, EC2 정보가 필요합니다.

따라서 Secret에 해당 정보들을 추가합니다.

Docker를 이용한 CD를 구축할 것이므로 Docker Hub의 계정 정보를 입력하고, EC2 서버의 Host와 pem key를 저장합니다.



EC2

EC2 서버에선 Docker Hub를 통해 Pull 받아 이미지를 저장하고 docker-compose up 하기위해 Docker와 docker-compose를 설치합니다.

# Docker 설치
sudo yum install docker -y

# Docker 권한 추가
sudo chmod 666 /var/run/docker.sock

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

# docker-compose 권한 추가
sudo chmod +x /usr/local/bin/docker-compose

그리고 docker-compose.yml을 작성해줍니다.

우선 Reach Rich의 사용자 MS, MySQL, Redis를 설정해줍니다.

version: '3.7'

volumes:
  reach-rich-user-mysql-volume:
    external: true
  reach-rich-redis-volume:
    external: true

networks:
  redis-network:
    driver: bridge
    external: true

services:
  mysql:
    container_name: reach-rich-user-mysql
    image: mysql:latest
    ports:
      - 3306:3306
    volumes:
      - reach-rich-user-mysql-volume:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: [비밀번호]

  redis:
    container_name: reach-rich-redis
    hostname: reach-rich-redis
    image: redis:latest
    command: redis-server --port 6379
    ports:
      - 6379:6379
    volumes:
      - reach-rich-redis-volume:/data
    networks:
      - redis-network

  spring:
    container_name: reach-rich-user
    image: [CD 과정에서 Push할 Docker Hub Repository]
    expose:
      - 8080

위 과정에서 Volume과 Network가 이미 존재한 상태라면 에러가 발생하여 생성되지 않은채로 컨테이너가 띄워질 수 있으므로, 이미 있는 경우 external 옵션을 추가합니다.



dockerfile

Spring Application을 이미지로 빌드하기 위한 dockerfile을 작성합니다.

FROM openjdk:11
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]

간단한 설명을 덧붙이자면,

  • FROM : 베이스 이미지
  • ARG : 이미지 빌드 시 --build-arg로 넘길 인자
  • COPY : 이미지나 파일을 도커 이미지의 파일 시스템으로 복사
  • ENTRYPOINT : 이미지를 컨테이너로 띄울 때 항상 실행되어야 하는 명령

과 같습니다.



GitHub Action

이제 CD 스크립트를 작성할 차례입니다.

CI 스크립트를 작성했던 것처럼 Yaml 파일을 추가합니다.

name: CD

on:
  push:
    branches: [ "develop" ]

permissions:
  contents: read

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Setup JDK 11
        uses: actions/setup-java@v3
        with:
          java-version: '11'
          distribution: 'temurin'
          
      - 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-
      - name: Config File Write
        run: |
          # main 설정 파일 디렉토리로 이동
          cd ./src/main/resources
          
          # application-mysql.yml
          touch ./application-mysql.yml
          echo "${{secrets.CI_APPLICATION_MYSQL}}" >> ./application-mysql.yml
          
          # application-redis.yml
          touch ./application-redis.yml
          echo "${{ secrets.CI_APPLICATION_REDIS }}" >> ./application-redis.yml
        shell: bash

      - name: Gradle Build
        run: ./gradlew bootJar
        
      - name: Build Docker Image
        run: |
          docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }}
          docker build -t ${{ secrets.DOCKER_USERNAME }}/reach-rich-user .
          docker push ${{ secrets.DOCKER_USERNAME }}/reach-rich-user
      - name: Docker Pull & Compose Up
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.HOST }}
          username: ec2-user
          key: ${{ secrets.KEY }}
          script: |
            docker rm -f $(docker ps -qa)
            docker rmi ${{ secrets.DOCKER_USERNAME }}/reach-rich-user
            docker pull ${{ secrets.DOCKER_USERNAME }}/reach-rich-user
            docker-compose up -d

CD 과정은 CI 과정에서 추가적으로 jar로 빌드하여 Docker Image로 Push하고 EC2에서 해당 Image를 Pull 받아 docker-compose up을 백그라운드로 수행하는 과정이 추가됩니다.


길었던 과정을 마치고 develop에 Push or Merge하여 동작 테스트를 해봅시다!

GitHub Action이 성공적으로 수행된 것을 확인할 수 있습니다.

EC2에 들어가 확인해보면...

우선 모든 컨테이너가 잘 실행된 것을 확인할 수 있습니다.

마지막으로 Spring Application 컨테이너의 로그를 확인하면

성공적인 Run을 확인할 수 있습니다.


이제 어느정도 개발 환경 구축이 끝났으니, 본격적인 Spring Security와 Redis Session을 사용한 로그인/회원가입(인증/인가)를 개발할 예정입니다.

혼자서 서버 구축에 대한 모든 것을 해내려니 힘이 들지만... 그만큼 재밌기도 하네요ㅎㅎ (퇴근하고 플젝하면 언제 쉬지...? 😂)



profile
내일은 개발왕 😎

0개의 댓글