728x90
반응형
이번에 젠킨스를 이용하여 Spring Boot를 CI/CD 파이프라인 구축하는 것에 대해 글을 작성해보려 합니다. 많은 오류와 시행착오 속에서 어떻게 해결했는지 알아보겠습니다.

🔥빌드 순서
- Code push to Github
- Build By Jenkins
- Push to Docker hub
- Docker run
🔥기술 스택
- Spring Boot / Gradle
- Docker
- Github
- Jenkins
- NCP - Server
- Slack
spring 서버와 jenkins 서버를 따로 두었다.
compact 서버는 월 4~5만원 정도

- 신규 가입하면 10만 크레딧을 지원해줘서 micro는 너무 답답하여 compact를 사용했습니다.
- 공인 IP를 연결하고, ACG를 설정해줍니다.
- 포트 포워딩을 해줍니다.
- 작은 프로젝트라 VPC를 사용 안하고 Classic 사용
## ubuntu server jdk-11 -> jdk-17 변경하기
sudo apt update
sudo apt install openjdk-17-jdk
java -version
sudo vi /etc/environment
source /etc/environment -> JAVA_HOME="/usr/lib/jvm/java-17-openjdk-amd64" 하단에 넣기
echo $JAVA_HOME
# 아래와 같이 나오면 성공
/usr/lib/jvm/java-17-openjdk-amd64
🖥️서버가 자꾸 터질 때
서버 내에 스왑 파일을 생성하고, 가상 메모리 기법을 활성화 하여 가상 메모리 공간을 마련해 안정적으로 동작할 수 있게
$ sudo dd if=/dev/zero of=/swapfile bs=128M count=16
$ sudo chmod 600 /swapfile
$ sudo mkswap /swapfile
$ sudo swapon /swapfile
$ sudo swapon -s
$ sudo vi /etc/fstab
/swapfile swap swap defaults 0 0
#안에 데이터가 있을 경우 맨 아래에 추가해주면 되요
🐬도커 설치하기
https://docs.docker.com/engine/install/ubuntu/
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo apt-key fingerprint 0EBFCD88
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt-get update
sudo apt-get install -y docker-ce
sudo usermod -aG docker root(ubuntu)
sudo curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
#도커 권한
sudo chmod 006 /var/run/docker.sock
#도커 버전
docker -v
🐬저는 스프링 부트와 젠킨스 서버를 따로 두었기 때문에 스프링 부트 서버에도 도커를 설치해줍니다.
sudo apt update
sudo apt install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt update
sudo apt install docker-ce
sudo systemctl start docker
sudo systemctl enable docker
👴🏼Jenkins 설치 및 빌드
docker run -d -p 8080:8080 -p 50000:50000 -v /jenkins:/var/jenkins -v /root/.ssh:/root/.ssh -v /var/run/docker.sock:/var/run/docker.sock --name jenkins -u root jenkins/jenkins:jdk17
# 조심) 계정이 root면 위 것으로 사용하고, ubuntu면 -v /home/ubuntu/.ssh:/root/.ssh
# 볼륨은 꼭 생성합시다!
이미지를 pull 받고 run을 돌려도 되지만, docker는 이미지가 없는 경우 docker hub에서 공식 이미지를 다운받아서 run 시켜주기 때문에 편한 방법 사용하면 되요.
Jenkins Container 조회
docker ps
docker ps -a
Jenkins 접속
#url로 접속
공인 IP:8080

#아래 코드를 입력하면 로그와 비밀번호가 뜹니다.
docker logs jenkins


🐬Dockerfile 작성

FROM openjdk:17-alpine
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
#왼쪽과 같이 도커 파일을 생성하고 플러그인을 설치해줍니다.
#이후에 깃허브에 push
git add Dockerfile
git commit -m 'Docs : add Dockerfile'
git push
👴🏼🐱Jenkins, Github 연동
- 공개키, 비밀키 생성(Jenkins Server)
Jenkins Container를 생성할 때 "/root/.ssh:/root/.ssh"로 .ssh 디렉토리를 마운트 해놓았기 때문에
Container 밖에서 ssh 키를 생성하면 Jenkins Container와 연결된다.
# 그냥 전부 enter를 입력해 default로 만든다.
ssh-keygen
# /root/.ssh에 id_rsa와 id_rsa.pub이 생성된다.
ls /root/.ssh
id_rsa id_rsa.pub known_hosts
#id_rsa : prvate key
#id_rsa.pub : public key -> 깃허브
- Github Deploy Key 등록
Github Repository > Setting > Deploy Keys > Add deploy key 선택
title은 아무거나 입력
# 공개키 복붙하고 key에 아래 내용을 넣어주면 된다.
# ssh-rsa 이렇게 시작할텐데 처음부터 끝까지 전부 붙여주면 된다.
cat /root/.ssh/id_rsa.pub
- Jenkins Credentials 등록
- Jenkins 대시보드 > Jenkins 관리 > Security > Credentials
# Stores scoped to Jenkins에 Domain이 (global)인 text 클릭
# Global credentials (unrestricted)로 이동한다.
# 왼쪽 메뉴의 Add credentials를 눌러 credentials를 추가
#KindSSH
Username with private key
#ID
github
#Username
root (default)
#Private Key
Enter directly 체크 -> private key 입력
여기서 private key는 Jenkins Server에서 생성한 id_rsa이다. 아래 명령어로 확인 가능하다.
cat /root/.ssh/id_rsa
# 이것도 -----BEGIN RSA PRIVATE KEY----- 시작할텐데 전부 붙여 넣기.
- Git clone을 위한 권한 설정
- Jenkins 대시보드 > System > Github





token을 복사하고 secret에 넣어준 후에 test connection을 해줍니다.
그리고 git clone 파이프 라인 생성을 위해 Add로 하나 더 생성해 줍니다.

Username -> github 아이디
Password -> access token
ID -> 구분 가능한 이름
👴🏼🐬Jenkins, Docker hub 연결
Docker Plugin 설치
- Jenkins 대시보드 > Jenkins 관리 > plugins > Available plugins
Docker, Docker Pipeline 검색 후 설치 및 재실행
== docker restart 컨테이너ID(젠킨스 서버에서 docker ps -a로 검색가능)
- Docker Hub Credencials 등록
- Jenkins 대시보드 > Jenkins 관리 > Security > Credentials
# Kind
Username with password
# Username
본인의 Docker Hub ID
# Password
본인의 Docker Hub Password
# ID
docker-hub
- Jenkins 내부에 Docker 설치
docker exec -u root -it jenkins /bin/bash
# 리눅스 버전
cat /etc/issu
# Docker 설치
## - Old Version Remove
apt-get remove docker docker-engine docker.io containerd runc
## - Setup Repo
apt-get update -y
apt-get install -y\
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 -y
apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin -y
👴🏼🖥️Jenkins, Spring Boot Server SSH 연결
Jenkins Server == 유저 == 비밀키
Spring Server == 서버 == 공개키
Jenkins 대시보드 > Jenkins 관리 > 플러그인 관리 > 설치 가능 > SSH Agent
플러그인을 검색하고 설치 및 재실행
Spring Server에 공개키 설정(.ssh/authorized_keys -> 공개키 추가)
# jenkins server에서
cat /root/.ssh/id_rsa.pub
# Spring server에 pub키 추가 데이터가 있다면 맨 아래에 추가
vi /root/.ssh/authorized_keys
Jenkins Credentials 등록
Jenkins 대시보드 > Jenkins 관리 > Security > Credentials
# Stores scoped to Jenkins에 Domain이 (global)인 text 클릭
# Global credentials (unrestricted)로 이동한다.
# 왼쪽 메뉴의 Add credentials를 눌러 credentials를 추가
# Kind
SSH Username with private key
# ID
ssh
# Username
root (default)
# Private Key
Enter directly 체크 -> jenkins server의 private key 입력
cat /root/.ssh/id_rsa
#이것도 전부다 입력
👴🏼🐱Jenkins, Github Webhook 설정
push가 발생했을 때 자동으로 jenkins 빌드가 실행되게
- Github Integration Plugin 설치
- Jenkins 대시보드 > Jenkins 관리 > plugins > Available plugins
Github Integration Plugin 설치 및 재실행
Jenkins Pipeline 설정
- Jenkins Pipeline 구성 > General > Github project 깃 레포 입력 > 훅 체크


🐱Github Webhook 추가
Github Repository에서 Settings > Webhooks > Add Webhook 눌러 추가한다.
# Payload URL
Jenkins Server URL:Jenkins Server 포트/github-webhook/
# Content
application/x-www-form-urlencoded
#나머지는 모두 default 설정 유지
Add webhook 버튼을 눌러 Webhook을 추가 -> 목록에서 녹색 체크 아이콘이 생성되면 성공(새로고침 해주기)
🔗Pipeline Script 생성하기



pipeline {
agent any
environment {
imagename = "kwondh/ssda" <-도커 허브 이미지명
registryCredential = 'docker-hub'
dockerImage = ''
SLACK_CHANNEL = "#jenkins"
SLACK_SUCCESS_COLOR = "#2C953C";
SLACK_FAIL_COLOR = "#FF3232";
}
stages {
stage('Git Clone') {
steps {
git branch: 'main', credentialsId: 'gitgit', url: 'Github Repository SSH Url([git@github.com 으로 시작하는 깃허브 주소])'
}
post {
success {
slackSend (
channel: SLACK_CHANNEL,
color: SLACK_SUCCESS_COLOR,
message: "===================================\n배포 파이프라인 시작되었습니다."
)
}
}
}
stage('Build Gradle') {
steps {
echo 'Build Gradle'
dir('.') {
sh './gradlew build -x test'
sh './gradlew clean build'
}
}
post {
success {
slackSend (
channel: SLACK_CHANNEL,
color: SLACK_SUCCESS_COLOR,
message: "Build Gradle 성공함ㅋㅋ"
)
}
}
}
stage('Build Docker') {
steps {
echo 'Build Docker'
script {
dockerImage = docker.build imagename
}
}
post {
success {
slackSend (
channel: SLACK_CHANNEL,
color: SLACK_SUCCESS_COLOR,
message: "Build Docker 성공함ㅋㅋ"
)
}
}
}
stage('Push Docker') {
steps {
echo 'Push Docker'
script {
docker.withRegistry( '', registryCredential) {
dockerImage.push()
}
}
}
post {
success {
slackSend (
channel: SLACK_CHANNEL,
color: SLACK_SUCCESS_COLOR,
message: "Push Docker 성공함ㅋㅋㅋ"
)
}
}
}
stage('Docker Run') {
steps {
echo 'Pull Docker Image & Docker Image Run'
sshagent(credentials: ['ssh']) {
sh "ssh -o StrictHostKeyChecking=no -p 1025 root@공인IP(spring server 아래와 같음 접속이 잘 안되면 jenkins서버에서 스프링 서버로 접속해보기) 'docker pull kwondh/ssda'" <- 도커 허브 이미지명
sh "ssh -o StrictHostKeyChecking=no -p 1025 root@106.10.32.11 'docker ps -q --filter name=ssda | grep -q . && docker rm -f \$(docker ps -aq --filter name=ssda); docker run -d --name ssda -p 8080:8080 kwondh/ssda'"
}
}
post {
success {
slackSend (
channel: SLACK_CHANNEL,
color: SLACK_SUCCESS_COLOR,
message: "배포 완료^3^\n=============================="
)
}
}
}
}
}

너무 어려웠지만 포기하지 않고 해결해 나갔다. 수정해야 할 부분이 있다면 알려주세요!! 감사합니다.
728x90
반응형