Github Action을 활용한 Docker,SpringBoot CI/CD

Danny·2023년 11월 1일

ASAC

목록 보기
7/8

Intro

매번 새로운 커밋이 발생할 때마다 서버에 새로운 버전으로 업로드하고, 기존에 실행 중이던 프로세스를 종료한 후, 새로 업로드한 프로젝트를 실행하는 일련의 과정은 상당히 번거로웠다.

그래서 Github Action을 활용한 SpringBoot 프로젝트의 CI/CD 파이프라인 구축 방법에 대해 알아볼것.

이번 글의 목표는 main 브랜치에 push가 발생하는 경우 자동으로 서버에 배포되도록 하는 파이프라인을 구축하는 것.

프로젝트 생성

기본 Coupang ERD 프로젝트로 활용 할 계획이지만,
프로젝트를 기본적으로 생성해보자.


실행 테스트

http://localhost:9000/test/log

성공!

Github 저장소에 push

이제 새로 만든 프로젝트를 commit 후 Github 저장소에 push까지 해줍니다.

git add .
git commit -m "Commit message"

커밋 후에는 새로운 저장소를 생성

Github.com에서 저장소 생성

git remote add origin git@github.com:ShanePark/ci-cd-example.git
git branch -M main
git push -u origin main


기초 작업

Docker

회원가입후 레파지토리 생성

  • 이때 적용한 레파지토리 이름은 나중에도 사용하니 꼭 기억하자

  1. Github Actions 시 실행될 프로세스를 담은 yml 파일 만들기

파이프라인 생성

  1. 인텔리제이에서 코드를 작성 후, Github으로 Push.

  2. Github에서 조건을 만족할 경우, Github Actions 실행.
    (main branch에 코드가 Push, Pull Request될 경우로 설정함.)

Github Actions는 미리 작성해 둔 .yml 파일의 내용 대로 프로세스가 진행됨.

  • 빌드
  • 도커 repository에 이를 push
  • ssh로 서버에서 도커 이미지 pull 받아 실행
    • 이러한 프로세스를 만족하도록 파일을 작성

빌드

name: Java CI with Gradle

on:
  push:
    branches: [ "main" , "dev" ]
  pull_request:
    branches: [ "main" , "dev" ]

permissions:
  contents: read

jobs:
  build:

    runs-on: ubuntu-latest

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


      - name: make application.properties
        run: |
          cd ./src/main/resources
          touch ./application.properties
          echo "${{ secrets.APPLICATION_PROD }}" > ./application.properties
      - name: Grant execute permission for gradlew
        run: chmod +x gradlew

      - name: Build with Gradle
        run: ./gradlew build -x test

      - name: Docker build & push to docker repo
        run: |
          docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }}
          docker build -f Dockerfile -t ${{ secrets.DOCKER_REPO }}/lennnnon_cicd .
          docker push ${{ secrets.DOCKER_REPO }}/lennnnon_cicd
      - name: Deploy
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.REMOTE_IP }}
          username: ${{ secrets.REMOTE_SSH_ID }}
          key: ${{ secrets.PRIVATE_KEY }}
          port: ${{ secrets.REMOTE_SSH_PORT }}
          # 도커 작업
          script: |
            docker rm -f $(docker ps -qa)
            docker pull ${{ secrets.DOCKER_REPO }}/lennnnon_cicd
            docker-compose up -d
            docker image prune -f
  • REMOTE_IP : 대상 아이피
  • REMOTE_SSH_ID : 접속할 대상
  • REMOTE_SSH_KEY : Private Key
  • REMOTE_SSH_PORT : 포트번호 (22번이 일반적인 ssh 포트)

Secrets

  • Secrets and variables -> Actions
    • New Repository secret -> Key , Value 로 추가가능
    • EX: ${{ secrets.DOCKER_USERNAME }}

docker hub

이제 나는 로컬에서 작성후 git main 브랜치에 push가 발생하는 경우 Github Action -> Docker pull -> Aws서버에 자동으로 배포되도록 구성했다.

Tip
Public IP와 Host의 개념이 약하다면
설정해둔 aws인스턴스의 페스워드로도 ssh 접속가능
https://github.com/appleboy/ssh-action#setting-up-ssh-key


혹여나 Github Action에서 내 서버에 접속 했는지 확인하려면

- name: Deploy
      uses: appleboy/ssh-action@master
      with:
        host: ${{ secrets.REMOTE_IP }}
        username: ${{ secrets.REMOTE_SSH_ID }}
        key: ${{ secrets.PRIVATE_KEY }}
        port: ${{ secrets.REMOTE_SSH_PORT }}
        # 도커 작업
        script: |
          ls -la
          docker pull ${{ secrets.DOCKER_USERNAME }}/lennnnon_cicd:latest
          docker stop $(docker ps -a -q)
          docker run -d --log-driver=syslog -p 8080:8080 ${{ secrets.DOCKER_USERNAME }}/lennnnon_cicd:latest
          docker rm $(docker ps --filter 'status=exited' -a -q)
          docker image prune -a -
맨위에 ls -la를 해볼걸 추천
내 서버에 잘 접속했구나 뿌듯함을 느낌


실행화면

1. Push


2. Action

3. Build

4. Docker push @ pull

5. Deploy


👻EC2를 ubuntu최신버전으로 사용하면 일어날 오류

ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey], no supported methods remain

배포환경자동화에 도움이 되었기를 바라면서 추가로 도움이 될만한 링크들

github action 문법

해당게시물에서 설명한 레포지토리

이미지의 참고

0개의 댓글