회고/개인프로젝트

[개인프로젝트] CI/CD 연동하기 *gitHube Actions

불광동 물주먹 2026. 2. 4. 13:59

1.도입배경

 

- 개인프로젝트 서버가 확장되면서, 백앤드서버, 채팅서버, 카프카 ,리액트 등
  코드 수정 후 배포의 번거로움이 늘어 CI/CD 연동의 필요성을 느꼈다.

https://gluonhq.com/use-github-actions-to-automate-your-gluon-build-and-release-cycle/

 

 

GitHub Actions는 별도의 도구 없이 GitHub 플랫폼 내에서 CI/CD 환경을 구축할 수 있게 해줍니다. 소스 코드 관리와 배포 자동화를 하나의 생태계에서 처리할 수 있다는 점이 가장 큰 장점이며, 이를 통해 개발 프로세스의 효율성을 극대화하고 팀원 간의 유기적인 협업을 가능하게 합니다.

 


2.파이프라인 

2-1. GitHub Actions: CI/CD 파이프라인 엔진.

 

GitHub Actions를 구성하는 5가지 핵심 요소

GitHub Actions는 단순히 명령어를 나열하는 것이 아니라, 체계적인 컴포넌트들로 이루어져 있습니다. 이해를 돕기 위해 **'자동화 레시피'**에 비유하여 정리해 보았습니다.

1. 워크플로우 (Workflow)

  • 개념: 전체적인 자동화 프로세스의 **'설계도'**입니다. (Jenkins의 Jenkinsfile과 유사한 역할)
  • 설정: 저장소의 .github/workflows 경로에 위치하며, YAML 형식으로 작성합니다.
  • 비유: "어떤 요리를 만들 것인가?"에 대한 전체 레시피 북이라고 할 수 있습니다.

2. 이벤트 (Event)

  • 개념: 워크플로우를 가동하는 **'방성쇠(Trigger)'**입니다.
  • 종류: 코드 push, pull_request부터 특정 시간에 실행되는 schedule, 수동으로 실행하는 workflow_dispatch 등이 있습니다.
  • 비유: "주문이 들어왔을 때(Push)" 요리를 시작하도록 신호를 주는 것과 같습니다.

3. 잡 (Job)

  • 개념: 워크플로우 내에서 처리되는 **'독립적인 작업 단위'**입니다.
  • 특징: 각 잡은 별도의 가상 환경(Runner)에서 실행되며, 필요에 따라 잡끼리 순서를 정하거나 의존성을 가질 수 있습니다.
  • 비유: "재료 손질", "조리하기"처럼 크게 나뉜 요리의 단계입니다.

4. 단계 (Step)

  • 개념: 잡 안에서 실제로 실행되는 **'개별 명령'**의 집합입니다.
  • 구성: 리눅스 쉘 명령어를 직접 입력하거나, 이미 만들어진 '액션(Action)'을 불러와서 실행합니다.
  • 비유: "양파 썰기", "물 500ml 붓기" 같은 구체적인 동작 하나하나를 의미합니다.

5. 액션 (Action)

  • 개념: 자주 사용되는 작업을 묶어놓은 **'재사용 가능한 모듈'**입니다.
  • 활용: 직접 만들 수도 있고, GitHub Marketplace에서 전 세계 개발자들이 공유한 액션(예: checkout, setup-java)을 가져다 쓸 수 있습니다.
  • 비유: "믹서기"나 "에어프라이어"처럼 복잡한 과정을 버튼 하나로 해결해 주는 주방 도구와 같습니다.

 

 


2-2.SSH/SCP (Appleboy Action): 서버 원격 제어 및 JAR 전송.

2-3.Ubuntu Systemd: 자바 프로세스의 서비스화 및 자동 재시작 관리.

3.과정 스크립트

 

1. 우분투에서 키 생성 

ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa_github


[설정 1] GitHub Secrets: HOST, USERNAME, SSH_KEY 등록

 

1.  GitHub Secrets 생성

 

2.work flow 

name: Java CI/CD (Main Backend)

on:
  push:
    branches: [ "master" ]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest

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

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

    - name: Setup Gradle
      uses: gradle/actions/setup-gradle@v4

    # [중요] 127 에러 해결을 위해 gradlew에 실행 권한 부여
    - name: Grant execute permission for gradlew
      run: chmod +x gradlew

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

    # 1. JAR 파일을 서버의 임시 경로(/var/www/backend)로 전송
    - name: Copy JAR to Server
      uses: appleboy/scp-action@v0.1.7
      with:
        host: ${{ secrets.HOST }}
        username: ${{ secrets.USERNAME }}
        key: ${{ secrets.SSH_KEY }}
        port: 2222
        source: "build/libs/ROOT.jar"
        target: "/var/www/backend"
        strip_components: 2
        overwrite: true

    # 2. 기존 파일 백업, 새 파일 삽입 및 서비스 재시작
    - name: Execute remote ssh commands
      uses: appleboy/ssh-action@v1.0.3
      with:
        host: ${{ secrets.HOST }}
        username: ${{ secrets.USERNAME }}
        key: ${{ secrets.SSH_KEY }}
        port: 2222
        script: |
          # 기존 ROOT.jar가 있으면 날짜별 백업
          if [ -f "/var/www/backend/ROOT.jar" ]; then
            cp /var/www/backend/ROOT.jar /var/www/backend/ROOT.jar.bak_$(date +%Y%m%d_%H%M%S)
          fi
          # systemd 서비스 재시작
          sudo systemctl restart donation-backend
          # 배포 결과 확인
          ls -l /var/www/backend/ROOT.jar*
          systemctl status donation-backend --no-pager

 

3. 커밋 후 배포 확인 (성공)



[설정 2] YAML 워크플로우:  gradle.yml

 



[설정 3] Systemd 서비스:

 

# 1. 시스템 설정 새로고침 (파일 수정 후 필수)
sudo systemctl daemon-reload

# 2. 서비스 활성화 (부팅 시 자동 실행)
sudo systemctl enable donation-chat

# 3. 서비스 시작/재시작
sudo systemctl restart donation-chat

# 4. 실시간 상태 및 로그 확인 (배포 성공 인증용)
sudo systemctl status donation-chat
sudo journalctl -u donation-chat -f