이번엔 스프링부트 코드를 Webhooks를 통해 자동배포를 해보겠습니다.
젠킨스 안에 도커 설치하기
젠킨스를 설치할때 도커 인 도커를 해야합니다. 만약 하지 않았다면 젠킨스를 삭제 후 다시 올려야 합니다.
1️⃣ Jenkins 컨테이너에 접속합니다.
docker exec -it jenkins-server /bin/bash
2️⃣ sudo를 사용하기 위해 관리자 모드로 들어갑니다.
su -
관리자 모드로 진입할때 비밀번호에서 계속 실패가 나올수 있는데 이때 밑을 참조하자.
3️⃣ Jenkins 안에 Docker를 설치합니다.
# Docker 설치
## - Old Version Remove
apt-get remove docker docker-engine docker.io containerd runc
## - Setup Repo
apt-get update
apt-get install \
ca-certificates \
curl \
gnupg \
lsb-release
mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
$(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
## - Install Docker Engine
apt-get update
apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
4️⃣ docker sudo 설정
도커에 sudo 명령어 없이 접근하기 위해 권한을 부여해줍니다.
chmod 666 /var/run/docker.sock
젠킨스에서 사용할 깃허브 토큰 발급
젠킨스에서 깃허브에 접근할 수 있도록 깃허브 토큰을 발급받겠습니다.
1️⃣ 깃허브 -> 프로필 -> settings 클릭
2️⃣ 왼쪽 하단 Developer settings 클릭
3️⃣ Personal access tokens -> Tokens(classic) -> Generate new token -> Generate new token(classic)
4️⃣ 토큰명 입력 후 기간 선택
저는 No expriation을 선택했습니다.
5️⃣ scope 선택
repo와 웹훅을 이용하기 위해 admin:repo_hook을 선택해주었습니다.
6️⃣ 생성된 토큰 값 확인
토큰은 한번만 보여주니 메모장 등에 저장합니다.
Spring 도커 파일 생성
# 이미지 지정
FROM openjdk:17
#ARG : docker build 명렁어를 사용할 때 입력받을 수 있는 인자 선언
ARG JAR_FILE=build/libs/*.jar
# copy 이미지에 파일이나 폴더 추가
COPY ${JAR_FILE} app.jar
# EntryPoint 컨테이너를실행할 때, 실행할 명령어를 지정해준다.
ENTRYPOINT [ "java" ,"-jar", "app.jar"]
젠킨스에서 깃허브 설정
1️⃣ 젠킨스에서 발급받은 토큰을 추가하겠습니다.
Dashboard -> Jenkins관리 -> System(시스템 설정)클릭
2️⃣ Github -> Add GitHub Server -> GitHub Server
3️⃣ 서버 생성(1)
이름을 입력하고 +Add를 선택해서 Jenkins를 선택합니다.
4️⃣ 서버 생성(2)
젠킨스를 추가하려면, Kind에서 Secret text를 선택후, github token과 깃허브 아이디를 입력합니다.
Description에는 원하는 설명을 적어줍니다.
그 후 Add를 누르면 Credentials에 방금 등록된 Description 이름으로 생성됩니다. Description을 넣지 않으면 ID로 생성됩니다.
테스트를 했을때 Credentials verified for user ~~~ 이런식으로 뜨면 성공입니다.
Save를 해주시면됩니다.
Pipeline 생성
이제 파이프라인을 생성하겠습니다.
1️⃣ 새로운 Item 클릭
2️⃣ 새로운 아이템을 생성합니다.
3️⃣ Pipeline 설정
1. Do not allow the pipeline to resume if the controller restarts에 체크
2. Jenkins Credentials 설정하기 (Secret File 방식)
이것은 .yml파일들을 젠킨스에 등록하기 위해서 사용합니다. jenkins안에 직접 넣어줄수 있지만 저같은 경우 credentials를 이용했습니다.
저같은경우 application.yml, application-dev.yml 이렇게 두개를 갖고있습니다. 그래서 항상 dev를 사용한다면 다음과 같이 작성해주시면 됩니다.
- Jenkins에 접속합니다.
- http://your-ec2-public-ip:8088/에서 Jenkins 대시보드로 이동합니다.
- Credentials 추가하기
- Jenkins 관리 → **Credentials → System → Global credentials (unrestricted)**로 이동합니다.
- "Add Credentials" 버튼을 클릭합니다.
- Secret File 추가하기
- Kind: Secret file 선택
- File: application.yml 파일을 로컬에서 선택하여 업로드
- ID: application-yml-file (ID는 나중에 파이프라인에서 사용할 이름입니다)
- Description: Spring Boot application.yml
- 같은 방식으로 application-dev.yml 파일도 추가합니다.
- ID: application-dev-yml-file
3. 파이프라인 스크립트 작성
그리고 git 폴더 구조는 밑과 같이 되어있습니다.
/WMS (프로젝트 폴더)
├── backend (실제 소스 코드가 있는 폴더)
│ ├── gradlew
│ ├── build.gradle
│ ├── settings.gradle
│ ├── src
│ └── ...
└── .git
pipeline {
agent any
environment {
BE_IMAGE_NAME = "wms_api"
BE_CONTAINER_NAME = "wms_api"
GIT_REPO = "https://github.com/Eungae-D/WMS.git"
GIT_BRANCH = "main"
BACKEND_DIR = "backend"
}
stages {
stage('Checkout') {
steps {
echo '🔄 Checking out Git repository...'
git url: "${GIT_REPO}", branch: "${GIT_BRANCH}"
}
}
stage('Build') {
steps {
echo '🔄 Starting BackEnd Build'
// Secret File 사용하여 application.yml 및 application-dev.yml 복사
withCredentials([
file(credentialsId: 'application-yml-file', variable: 'APP_YML_PATH'),
file(credentialsId: 'application-dev-yml-file', variable: 'APP_DEV_YML_PATH')
]) {
dir("${BACKEND_DIR}") {
sh '''
# 작업 디렉터리 생성 및 권한 수정
mkdir -p ${WORKSPACE}/${BACKEND_DIR}/src/main/resources/
sudo chown -R jenkins:jenkins ${WORKSPACE}
sudo chmod -R 775 ${WORKSPACE}
# Secret 파일 복사
cp "$APP_YML_PATH" ${WORKSPACE}/${BACKEND_DIR}/src/main/resources/application.yml
cp "$APP_DEV_YML_PATH" ${WORKSPACE}/${BACKEND_DIR}/src/main/resources/application-dev.yml
# Gradle 빌드
chmod +x gradlew
./gradlew clean bootJar -Dspring.profiles.active=dev
'''
}
}
}
post {
success { echo '✅ Gradle Build Success' }
failure { echo '❌ Gradle Build Failed' }
}
}
stage('Dockerization') {
steps {
echo "🐳 Starting Docker Image Build"
dir("${BACKEND_DIR}") {
sh '''
docker rmi ${BE_IMAGE_NAME} || true
docker build -t ${BE_IMAGE_NAME}:latest .
'''
}
}
post {
success { echo "✅ Docker Image Build Success" }
failure { echo "❌ Docker Image Build Failed" }
}
}
stage('Deploy') {
steps {
script {
echo "🚀 Deploying Application"
sh '''
# 기존 컨테이너 중지 및 삭제
docker stop ${BE_CONTAINER_NAME} || true
docker rm ${BE_CONTAINER_NAME} || true
# 새로운 컨테이너 실행
docker run --name ${BE_CONTAINER_NAME} --network my-network -d -p 8080:8080 ${BE_IMAGE_NAME}:latest --spring.profiles.active=dev
'''
}
}
post {
success { echo "✅ Deployment Successful" }
failure { echo "❌ Deployment Failed" }
}
}
}
}
만약 application.yml만 사용하신다면 밑을 확인해주시기 바랍니다.
pipeline {
agent any
environment {
BE_IMAGE_NAME = "wms_api"
BE_CONTAINER_NAME = "wms_api"
GIT_REPO = "https://github.com/Eungae-D/WMS.git"
GIT_BRANCH = "main"
BACKEND_DIR = "backend"
}
stages {
stage('Checkout') {
steps {
echo '🔄 Checking out Git repository...'
git url: "${GIT_REPO}", branch: "${GIT_BRANCH}"
}
}
stage('Build') {
steps {
echo '🔄 Starting BackEnd Build'
// Secret File 사용하여 application.yml 복사
withCredentials([
file(credentialsId: 'application-yml-file', variable: 'APP_YML_PATH')
]) {
dir("${BACKEND_DIR}") {
sh '''
# 작업 디렉터리 생성 및 권한 수정
mkdir -p ${WORKSPACE}/${BACKEND_DIR}/src/main/resources/
sudo chown -R jenkins:jenkins ${WORKSPACE}
sudo chmod -R 775 ${WORKSPACE}
# Secret 파일 복사
cp "$APP_YML_PATH" ${WORKSPACE}/${BACKEND_DIR}/src/main/resources/application.yml
# Gradle 빌드
chmod +x gradlew
./gradlew clean bootJar
'''
}
}
}
post {
success { echo '✅ Gradle Build Success' }
failure { echo '❌ Gradle Build Failed' }
}
}
stage('Dockerization') {
steps {
echo "🐳 Starting Docker Image Build"
dir("${BACKEND_DIR}") {
sh '''
docker rmi ${BE_IMAGE_NAME} || true
docker build -t ${BE_IMAGE_NAME}:latest .
'''
}
}
post {
success { echo "✅ Docker Image Build Success" }
failure { echo "❌ Docker Image Build Failed" }
}
}
stage('Deploy') {
steps {
script {
echo "🚀 Deploying Application"
sh '''
# 기존 컨테이너 중지 및 삭제
docker stop ${BE_CONTAINER_NAME} || true
docker rm ${BE_CONTAINER_NAME} || true
# 새로운 컨테이너 실행
docker run --name ${BE_CONTAINER_NAME} --network my-network -d -p 8080:8080 ${BE_IMAGE_NAME}:latest
'''
}
}
post {
success { echo "✅ Deployment Successful" }
failure { echo "❌ Deployment Failed" }
}
}
}
}
완료되었다.
'프로젝트 > WMS' 카테고리의 다른 글
[CI/CD] EC2+도커+젠킨스+NIGNX 배포하기 (8) (0) | 2024.11.12 |
---|---|
[CI/CD] EC2+도커+젠킨스+NIGNX 배포하기 (7) (0) | 2024.11.08 |
[CI/CD] EC2+도커+젠킨스+NIGNX 배포하기 (5) (0) | 2024.11.07 |
[CI/CD] EC2+도커+젠킨스+NIGNX 배포하기 (4) (0) | 2024.11.06 |
[CI/CD] EC2+도커+젠킨스+NIGNX 배포하기 (3) (3) | 2024.11.05 |