0%

Jenkins로 배포(CD) 자동화하기

Jenkins로 배포(CD) 자동화하기

이전 글에 이어지는 내용입니다. 저번 글에서 Jenkins를 설치했으니 이번에는 Jenkins를 사용해서 배포 자동화를 해보겠습니다.

jenkins 설정

Jenkins Plugin 설치

docker Pipeline을 설치합니다. Manage Jenkins -> Manage Plugins -> Available -> Docker Pipeline 설치.

Github Token 생성

전에 추가한 github Token에 권한을 추가해도 되지만, 관리 편의를 위해서 새로운 Token을 생성합니다. Settings -> Developer settings -> Personal access tokens -> Generate new token (classic)

권한은 다음과 같이 설정합니다.
gh-token

Jenkins Credential 추가

Jenkins에서도 새로운 Credential을 추가합니다. Manage Jenkins -> Manage Credentials -> Stores scoped to Jenkins -> Global credentials (unrestricted) -> Add Credentials

ghcr

docker socket 권한 설정

Jenkins 컨테이너 내부에서 외부 docker에 대해 명령어를 사용하기 위한 설정을 해줍니다. docker-compose.yml파일에 - /var/run/docker.sock:/var/run/docker.sock를 추가해 줍니다.

1
2
3
4
5
6
7
8
9
jenkins:
image: jenkins/jenkins:lts
container_name: jenkins
ports:
- "8080:8080"
volumes:
- jenkins_home:/var/jenkins_home
- /var/run/docker.sock:/var/run/docker.sock #새로 추가
restart: unless-stopped

또한 Jenkins 컨테이너 내부에서 docker 명령어를 사용하기 위해서 추가 설정해줍니다.

1
2
3
4
5
6
7
8
9
10
# Jenkins 컨테이너에 접속
docker exec -u root -it jenkins /bin/bash

# 도커 설치
apt-get update
apt-get install docker.io

# Jenkins 컨테이너 삭제 후 재시작
docker rm -f jenkins
docker-compose up -d jenkins

jenkins 컨테이너에 접속해서 docker 명령어를 정상 작동하면 성공입니다.
docker-ps

Dockerfile 생성

Docker bulid를 위한 Dockerfile을 생성합니다. repository root에 Dockerfile이라는 파일을 생성합니다.

1
2
3
4
FROM amazoncorretto:17
EXPOSE 8080
COPY build/libs/*SNAPSHOT.jar /app/spring-app.jar
ENTRYPOINT ["java","-jar","/app/spring-app.jar"]

Jenkinsfile 수정

Jenkinsfile을 수정합니다.

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
pipeline {
agent any

environment {
GHCR_URL = 'ghcr.io'
IMAGE_NAME = 'ghcr.io/<유저네임>/<리포지토리명>'
}

stages {
stage('Login to GHCR') {
steps {
script {
docker.withRegistry("https://${env.GHCR_URL}", 'ghcr_credentials') {}
}
}
}
stage('Checkout') {
steps {
echo 'Checking out the repository...'
checkout scm
}
}
stage('Build') {
steps {
echo 'Building the application...'
sh 'chmod +x gradlew'
sh './gradlew clean build -x test'
}
}
stage('Test') {
steps {
echo 'Running tests...'
sh './gradlew test'
}
}
stage('Build Image') {
steps {
sh "docker build -t ${env.IMAGE_NAME}:latest ."
}
}
stage('Push Image') {
steps {
script {
docker.withRegistry("https://${env.GHCR_URL}", 'ghcr_credentials') {
docker.image("${env.IMAGE_NAME}:latest").push()
}
}
}
}
}
}

확인

  • https://github.com/<본인 이름>?tab=packages에 들어가서 이미지가 잘 올라갔는지 확인합니다.
    package

ssh 설정

Plugin에서 SSH Agent가 설치되지 않았다면 설치해 줍니다. 설치가 됐으면 키 설정을 해줍니다.

jenkins > Manage Jenkins > Credentials > System > Global credentials (unrestricted) > Add Credentials에서 SSH Username with private key를 추가합니다. 그러면 다음과 같은 화면이 보입니다.

ssh
username은 서버의 username을 입력하고, private key는 이전 글에서 발급한 서버의 private key를 입력합니다.

Jenkinsfile 수정 해서 ssh로 서버에 배포하기

environment에 SSH관련정보와 GHCR관련 정보를 추가합니다.

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
pipeline {
agent any

environment {
GHCR_URL = 'ghcr.io'
IMAGE_NAME = 'ghcr.io/marinesnow34/jenkins-test'
SSH_USER = credentials('ARM_SSH_USER')
SSH_HOST = credentials('ARM_SSH_HOST')
GHCR_USERNAME = 'marinesnow34'
GHCR_PASSWORD = credentials('ghcr_credentials')
}

stages {
... 생략

stage('Deploy on Server') {
steps {
sshagent(['arm-ssh-credential']) {
sh """
ssh -o StrictHostKeyChecking=no ${SSH_USER}@${SSH_HOST} "
echo '${GHCR_PASSWORD}' | docker login ${GHCR_URL} -u ${GHCR_USERNAME} --password-stdin
docker pull ${IMAGE_NAME}:latest
docker stop app || true && docker rm app || true
docker run -d --name app ${IMAGE_NAME}:latest
"
"""
}
}
}
}
}

sshagent를 사용해서 ssh로 서버에 접속하고, docker 명령어를 사용해서 이미지를 pull하고, 컨테이너를 실행합니다.

컨테이너가 잘 실행되었는지 확인합니다.
jenkins

마무리

이렇게 Jenkins를 사용해서 CI/CD 배포 자동화를 해보았습니다. 아직은 Jenkins의 간단한 사용법만 알아봤지만, Jenkins는 다양한 플러그인을 사용해서 작업을 간단히 자동화할 수 있는 방법이 많습니다. Jenkins를 사용해서 더 많은 작업을 편하게 자동화 해봅시다.