[우테코 6기 레벨3] Github Actions CD - 개발 서버 도커 배포

새양·2024년 7월 23일
0

우테코 6기 일기장

목록 보기
14/16
post-thumbnail

목표

  • be/devPR MergeSpring Boot 프로젝트를 도커 이미지로 빌드 후 Docker Hub private repo 에 배포

  • 개발 서버에서 빌드한 이미지와 docker-compose.yaml 다운로드 후 변경이 필요한 컨테이너만 재시작

개발서버 CD

Self-hosted Runner

우테코에서 제공받은 EC2 는 모든 외부 IP 에서 SSH 접속이 불가능 합니다.

따라서 EC2self-hosted runner 를 설치하여 GithubPolling 방식으로 명령을 수행해야하는지 지속적으로 물어보며 트리거가 될 경우 작업을 실행하는 구성을 해야합니다.

Setting > Actions > Runner 에서 New self-hosted runner 버튼을 클릭하여 운영체제와 아키텍쳐를 선택 후 알려주는 명령어 대로 실행합니다.

파일 생성

.github/workflows/be-cd-dev.yaml 파일 생성

각 job 의 설명을 아래와 같아서 프로젝트 상황 별 필요한 부분만 가져다 사용하면 됩니다!

  • Build
    • Checkout Repository 코드 가져오기
    • Set up JDK 21 자바 설치
    • Cache Gradle 그래들 캐싱
    • Add execute permissions 그래들 실행 권한 부여
    • Build 스프링 빌드
    • Test and Create OAS 테스트 및 API Spec 생성
    • Create bootJar 실행 가능한 jar 파일 생성
    • Build Docker image 도커 이미지 빌드
    • Login to Docker Hub 도커 허브 로그인
    • Push Docker image 도커 허브로 업로드
    • Upload docker-compose 깃헙 액션 저장소에 컴포즈 파일 업로드
  • Deploy
    • Set up environment variables 중요 변수 추출
    • Download docker-compose 깃헙 액션 저장소에서 컴포즈 파일 다운로드
    • Rename downloaded file 파일명에 -dev 제거
    • Login to Docker Hub 도커 허브 로그인
    • Pull latest Docker images 도커 이미지 다운로드
    • Restart docker compose 컴포즈 재시작 (무중단 배포 필요)
    • Clean up unused Docker images 이전 도커 이미지 제거
name: Backend CD Develop

on:
  push:
    branches:
      - be/dev

concurrency:
  group: ${{ github.ref }}
  cancel-in-progress: true

jobs:
  build:
    runs-on: ubuntu-latest
    environment: test

    steps:
      - name: Checkout Repository
        uses: actions/checkout@v4

      - name: Set up JDK 21
        uses: actions/setup-java@v4
        with:
          java-version: 21
          distribution: temurin
          cache: gradle

      - name: Cache Gradle
        uses: actions/cache@v4
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper
          key: ${{ runner.os }}-gradle-${{ hashFiles('**/build.gradle') }}
          restore-keys: |
            ${{ runner.os }}-gradle-

      - name: Add execute permissions
        working-directory: ./backend
        run: chmod +x ./gradlew

      - name: Build
        working-directory: ./backend
        run: ./gradlew build -x test -x bootJar

      - name: Test and Create OAS
        env:
          JASYPT_PASSWORD: ${{ secrets.JASYPT_PASSWORD }}
        working-directory: ./backend
        run: ./gradlew copyOasToSwagger

      - name: Create bootJar
        working-directory: ./backend
        run: ./gradlew bootJar

      - name: Build Docker image
        working-directory: ./backend
        run: |
          docker build \
          -f Dockerfile-dev \
          -t ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.DOCKERHUB_IMAGE_NAME }}:dev \
          .

      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Push Docker image
        run: docker push ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.DOCKERHUB_IMAGE_NAME }}:dev

      - name: Upload docker compose
        uses: actions/upload-artifact@v4
        with:
          name: docker-compose
          path: ./backend/src/main/resources/docker-compose-dev.yaml
          if-no-files-found: error

  deploy:
    needs: build
    runs-on: [self-hosted, dev]
    environment: dev

    steps:
      - name: Set up environment variables
        run: |
          cd ~/${{ secrets.DOCKERHUB_IMAGE_NAME }}
          echo "MYSQL_DATABASE=${{ secrets.MYSQL_DATABASE }}" > .env
          echo "MYSQL_ROOT_PASSWORD=${{ secrets.MYSQL_ROOT_PASSWORD }}" >> .env
          echo "JASYPT_PASSWORD=${{ secrets.JASYPT_PASSWORD }}" >> .env

      - name: Download docker compose
        uses: actions/download-artifact@v4
        with:
          name: docker-compose
          path: ~/${{ secrets.DOCKERHUB_IMAGE_NAME }}

      - name: Rename downloaded file
        run: |
          cd ~/${{ secrets.DOCKERHUB_IMAGE_NAME }}
          mv docker-compose-dev.yaml docker-compose.yaml

      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Pull latest Docker images
        run: docker compose -f ~/${{ secrets.DOCKERHUB_IMAGE_NAME }}/docker-compose.yaml pull

      - name: Restart docker compose
        run: |
          cd ~/${{ secrets.DOCKERHUB_IMAGE_NAME }}
          docker compose up -d

      - name: Clean up unused Docker images
        run: docker image prune -af

테스트

CD 스크립트는 default branch 를 변경할 필요가 없으며 on > push > branches 에 현재 작업 중인 브랜치 be/feat/000 을 추가하여 Push 할 때 마다 스크립트가 잘 작동하는지 Github 홈페이지 Actions 탭에서 확인하는 식으로 반복하는 것이 좋습니다.

마무리

테스트가 모두 잘 되어 배포가 될 경우 on > push > branchesfeat 브랜치를 제거하여 PR 을 작성합니다!

profile
안녕, 세상!

0개의 댓글