Project
[Jenkins] 멀티모듈 파이프 라인 (feat. Jenkinsfile)
seowooJeong
2025. 2. 26. 12:36
환경
- Gradle 7.0.1
- Java, SpringBoot
- Docker (docker compose)
- Spring gateway
- multi module
개요
- 하나의 프로젝트에 도메인별 모듈을 가지고 MSA 형태의 서비스를 제공하고 있는 상황에서 CI/CD를 구축해야 하는 상황이었다.
프로세스
Jenkins 설정 (GitLab / Jenkins 관련 기초 설정은 생략)
- 위의 예시에서는 GitLab에서 webhook push event를 전달받기 위한 설정이다.
(각 환경에 맞는 Build Triggers 설정을 해야한다)
- Jenkins Build Triggers를 통해 나온 Webhook용 URL을 넣고 Jenkins 설정 아래에 고급 버튼을 눌러 Secret token을 생성한다.
- 생성된 토큰은 GitLab Webhook 설정에 필요한 Secret token 값이다.
- Trigger (Push Events만 받을 경우)의 경우 Regular expression에 repository branch 상대경로를 넣어주면 된다.
제일 중요한 Groovy 문법을 사용하는 Jenkinsfile을 Spring 프로젝트 내에 만들고 Groovy 기반으로 script를 짜면 되는 것이다.
pipeline {
agent any
tools {
gradle "Gradle 7.0.1"
}
environment {
BUILD_TARGET_HOME = "/your/build/target/directory"
SSH_CONNECTION_CREDENTIAL = "your-jenkins-credential-name"
SSH_SERVER_ID = "yourSshServerAccount"
SSH_SERVER_DOMAIN = "yourSshServerDomainName"
GRADLE_TYPE = "bootJar"
SERVICE_GATEWAY = "gateway"
SERVICE_API = "api"
SERVICE_BOOK = "book"
SERVICE_USER = "user"
SERVICE_ADMIN = "admin"
DOCKER_SERVICE_NAME = "" //TODO 컨테이너명 동일하게 맞추고 적용
}
stages {
stage('Build') {
parallel {
stage('build-service-gateway') {
when {
anyOf {
changeset "${SERVICE_GATEWAY}/**/*"
}
}
steps {
echo "Build Start ${SERVICE_GATEWAY}"
sh "./gradlew ${SERVICE_GATEWAY}:clean"
sh "./gradlew ${SERVICE_GATEWAY}:${GRADLE_TYPE} -x test"
echo "Build End ${SERVICE_GATEWAY}"
}
}
stage('build-service-book') {
when {
anyOf {
changeset "${SERVICE_BOOK}/**/*"
}
}
steps {
echo "Build Start ${SERVICE_BOOK}"
sh "./gradlew ${SERVICE_BOOK}:clean"
sh "./gradlew ${SERVICE_BOOK}:${GRADLE_TYPE} -x test"
echo "Build End ${SERVICE_BOOK}"
}
}
stage('build-service-user') {
when {
anyOf {
changeset "${SERVICE_USER}/**/*"
}
}
steps {
echo "Build Start ${SERVICE_USER}"
sh "./gradlew ${SERVICE_USER}:clean"
sh "./gradlew ${SERVICE_USER}:${GRADLE_TYPE} -x test"
echo "Build End ${SERVICE_USER}"
}
}
stage('build-service-api') {
when {
anyOf {
changeset "${SERVICE_API}/**/*"
}
}
steps {
echo "Build Start ${SERVICE_API}"
sh "./gradlew ${SERVICE_API}:clean"
sh "./gradlew ${SERVICE_API}:${GRADLE_TYPE} -x test"
echo "Build End ${SERVICE_API}"
}
}
stage('build-service-admin') {
when {
anyOf {
changeset "${SERVICE_ADMIN}/**/*"
}
}
steps {
echo "Build Start ${SERVICE_ADMIN}"
sh "./gradlew ${SERVICE_ADMIN}:clean"
sh "./gradlew ${SERVICE_ADMIN}:${GRADLE_TYPE} -x test"
echo "Build End ${SERVICE_ADMIN}"
}
}
}
}
stage('Deploy') {
parallel {
stage('deploy-service-gateway') {
when {
anyOf {
changeset "${SERVICE_GATEWAY}/**/*"
}
}
steps {
sshagent([SSH_CONNECTION_CREDENTIAL]) {
echo "Deploy Start ${SERVICE_GATEWAY}"
sh "scp -o 'StrictHostKeyChecking no' -r ${WORKSPACE}/${SERVICE_GATEWAY}/build/libs/*.jar ${SSH_SERVER_ID}@${SSH_SERVER_DOMAIN}:${BUILD_TARGET_HOME}/${SERVICE_GATEWAY}"
sh "ssh -o 'StrictHostKeyChecking=no' ${SSH_SERVER_ID}@${SSH_SERVER_DOMAIN} 'docker-compose -f ${BUILD_TARGET_HOME}/docker-compose-dev.yml restart svr-mobi-book-gateway-service-v2'"
echo "Deploy End ${SERVICE_GATEWAY}"
}
}
}
stage('deploy-service-book') {
when {
anyOf {
changeset "${SERVICE_BOOK}/**/*"
}
}
steps {
sshagent([SSH_CONNECTION_CREDENTIAL]) {
echo "Deploy Start ${SERVICE_BOOK}"
sh "scp -o 'StrictHostKeyChecking no' -r ${WORKSPACE}/${SERVICE_BOOK}/build/libs/*.jar ${SSH_SERVER_ID}@${SSH_SERVER_DOMAIN}:${BUILD_TARGET_HOME}/${SERVICE_BOOK}"
sh "ssh -o 'StrictHostKeyChecking=no' ${SSH_SERVER_ID}@${SSH_SERVER_DOMAIN} 'docker-compose -f ${BUILD_TARGET_HOME}/docker-compose-dev.yml restart svr-mobi-book-api-v2'"
echo "Deploy End ${SERVICE_BOOK}"
}
}
}
stage('deploy-service-user') {
when {
anyOf {
changeset "${SERVICE_USER}/**/*"
}
}
steps {
sshagent([SSH_CONNECTION_CREDENTIAL]) {
echo "Deploy Start ${SERVICE_USER}"
sh "scp -o 'StrictHostKeyChecking no' -r ${WORKSPACE}/${SERVICE_USER}/build/libs/*.jar ${SSH_SERVER_ID}@${SSH_SERVER_DOMAIN}:${BUILD_TARGET_HOME}/${SERVICE_USER}"
sh "ssh -o 'StrictHostKeyChecking=no' ${SSH_SERVER_ID}@${SSH_SERVER_DOMAIN} 'docker-compose -f ${BUILD_TARGET_HOME}/docker-compose-dev.yml restart svr-mobi-user-api-v2'"
echo "Deploy End ${SERVICE_USER}"
}
}
}
stage('deploy-service-api') {
when {
anyOf {
changeset "${SERVICE_API}/**/*"
}
}
steps {
sshagent([SSH_CONNECTION_CREDENTIAL]) {
echo "Deploy Start ${SERVICE_API}"
sh "scp -o 'StrictHostKeyChecking no' -r ${WORKSPACE}/${SERVICE_API}/build/libs/*.jar ${SSH_SERVER_ID}@${SSH_SERVER_DOMAIN}:${BUILD_TARGET_HOME}/${SERVICE_API}"
sh "ssh -o 'StrictHostKeyChecking=no' ${SSH_SERVER_ID}@${SSH_SERVER_DOMAIN} 'docker-compose -f ${BUILD_TARGET_HOME}/docker-compose-dev.yml restart mobi-book-api-service'"
echo "Deploy End ${SERVICE_API}"
}
}
}
stage('deploy-service-admin') {
when {
anyOf {
changeset "${SERVICE_ADMIN}/**/*"
}
}
steps {
sshagent([SSH_CONNECTION_CREDENTIAL]) {
echo "Deploy Start ${SERVICE_ADMIN}"
sh "scp -o 'StrictHostKeyChecking no' -r ${WORKSPACE}/${SERVICE_ADMIN}/build/libs/*.jar ${SSH_SERVER_ID}@${SSH_SERVER_DOMAIN}:${BUILD_TARGET_HOME}/${SERVICE_ADMIN}"
sh "ssh -o 'StrictHostKeyChecking=no' ${SSH_SERVER_ID}@${SSH_SERVER_DOMAIN} 'docker-compose -f ${BUILD_TARGET_HOME}/docker-compose-dev.yml restart mobi-book-admin-service'"
echo "Deploy End ${SERVICE_ADMIN}"
}
}
}
}
}
}
}
ps. 젠킨스 서버에서 만든 공개키(보통 /home/jenkins/.ssh 안에 만들어 관리한다. known_host 와 같은 파일) 를 GitLab ssh 만들 때 넣어서 만들면 젠킨스 서버에서 GitLab repository 접근할 때 허용해 주겠다 라는 설정.
++ 추가 사항 있으면 추가할 포스팅입니다.