Github Action 이용한 CI/CD Spring Server 무중단 배포 (feat: Synology Nas)

2024. 6. 5. 22:48Spring

프로젝트를 배포할 때 도커 이미지를 수동으로 도커 허브로 push 하고 다시 시놀로지 나스 도커로 poll 해오는 과정이 매우 귀찮기 때문에 깃허브에 올린 코드를 자동으로 재배포하는 파이프라인을 구축하게 되었습니다.

 

목차

  1. 시놀로지 나스 ssh 접속 키 발급
  2. gradle.yml 파일 생성
시놀로지 나스 ssh 접속 키 발급

 

시놀로지 나스 도커에 GitHub Actions를 이용해 배포하려면 SSH 접속을 위한 키가 필요합니다. 우선 SSH 접속을 허용하고 나스에 접속합니다. Windows에서는 Putty를 이용해 접속하고, Mac에서는 터미널에서 SSH를 통해 접속합니다.

접속하는 시놀로지 나스 계정은 도커 제어 권한이 있어야 합니다. 계정의 루트 디렉토리에 .ssh 폴더를 생성하고 해당 폴더에 접속합니다.

 

Nas Key 발급 (.ssh 폴더 내에 생성) 및 private key 확인

ssh-keygen //키 생성
cat id_rsa // private key 값 확인 후 복사 후 github action secret에 저장

 

private key 값을 전체 복사하여 GitHub Action Secret에 저장해야 합니다. 암호화된 부분만 복사하지 않도록 주의합니다.

 

 

gradle.yml 파일 생성

 

GitHub 프로젝트에 접속한 후, Action으로 이동하여 Java with Gradle을 클릭하고 Configure를 클릭합니다. 자동으로 생성되는 코드를 그대로 커밋합니다.

이후, gradle.yml 파일을 개별 환경에 맞게 작성합니다.

 

안보이면 Java with Gradle 검색한다.

 

gradle.yml 파일에 작성해야되는 코드는 개별 환경에 맞춰서 작성해주면 됩니다.

 

  1. gradle 권한 설정
  2. 깃허브에 올리지 않은 properties 생성 (DB_URL, DB_PW, API_KEY...)
  3. Build JAR
  4. JAR 저장
  5. 도커 이미지 빌드
  6. 도커 로그인
  7. 도커 이미지 허브에 전송
  8. 시놀로지 나스 SSH 접속
  9. 시놀로지 나스 도커 재배포

여기서 주의 깊게 봐야되는건 시놀로지 private key 발급과 ssh 접속 허용하는 부분이다. 발급 받을 때 사용자가 도커 관련 읽기/쓰기 권한이 있는지 확인해야 합니다.

 

name: CI/CD using GitHub Actions & Docker

on:
  push:
    branches: [ "master" ]
  pull_request:
    branches: [ "master" ]

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read

    steps:
      - uses: actions/checkout@v4

      - name: Set up JDK 17
        uses: actions/setup-java@v4
        with:
          java-version: '17'
          distribution: 'temurin'

	// Gradle 권한 부여
      - name: Grant execute permission for Gradle
        run: chmod +x ./gradlew

	// 깃허브에 업로드 하지 않은 은닉 폴더 GitHub Action Sercert에 별도 저장된 값을 불러와 동일한 위치에 properties 생성
      - name: Create application-api.properties
        run: |
          echo "properties에서 사용하는 이름=${{ secrets.Action에 저장된 값의 name }}" >> src/main/resources/application-api.properties

      - name: Display application-api.properties content for verification
        run: cat src/main/resources/application-api.properties

      - name: Build JAR
        run: ./gradlew clean build -x test

      - name: Set artifact
        run: echo "artifact=$(ls ./build/libs)" >> $GITHUB_ENV

      - name: Build Docker image
        run: |
          docker build -t 도커 이름/이미지 이름:latest .
          echo "DOCKER_IMAGE=도커 이름/이미지 이름:latest" >> $GITHUB_ENV

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

      - name: Push Docker image to Docker Hub
        run: docker push ${{ env.DOCKER_IMAGE }}

	// 시놀로지 SSH 접속
      - name: Set up SSH connection
        uses: webfactory/ssh-agent@v0.5.3
        with:
        // 이전에 발급받은 private key 값을 "그대로" 저장한 것을 호출
          ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}

      - name: SSH into Synology NAS and deploy
        env:
          NAS_USERNAME: ${{ secrets.NAS_USERNAME }}
          NAS_PASSWORD: ${{ secrets.NAS_PASSWORD }}
          NAS_HOST: ${{ secrets.NAS_HOST }}
        run: |
          sshpass -p "$NAS_PASSWORD" ssh -o StrictHostKeyChecking=no $NAS_USERNAME@$NAS_HOST << EOF
            docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }}
            docker pull ${{ env.DOCKER_IMAGE }}
            docker stop 이미지 이름 || true
            docker rm 이미지 이름 || true
            docker run -d --name 이미지 이름 \
              -p 8080:8080 ${{ env.DOCKER_IMAGE }}
          EOF

 

Secret key 등록

 

GitHub Actions에서 New repository secret을 이용해 상단에서 생성한 properties와 도커 아이디, 비밀번호 등 공개되면 안되는 값들을 저장해두고 ${{ secrets.이름 }} 형태로 호출하여 사용합니다.

 

 

참고 블로그

 

https://jd6186.github.io/NAS_CI_CD/

 

[DevOps] Synology NAS, Github Action으로 CI/CD(자동배포) 구축 | Noah

주니어 개발자의 소소한 기술블로그 💻 Archive에서 더 많은 글을 확인하실 수 있습니다. @github.

jd6186.github.io