Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
Tags
- nuxt
- 백준
- TypeScript
- chrome
- 광고 id
- 코테
- 코딩테스트
- EC2
- kotlin
- Jenkins
- AWS
- spring boots
- docker
- Android
- React
- toml
- Next
- Express
- python
- 파이썬
- css
- JavaScript
- 오퍼월
- it
- 티스토리챌린지
- 개발
- NanoHttpd
- nginx
- react-native
- 오블완
Archives
- Today
- Total
내맘대로 개발일지
[AWS] Jenkins 로 배포하기 [Spring] 본문
[AWS] Jenkins 로 배포하기 [Node]
[Jenkins] EC2 안에서 설치하고 실행하기[EC2] 안에서 nginx 사용하기[AWS] 아무것도 모르는데 EC2 + Docker + MariaDB + nginx진짜 아무것도 모른다.개발만 해봤지 인프라 처음해본다.곁눈질도 안해봤고 해주는
8735.tistory.com
드디어 여기까지왔다....
마지막으로 Spring 서버를 무중단으로 해볼 예정이다.
기본적인 설정은 프론트를 배포하면서 다 해놓은 상태이다.
서버도 프론트와 동일하게 Pipeline 으로 만들고
스크립트를 작성해준다.
pipeline {
agent any
options { timestamps() }
environment {
PROJECT_NAME = "PROJECT_NAME"
GIT_URL = "GIT_URL"
GIT_BRANCH = "GIT_BRANCH"
CREDENTIALS_ID = "github_ssh"
DOCKER_IMAGE = "DOCKER_IMAGE:latest"
BLUE_PORT = "8080"
GREEN_PORT = "8082"
NGINX_CONF = "/etc/nginx/conf.d/default.conf"
// sudo 비번 없이 실행 (sudoers 에 ec2-user NOPASSWD 설정 필요)
SUDO = "sudo -n"
}
stages {
stage('Clone Repository') {
steps {
sh "git --version"
git branch: "${GIT_BRANCH}",
credentialsId: "${CREDENTIALS_ID}",
url: "${GIT_URL}"
}
}
stage('Build JAR') {
steps {
sh 'chmod +x ./gradlew'
sh './gradlew clean build -x test'
}
}
stage('Build Docker Image') {
steps {
sh """
echo "🐳 build image: ${DOCKER_IMAGE}"
docker build -t ${DOCKER_IMAGE} .
"""
}
}
stage('Blue-Green Deploy') {
steps {
script {
// 1) nginx 에서 현재 LIVE 포트(8080 or 8082) 확인
def currentPort = sh(
script: "grep -o '127.0.0.1:808[0-9]' ${NGINX_CONF} | head -n1 | sed 's/127.0.0.1://' || echo ''",
returnStdout: true
).trim()
if (!currentPort) {
// 처음 셋업 시에는 8080 기준
currentPort = BLUE_PORT
}
echo "현재 LIVE PORT = ${currentPort}"
def bluePort = currentPort
def greenPort = (currentPort == BLUE_PORT) ? GREEN_PORT : BLUE_PORT
def blueName = "${PROJECT_NAME}-${bluePort}"
def greenName = "${PROJECT_NAME}-${greenPort}"
echo "BLUE (현재 LIVE) : ${blueName} / ${bluePort}"
echo "GREEN(새 버전) : ${greenName} / ${greenPort}"
// 2) 기존 GREEN 컨테이너 정리
sh """
echo "🧹 기존 GREEN 컨테이너 정리: ${greenName}"
docker stop ${greenName} || true
docker rm ${greenName} || true
# 예전에 쓰던 이름이 있으면 같이 정리
docker stop backend || true
docker rm backend || true
"""
// 3) 새 버전을 GREEN 포트로 먼저 기동
sh """
echo "🚀 새 버전(${greenPort}) 기동: ${greenName}"
docker run -d \\
--name ${greenName} \\
--network host \\
-e SPRING_PROFILES_ACTIVE=prod \\
-e SERVER_PORT=${greenPort} \\
${DOCKER_IMAGE}
"""
// 4) GREEN 헬스체크 (/api 사용)
sh """
echo "🩺 새 버전(포트 ${greenPort}) 헬스체크 시작"
for i in {1..30}; do
if curl -sf http://127.0.0.1:${greenPort}/api > /dev/null; then
echo "✅ 새 버전(포트 ${greenPort}) 헬스체크 통과"
exit 0
fi
echo "⏳ 대기중 (\$i)..."
sleep 2
done
echo "❌ 새 버전(포트 ${greenPort}) 헬스체크 실패"
echo "------ 컨테이너 로그 (${greenName}) ------"
docker logs ${greenName} || true
exit 1
"""
// 5) nginx proxy_pass 808X → GREEN 포트로 변경
sh """
echo "🔁 Nginx proxy_pass ${bluePort} → ${greenPort} 변경"
${SUDO} sed -i 's/127.0.0.1:${bluePort}/127.0.0.1:${greenPort}/' ${NGINX_CONF}
echo "🔎 nginx 설정 테스트"
${SUDO} nginx -t
echo "🔄 nginx reload"
${SUDO} systemctl reload nginx
"""
// 6) 옛날 BLUE 컨테이너 종료/삭제
sh """
echo "🛑 기존 BLUE 컨테이너 정리: ${blueName}"
docker stop ${blueName} || true
docker rm ${blueName} || true
"""
echo "🎉 blue-green 배포 완료 (LIVE PORT = ${greenPort})"
}
}
}
}
}
스크립트가 길어서 어려운데 간단하게 보면
포트를 8080 과 8082 를 번갈아가면서 새로운게 올라올때까지
기다렸다가 헬스체크가 끝나고나면 포트를 변경해 연결해주는 것으로 해서
실제 웹에서는 무중단처럼 느낄 수 있게끔 해주는 방식이다.
스크립트를 작성하고 다음은 nginx 를 수정해줘야한다.
server {
listen 80;
server_name _;
root /var/www/frontend;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://127.0.0.1:8082/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 5s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
gzip on;
gzip_types text/plain text/css application/json application/javascript application/xml+rss;
gzip_min_length 256;
}
ps aux | grep jenkins | head
jenkins ...
해당 명령어를 통해 Jenkins 가 어떤 계정으로 돌아가는지 확인하고
맨앞에 나오는 이름이 유저이름이다 나같은경우는 jenkins 였고
// 파일 열고
sudo visudo -f /etc/sudoers.d/jenkins
// 입력 하고
jenkins ALL=(ALL) NOPASSWD: /usr/bin/sed, /usr/sbin/nginx, /usr/bin/systemctl
// 문법 체크
sudo visudo -c
// 결과
/etc/sudoers.d/jenkins: OK
// 적용 테스트
sudo -n echo "sudo works"
// 결과
sudo works
해당 파일로 들어가서 해당 명령을 입력해준다.
이를 통해서 Jenkins 가 서버권한을 갖고 설정 파일을 건드릴 수 있게 된다.
이렇게해서 젠킨스가서 빌드를 실행해보면 무중단처럼 배포를 진행할 수 있게된다.
'IT' 카테고리의 다른 글
| [AWS] Jenkins 로 배포하기 [Node] (0) | 2025.11.24 |
|---|---|
| [AWS] 고정 IP 할당받기 (0) | 2025.11.19 |
| [Jenkins] EC2 안에서 설치하고 실행하기 (0) | 2025.11.12 |
| [EC2] 안에서 nginx 사용하기 (0) | 2025.11.12 |
| [AWS] 아무것도 모르는데 EC2 + Docker + MariaDB + nginx (0) | 2025.11.11 |