본문 바로가기
개발 기록

2024-05-26(배포, docker-compose, Spring Cloud, Github Actions)

by 진꿈청 2024. 5. 26.

이번 캡스톤 프로젝트에서 배포를 맞게 되었고

Spring Cloud를 처음 사용해보며 여러 작업을 하고 있다.

docker-compose를 이용하여 컨테이너가 같은 도커 네트워크 환경을 공유할 수 있도록 하였고

 

MSA의 장점에 걸맞게 스케일 아웃했을 때 서버가 중단되지 않고 배포가 되는
무중단 배포를 위해 Makefile를 제작하였다.

(필자의 생각에 근거하여 Makefile을 작성하였기 때문에 이게 옳은 방법이라곤 할 수 없다.)

 

 

Makefile 초안(지금은 조금 다름)

.PHONY: up down

up:
        docker-compose pull
        docker-compose up -d zookeeper kafka discovery-service gateway-service redis-user mysql-user user-service redis-community mariadb-community community-service mongo-chat chat-service openvidu sig-service
        docker image prune -f

down:
        docker-compose down

user-update:
        docker-compose up -d user-service-temp
        docker-compose pull
        sleep 10
        docker-compose up -d user-service
        sleep 60
        container_id=$(docker ps | grep user-service-temp | grep -v 'CONTAINER' | awk '{print $1}')
        docker exec -i "$container_id" kill -15 $(docker exec -i "$container_id" lsof -i | grep java | awk 'NR==1 {print $2}')
        docker rm -f "$container_id"
        docker image prune -f

community-update:
        docker-compose up -d community-service-temp
        docker-compose pull
        sleep 10
        docker-compose up -d community-service
        sleep 60
        container_id=$(docker ps | grep community-service-temp | grep -v 'CONTAINER' | awk '{print $1}')
        docker exec -i "$container_id" kill -15 $(docker exec -i "$container_id" lsof -i | grep java | awk 'NR==1 {print $2}')
        docker rm -f "$container_id"
        docker image prune -f

chat-update:
        docker-compose up -d chat-service-temp
        docker-compose pull
        sleep 10
        docker-compose up -d chat-service
        sleep 60
        container_id=$(docker ps | grep chat-service-temp | grep -v 'CONTAINER' | awk '{print $1}')
        docker exec -i "$container_id" kill -15 $(docker exec -i "$container_id" lsof -i | grep java | awk 'NR==1 {print $2}')
        docker rm -f "$container_id"
        docker image prune -f

state-update:
        docker-compose up -d state-service-temp
        docker-compose pull
        sleep 10
        docker-compose up -d state-service
        sleep 60
        container_id=$(docker ps | grep state-service-temp | grep -v 'CONTAINER' | awk '{print $1}')
        docker exec -i "$container_id" kill -15 $(docker exec -i "$container_id" lsof -i | grep java | awk 'NR==1 {print $2}')
        docker rm -f "$container_id"
        docker image prune -f

sig-update:
        docker-compose up -d sig-service-temp
        docker-compose pull
        sleep 10
        docker-compose up -d sig-service
        sleep 60
        container_id=$(docker ps | grep sig-service-temp | grep -v 'CONTAINER' | awk '{print $1}')
        docker exec -i "$container_id" kill -15 $(docker exec -i "$container_id" lsof -i | grep java | awk 'NR==1 {print $2}')
        docker rm -f "$container_id"
        docker image prune -f

notification-update:
        docker-compose up -d notification-service-temp
        docker-compose pull
        sleep 10
        docker-compose up -d notification-service
        sleep 60
        container_id=$(docker ps | grep notification-service-temp | grep -v 'CONTAINER' | awk '{print $1}')
        docker exec -i "$container_id" kill -15 $(docker exec -i "$container_id" lsof -i | grep java | awk 'NR==1 {print $2}')
        docker rm -f "$container_id"
        docker image prune -f


그리고 오늘은 Github Actions에 사용될 YAML 파일을 각 서비스에 맞게 설정을 했다.

 

 

내가 제작한 Community-Service의 Github Actions YAML 예시

name: CommunityService CI/CD

on:
  pull_request:
    branches:
      - 'BE/dev'

jobs:
  build-and-push:
    runs-on: ubuntu-latest
    if: github.event.pull_request.head.ref == 'BE/community'
    steps:
      - name: Checkout Repository
        uses: actions/checkout@v2
          
      - name: Cache Gradle dependencies
        uses: actions/cache@v2
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper
          key: gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
          restore-keys: |
            gradle-

      - name: Set up JDK 17
        uses: actions/setup-java@v2
        with:
          java-version: '17'
          distribution: 'temurin'
      - name: Grant execute permission for gradlew
        run: chmod +x src/backend/community-service/gradlew

      - name: Project Build
        env:
          jasypt.encryptor.password: ${{ secrets.JASYPT_PASSWORD }}
        working-directory: ./src/backend/community-service
        run: ./gradlew clean build
        shell: bash

      - name: Docker Login
        run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin

      - name: Docker Image Build
        run: docker build -t ${{ secrets.DOCKER_USERNAME }}/community-service:1.0 ./src/backend/community-service

      - name: Docker Image Push
        run: docker push ${{ secrets.DOCKER_USERNAME }}/community-service:1.0

      - name: GCP 인스턴스 접속 및 무중단 배포
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.GCP_HOST }}
          username: ${{ secrets.GCP_USERNAME }}
          key: ${{ secrets.GCP_SSH_KEY }}
          script: |
            cd /script
            make community-update

 

각 서비스 별로 BE/community와 같은 네이밍으로 브랜치를 만들었는데
이곳에 git push가 일어날 때마다 배포를 하기엔 너무 잦은 배포가 이루어질 것 같고

그렇다고 배포용 브랜치를 하나 더 만들기엔 너무 많은 브랜치가 생긴다.

따라서, 코드 리뷰를 통해 PR을 하는 우리 캡스톤 그라운드 룰에 맞게 PR 작업 시 배포가 되도록 하였다.

모놀리식이 아닌 MSA 방식이므로 어떤 브랜치에서 PR이 일어났는지를 확인하고 배포를 해야 하므로,

    if: github.event.pull_request.head.ref == 'BE/community'

 

위와 같은 내용을 넣어주었다.

 

사용한 클라우드 서비스는 GCP(Google Cloud Platform)의 GCE이다.

 

 

맘 같아선 Grafana와 프로메테우스 또는 로키를 추가하고 싶은데
시간이 될지는 모르겠다.

'개발 기록' 카테고리의 다른 글

정보처리기사 합격 (2024.06.18)  (0) 2024.06.25
2024-05-11  (0) 2024.05.11
2024-05-03  (0) 2024.05.03
2024-04-21  (0) 2024.04.21
2024-04-17  (0) 2024.04.17