본문 바로가기
Spring & SpringBoot

GitHub Actions + Self-hosted Runner로 구성한 MSA 자동 배포 시스템

by 창따오 2025. 7. 22.
728x90

1. 프로젝트 구조 개요

이번 프로젝트는 MSA 아키텍처 기반으로 구성되었으며, 다음과 같은 서비스들로 나뉩니다:

  • ✅ gateway (Spring Cloud Gateway)
  • ✅ auth-service (JWT 기반 인증 서비스)
  • ✅ user-service (사용자 도메인 서비스)
  • ✅ eureka-server (서비스 디스커버리)

각 서비스는 개별 GitHub Repository에서 관리되며, 각각 Docker 이미지로 빌드되어 Docker Hub에 push되고, 이후 집 PC(WLS 환경)에서 pull 및 자동 container 재기동되는 구조입니다.

 


2. GitHub Actions CI 구성

각 서비스는 다음과 같은 GitHub Actions workflow를 사용해 Docker 이미지로 자동 빌드됩니다:

name: Build and Push to Docker Hub

on:
  push:
    branches: [ "main" ]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout source
        uses: actions/checkout@v3

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

      - name: Grant execute permission to Gradle
        run: chmod +x ./gradlew

      - name: Build the application
        run: ./gradlew bootJar

      - name: Log in to Docker Hub
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - name: Build and push Docker image
        run: |
          docker build -t changddao/gateway:latest .
          docker push changddao/gateway:latest

각 서비스별로 이미지명만 다르게 설정하면 됩니다.

 


3. 집 PC에 Self-hosted Runner 설치 및 CD 구성

집 PC의 WSL 환경에서 self-hosted runner를 설치하고 각 서비스별로 다음과 같은 방식으로 CD를 구성했습니다:

 

 cd:
    needs: build-and-deploy
    runs-on: self-hosted
    steps:
      - name: Pull latest Docker image
        run: docker compose -f ./docker-compose.yml pull gateway

      - name: Restart container
        run: docker compose -f ./docker-compose.yml up -d gateway

 

4. 환경 변수 보안 설정

.env 파일을 docker-compose.yml과 동일 디렉토리에 배치하여 민감한 정보를 관리합니다:

.env 예시:

DB_USERNAME=postgres
DB_PASSWORD=secret
JWT_SECRET_KEY=my-very-secret-key

application.yml에서는 아래처럼 주입되도록 구성:

jwt:
  secret: ${JWT_SECRET_KEY}

 


5. Eureka에서 컨테이너 이름이 안 보일 때

Eureka 대시보드에서 UNKNOWN으로 뜨는 문제는 application.yml에 아래 설정 추가로 해결:

spring:
  application:
    name: gateway  # 또는 서비스명

eureka:
  instance:
    instance-id: ${spring.application.name}:${random.value}
    prefer-ip-address: true

✨ 마무리

이번 자동 배포 시스템 구축을 통해 다음과 같은 점들을 경험할 수 있었습니다:

  • GitHub Actions + Self-hosted runner로 CI/CD 완전 자동화
  • Docker Hub를 중간 배포 허브로 활용
  • .env를 통한 민감정보 분리와 보안 관리
  • Eureka 기반 MSA 서비스 디스커버리 완성

🔜 다음 목표

  • Kafka 및 DB 서비스들도 동일한 방식으로 CD 구축
  • Grafana + Prometheus 기반 모니터링 추가
  • docker-compose.override.yml을 활용한 로컬 개발 환경 자동화