Jenkins CI/CD 파이프라인 구축


Jenkins는 오픈소스 자동화 서버로, 빌드, 테스트, 배포를 자동화하는 CI/CD 파이프라인을 구축할 수 있습니다. 코드 변경 시 자동으로 빌드하고 테스트하여 품질을 유지합니다.



언제 사용하나요?



  • 코드 푸시 시 자동 빌드 및 테스트

  • 개발/스테이징/프로덕션 자동 배포

  • 코드 품질 검사 자동화

  • 정기적인 배치 작업 스케줄링



Jenkins 설치


# Docker로 설치 (권장)
docker run -d -p 8080:8080 -p 50000:50000
-v jenkins_home:/var/jenkins_home
--name jenkins jenkins/jenkins:lts

# CentOS/RHEL
sudo wget -O /etc/yum.repos.d/jenkins.repo
https://pkg.jenkins.io/redhat-stable/jenkins.repo
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key
sudo yum install jenkins java-11-openjdk
sudo systemctl start jenkins

# Ubuntu
curl -fsSL https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo tee
/usr/share/keyrings/jenkins-keyring.asc > /dev/null
sudo apt-get update && sudo apt-get install jenkins


Jenkinsfile 기본 구조


// 선언적 파이프라인 (Declarative Pipeline)
pipeline {
agent any

environment {
JAVA_HOME = "/usr/lib/jvm/java-17"
MAVEN_HOME = "/opt/maven"
}

stages {
stage("Checkout") {
steps {
git branch: "main",
url: "https://github.com/user/repo.git",
credentialsId: "github-credentials"
}
}

stage("Build") {
steps {
sh "mvn clean package -DskipTests"
}
}

stage("Test") {
steps {
sh "mvn test"
}
post {
always {
junit "target/surefire-reports/*.xml"
}
}
}

stage("Deploy") {
when {
branch "main"
}
steps {
sh "./deploy.sh"
}
}
}

post {
success {
echo "빌드 성공!"
// Slack 알림
slackSend channel: "#builds",
message: "빌드 성공: ${env.JOB_NAME}"
}
failure {
echo "빌드 실패!"
slackSend channel: "#builds",
color: "danger",
message: "빌드 실패: ${env.JOB_NAME}"
}
}
}


멀티 브랜치 파이프라인


pipeline {
agent any

stages {
stage("Build") {
steps {
sh "mvn clean package"
}
}

stage("Deploy to Dev") {
when { branch "develop" }
steps {
sh "kubectl apply -f k8s/dev/"
}
}

stage("Deploy to Staging") {
when { branch "release/*" }
steps {
sh "kubectl apply -f k8s/staging/"
}
}

stage("Deploy to Production") {
when { branch "main" }
steps {
input message: "프로덕션 배포 승인?"
sh "kubectl apply -f k8s/prod/"
}
}
}
}


Docker 빌드 및 푸시


pipeline {
agent any

environment {
DOCKER_REGISTRY = "registry.example.com"
IMAGE_NAME = "myapp"
IMAGE_TAG = "${env.BUILD_NUMBER}"
}

stages {
stage("Build Docker Image") {
steps {
script {
docker.build("${DOCKER_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}")
}
}
}

stage("Push to Registry") {
steps {
script {
docker.withRegistry("https://${DOCKER_REGISTRY}", "docker-credentials") {
docker.image("${DOCKER_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}").push()
docker.image("${DOCKER_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}").push("latest")
}
}
}
}
}
}


병렬 실행


stage("Test") {
parallel {
stage("Unit Tests") {
steps {
sh "mvn test -Dtest=*UnitTest"
}
}
stage("Integration Tests") {
steps {
sh "mvn test -Dtest=*IntegrationTest"
}
}
stage("E2E Tests") {
steps {
sh "npm run test:e2e"
}
}
}
}


크레덴셜 관리


// 크레덴셜 사용
stage("Deploy") {
steps {
withCredentials([
usernamePassword(
credentialsId: "ssh-credentials",
usernameVariable: "SSH_USER",
passwordVariable: "SSH_PASS"
),
string(
credentialsId: "api-key",
variable: "API_KEY"
)
]) {
sh "sshpass -p $SSH_PASS scp app.jar $SSH_USER@server:/app/"
}
}
}


Webhook 설정 (GitHub)


# GitHub Webhook URL
https://jenkins.example.com/github-webhook/

# 설정
1. GitHub 저장소 Settings > Webhooks
2. Payload URL: Jenkins URL + /github-webhook/
3. Content type: application/json
4. Events: Push, Pull Request

# Jenkinsfile에 트리거 추가
pipeline {
triggers {
githubPush()
}
...
}


필수 플러그인



  • Pipeline - 파이프라인 DSL

  • Git - Git 연동

  • Docker Pipeline - Docker 빌드

  • Slack Notification - 알림

  • Blue Ocean - 시각화 UI