SpringBoot + GitHub Actions CI/CD 완벽 구성 & 문제 해결
SpringBoot 애플리케이션에 GitHub Actions를 활용한 CI/CD 파이프라인을 구축하고, 실제 운영 환경에서 발생하는 문제를 해결하는 방법을 단계별로 설명합니다. 이 가이드는 JDK 설치부터 클라우드 배포까지 전체 워크플로우를 다루며, 실패 사례별 트러블슈팅 기법을 포함합니다.
튜토리얼: SpringBoot CI/CD 기본 구성
1. GitHub 리포지토리 연결 및 기본 Workflow 생성
- SpringBoot 프로젝트를 GitHub에 업로드합니다.
git init git add . git commit -m "Initial commit" git branch -M main git remote add origin https://github.com/<your-id>/<repo-name>.git git push -u origin main .github/workflows/springboot-ci-cd.yml파일을 생성합니다.
2. 기본 Workflow YAML 구성
name: SpringBoot CI/CD
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: Build with Gradle
run: ./gradlew build
- name: Build Docker image
run: |
docker build -t my-springboot-app:latest .
docker tag my-springboot-app:latest \
$AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/my-springboot-app:latest
- name: Push to ECR
run: |
aws ecr get-login-password --region $AWS_REGION | \
docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com
docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/my-springboot-app:latest
env:
AWS_ACCOUNT_ID: ${{ secrets.AWS_ACCOUNT_ID }}
AWS_REGION: ${{ secrets.AWS_REGION }}
팁: Maven 사용 시
./mvnw clean package로 변경합니다. Dockerfile이 프로젝트 루트에 위치해야 합니다.
3. GitHub Secrets 설정
- AWS 계정의
AWS_ACCOUNT_ID와AWS_REGION을 Secrets에 등록 - Azure App Service 사용 시
AZURE_WEBAPP_NAME과AZURE_CREDENTIALS추가
트러블슈팅: CI/CD 실패 주요 사례
1. 빌드 실패 사례
- Java 버전 불일치:
→Error: Java version "1.8.0_292" is not supported by Gradlesetup-java액션의java-version을 프로젝트 요구사항에 맞춰 수정 - Gradle wrapper 미포함:
→/bin/sh: ./gradlew: No such file or directorygradlew바이너리 포함 여부 확인 (Gradle wrapper 사용 필수) - 의존성 다운로드 실패:
→ 방화벽 설정 확인 또는Could not transfer artifact com.example:library:jar:1.0.0--no-daemon플래그 추가
2. 배포 실패 사례
- IAM 권한 문제:
→ AWS ECR 접근 권한이 있는 IAM 역할 생성 후 Secrets에 자격 증명 등록User is not authorized to perform ecr:PutImage - Docker 태그 충돌:
→manifest for my-springboot-app:latest not founddocker pull로 기존 이미지 삭제 후 재시도 - Helm chart 오류:
→ Helm 차트 버전 호환성 확인 및failed: Invalid value: : invalid type for io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContexthelm dependency update실행
3. 캐시 미적용 문제
GET https://jcenter.bintray.com/...
→ Gradle/Maven 의존성 캐시 추가:
- name: Cache Gradle packages
uses: actions/cache@v3
with:
path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }}
restore-keys: |
${{ runner.os }}-gradle-
문제 해결: 단계별 검증 방법
1. 로컬에서 Workflow 테스트
act CLI로 로컬에서 워크플로우를 시뮬레이션합니다.
brew install nektos/act/act
act --pull-request --pull-request-head-sha=$(git rev-parse HEAD)
2. 디버그 로그 활성화
워크플로우 단계에 set -x 추가:
- name: Debug Docker build
run: |
set -x
docker build -t my-springboot-app:latest .
3. Self-hosted Runner 로그 분석
SSH로 러너 서버에 접속해 직접 로그 확인:
journalctl -u github-actions-runner.service -f
4. 품질 검증 도구 연동
- JUnit 테스트 결과:
gradle test jacocoTestReport추가 - SonarQube 분석:
- name: Run SonarQube Scanner
uses: SonarSource/sonarqube-scan-action@master
with:
projectKey: my-springboot-project
projectName: SpringBoot Demo
참고 문서
주의사항: 프로덕션 환경에서는
main브랜치 외에develop브랜치에 대한 별도 워크플로우를 구성하는 것이 안전합니다. 이미지 태그 전략으로는SHA기반 태그를 권장합니다.