-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathJenkinsfile
More file actions
119 lines (111 loc) · 4.52 KB
/
Jenkinsfile
File metadata and controls
119 lines (111 loc) · 4.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
pipeline {
agent any
tools {
gradle 'gradle-8.4'
jdk 'jdk-21'
}
environment {
WORKSPACE = "/var/jenkins_home/workspace/laundreader-prod"
IMAGE_NAME = 'user-api'
IMAGE_TAG = "v${BUILD_NUMBER}"
BLUE_COMPOSE = "${WORKSPACE}/secure-submodule/docker/docker-compose.blue.yml"
GREEN_COMPOSE = "${WORKSPACE}/secure-submodule/docker/docker-compose.green.yml"
COMMON_COMPOSE = "${WORKSPACE}/secure-submodule/docker/docker-compose.common.yml"
USER_API_DOCKERFILE_PATH = "/secure-submodule/docker/user-api.Dockerfile"
HOST_IP = "49.50.133.246"
NGINX_UPSTREAM_CONF = "/etc/nginx/conf.d/user-api-upstream.conf"
}
stages {
stage('Checkout') {
steps {
// 서브모듈 포함 checkout
checkout([
$class: 'GitSCM',
branches: [[name: '*/develop']],
userRemoteConfigs: [[
url: 'https://github.com/Laundreader/server.git',
credentialsId: 'github-token'
]],
extensions: [
[$class: 'SubmoduleOption', recursiveSubmodules: true]
]
])
}
}
stage('Build JAR') {
steps {
sh "chmod +x ./gradlew"
sh './gradlew :user-api:buildNeeded --stacktrace --info -x test'
}
}
stage('Docker Build'){
steps {
sh """
DOCKER_BUILDKIT=0 docker build \
-f ${WORKSPACE}${USER_API_DOCKERFILE_PATH} \
-t ${IMAGE_NAME}:${IMAGE_TAG} \
-t ${IMAGE_NAME}:latest \
${WORKSPACE}/user-api/build/libs
"""
}
}
stage('Deploy') {
steps {
script {
// 1. Redis 실행 확인
sh "docker-compose -f ${COMMON_COMPOSE} up -d"
// 현재 활성 컨테이너 확인 (Blue 또는 Green)
def active = sh(
script: "docker ps --filter 'name=user-api-blue' --filter 'name=user-api-green' --format '{{.Names}}' | head -n 1",
returnStdout: true
).trim()
// 3. 다음 배포 대상 결정
def nextCompose
def nextService
def nextPort
if (!active || active == 'user-api-green') {
nextCompose = BLUE_COMPOSE
nextService = 'user-api-blue'
nextPort = 8080
} else {
nextCompose = GREEN_COMPOSE
nextService = 'user-api-green'
nextPort = 8081
}
echo "▶️ Active container: ${active ?: 'None'}"
echo "🔄 Next deploy: ${nextService} using ${nextCompose}"
// 새 컨테이너 시작
sh "docker-compose -f ${nextCompose} up -d --build"
// 새 컨테이너 정상 구동 확인
sh """
for i in {1..5}; do
curl -fs http://localhost:${nextPort}/health && break
echo 'Waiting for container...'
sleep 3
done || { echo '❌ Container failed to start'; exit 1; }
"""
// Nginx upstream 갱신
sshagent (credentials: ['jenkins-ssh-key']) {
sh """
ssh -o StrictHostKeyChecking=no root@${HOST_IP} \\
"echo 'upstream user_api_upstream { server localhost:${nextPort}; }' > ${NGINX_UPSTREAM_CONF} &&
nginx -t &&
systemctl reload nginx"
"""
}
// 이전 컨테이너 종료
if(active) {
echo "Stopping old container: ${active}"
sh "docker rm -f ${active} || true"
}
echo "✅ Traffic switched to ${nextService} (port ${nextPort}) via Nginx"
}
}
}
}
post {
always {
echo '파이프라인 종료'
}
}
}