9.0 KiB
9.0 KiB
폐쇄망 환경 사전 빌드 JAR 배포 가이드
개요
인터넷이 차단된 Jenkins 서버에서 빌드 없이 사전에 빌드된 JAR 파일을 사용하여 배포합니다.
아키텍처
기존 방식 (실패)
Jenkins 서버 → Git Clone → Gradle Build (의존성 다운로드 필요) → JAR 생성 → 배포
❌ 인터넷 필요
새로운 방식 (성공)
로컬 PC → Gradle Build → JAR 생성 → Git Commit
Jenkins 서버 → Git Clone → JAR 사용 (빌드 불필요) → 배포
✅ 인터넷 불필요
장점
- 인터넷 불필요: Jenkins 서버가 완전히 폐쇄망이어도 동작
- 빠른 배포: 빌드 시간 불필요 (~3분 → ~10초)
- 간단한 설정: 복잡한 Gradle cache나 local repository 불필요
- 일관성: 로컬에서 테스트한 동일한 JAR 파일 배포
단점
- Git 용량 증가: JAR 파일(~19MB)이 버전 관리됨
- 로컬 빌드 필요: 코드 변경 시 로컬에서 빌드 후 커밋 필요
- 바이너리 커밋: Git에 바이너리 파일 포함
사용 방법
1. 로컬 환경 (인터넷 연결 가능한 PC)
코드 변경 시
cd kamco-make-dataset-generation
# 1. 코드 수정
# ... 코드 변경 ...
# 2. JAR 빌드
./gradlew clean bootJar
# 3. JAR 파일 확인
ls -lh build/libs/generator-dataset-for-training.jar
# 4. Git 커밋
git add .
git add -f build/libs/generator-dataset-for-training.jar
git commit -m "Update: 기능 추가 및 JAR 업데이트"
git push
2. Jenkins 서버 (폐쇄망 환경)
Jenkins 파라미터
파이프라인 실행 시 다음 파라미터를 설정할 수 있습니다:
| 파라미터 | 타입 | 기본값 | 설명 |
|---|---|---|---|
| SPRING_PROFILES_ACTIVE | String | prod | Spring Profile (dev/prod) |
| BATCH_DATE | String | (공백) | Batch 날짜 (YYYY-MM-DD, 공백 = 오늘) |
| ADDITIONAL_PARAMS | String | (공백) | 추가 파라미터 (예: limit=100) |
| ACTION | Choice | RUN | 실행 모드 (RUN / VERIFY_ONLY) |
실행 예시
1. 기본 실행 (오늘 날짜):
ACTION: RUN
SPRING_PROFILES_ACTIVE: prod
BATCH_DATE: (공백) ← 자동으로 오늘 날짜 사용
ADDITIONAL_PARAMS: (공백)
→ java -jar generator-dataset-for-training.jar --spring.profiles.active=prod date=2026-02-09
2. 특정 날짜로 실행:
ACTION: RUN
SPRING_PROFILES_ACTIVE: prod
BATCH_DATE: 2024-01-15
ADDITIONAL_PARAMS: (공백)
→ java -jar generator-dataset-for-training.jar --spring.profiles.active=prod date=2024-01-15
3. 오늘 날짜 + 추가 파라미터:
ACTION: RUN
SPRING_PROFILES_ACTIVE: prod
BATCH_DATE: (공백)
ADDITIONAL_PARAMS: limit=100 debug=true
→ java -jar generator-dataset-for-training.jar --spring.profiles.active=prod date=2026-02-09 limit=100 debug=true
4. 개발 환경 테스트:
ACTION: RUN
SPRING_PROFILES_ACTIVE: dev
BATCH_DATE: 2024-02-01
ADDITIONAL_PARAMS: dryRun=true
→ java -jar generator-dataset-for-training.jar --spring.profiles.active=dev date=2024-02-01 dryRun=true
5. JAR 검증만 (실행 안 함):
ACTION: VERIFY_ONLY
→ JAR 파일 존재만 확인하고 종료
날짜 파라미터 동작 방식
BATCH_DATE 파라미터:
- 비어있음 (기본값): Jenkins 서버의 현재 날짜 자동 사용 (YYYY-MM-DD)
- 값 입력: 입력한 날짜 사용 (예: 2024-01-15)
예시:
# BATCH_DATE가 비어있으면
TODAY=$(date +%Y-%m-%d) # 2026-02-09
java -jar app.jar date=2026-02-09
# BATCH_DATE에 2024-01-15 입력하면
java -jar app.jar date=2024-01-15
Jenkins 파이프라인 단계
Jenkins는 자동으로:
- Environment 설정: 오늘 날짜 계산 (TODAY 변수)
- Checkout: Git에서 코드 체크아웃
- Verify JAR: JAR 파일 존재 확인
- Run JAR (ACTION=RUN인 경우만):
- BATCH_DATE가 비어있으면 TODAY 사용
- JAR 실행 with 파라미터
파일 구조
kamco-make-dataset-generation/
├── build/
│ └── libs/
│ └── generator-dataset-for-training.jar ← Git에 포함됨
├── src/
├── build.gradle
├── Jenkinsfile
└── .gitignore ← build/libs/*.jar 예외 처리
.gitignore 설정
# Gradle
.gradle/
build/
!build/libs/ # libs 디렉토리는 추적
!build/libs/*.jar # jar 파일은 추적
out/
Jenkinsfile 구조
parameters {
string(name: 'SPRING_PROFILES_ACTIVE', defaultValue: 'prod', ...)
string(name: 'BATCH_DATE', defaultValue: '', ...)
string(name: 'ADDITIONAL_PARAMS', defaultValue: '', ...)
choice(name: 'ACTION', choices: ['RUN', 'VERIFY_ONLY'], ...)
}
environment {
TODAY = sh(script: "date +%Y-%m-%d", returnStdout: true).trim()
}
stage('Verify JAR') {
// JAR 파일 존재 확인
// 파일 정보 출력
}
stage('Run JAR') {
when {
expression { params.ACTION == 'RUN' }
}
// 날짜 결정: BATCH_DATE가 비어있으면 TODAY 사용
def batchDate = params.BATCH_DATE ?: env.TODAY
// JAR 실행
// java -jar generator-dataset-for-training.jar --spring.profiles.active=prod date=${batchDate} ${ADDITIONAL_PARAMS}
}
배포 설정
Deploy stage에 실제 배포 명령을 추가하세요:
stage('Deploy') {
steps {
dir("kamco-make-dataset-generation") {
script {
def jarPath = "build/libs/${env.JAR_NAME}"
// 예시 1: SCP로 서버 전송
sh "scp ${jarPath} user@target-server:/app/lib/"
// 예시 2: SSH로 서비스 재시작
sh "ssh user@target-server 'systemctl restart kamco-app'"
// 예시 3: Docker 이미지 빌드
sh "docker build -t kamco-app:${env.COMMIT_HASH} ."
sh "docker push kamco-app:${env.COMMIT_HASH}"
// 예시 4: Kubernetes 배포
sh "kubectl set image deployment/kamco-app kamco-app=kamco-app:${env.COMMIT_HASH}"
}
}
}
}
트러블슈팅
JAR 파일이 Git에 추가되지 않음
문제: git status에서 JAR 파일이 보이지 않음
해결:
# Force add로 추가
git add -f build/libs/generator-dataset-for-training.jar
# .gitignore 확인
cat .gitignore | grep build
Jenkins에서 JAR 파일을 찾을 수 없음
문제: "JAR file not found" 에러
해결:
# 로컬에서 JAR 커밋 확인
git log --all -- build/libs/generator-dataset-for-training.jar
# JAR가 커밋되었는지 확인
git ls-tree -r HEAD --name-only | grep jar
# 커밋되지 않았다면 다시 커밋
git add -f build/libs/generator-dataset-for-training.jar
git commit -m "Add pre-built JAR file"
git push
JAR 파일 크기가 너무 큼
문제: Git repository 크기 증가 우려
해결:
- 이 방법이 적절하지 않다면 Gradle cache 방법 사용
- Git LFS(Large File Storage) 사용 고려
- Artifactory/Nexus 같은 artifact repository 구축
의존성 업데이트
새로운 의존성 추가 시:
# 1. build.gradle 수정
# 2. 로컬에서 빌드
./gradlew clean bootJar
# 3. 새 JAR 커밋
git add build.gradle
git add -f build/libs/generator-dataset-for-training.jar
git commit -m "Add new dependency: spring-boot-starter-security"
git push
버전 관리 전략
Git 커밋 메시지 예시
# 기능 추가
git commit -m "feat: 사용자 인증 기능 추가 및 JAR 업데이트"
# 버그 수정
git commit -m "fix: 데이터 처리 버그 수정 및 JAR 업데이트"
# JAR만 업데이트
git commit -m "build: JAR 재빌드 (의존성 업데이트)"
태그 사용
# 릴리스 태그
git tag -a v1.0.0 -m "Release version 1.0.0"
git push origin v1.0.0
# Jenkins에서 특정 버전 배포
git checkout v1.0.0
성능 비교
| 항목 | 기존 방식 | 새로운 방식 |
|---|---|---|
| 빌드 시간 | ~3분 | 없음 (~10초) |
| 인터넷 필요 | 필요 | 불필요 |
| 디스크 사용 | ~500MB (Gradle cache) | ~19MB (JAR) |
| 설정 복잡도 | 높음 | 낮음 |
| 일관성 | 빌드 환경에 따라 다름 | 동일한 JAR |
주의사항
- JAR 파일 크기: 매 커밋마다 19MB 추가 (Git history 증가)
- 빌드 책임: 개발자가 로컬에서 빌드 책임
- 테스트 중요성: 로컬에서 충분한 테스트 후 커밋
- Git LFS 고려: JAR 파일이 자주 변경되면 Git LFS 사용 검토
대안 방법
이 방법이 적합하지 않은 경우:
1. Gradle Cache 방법
- ~/.gradle 디렉토리를 Jenkins 서버로 복사
- 한 번만 설정, 이후 offline 빌드
2. Artifact Repository
- Nexus, Artifactory 구축
- 폐쇄망 내부에 Maven repository 운영
3. Docker Image
- Docker image에 JAR 포함
- Docker registry 사용
참고 자료
- Spring Boot Documentation: https://docs.spring.io/spring-boot/
- Gradle Documentation: https://docs.gradle.org/
- Git LFS: https://git-lfs.github.com/