티스토리 뷰

728x90

과거에 Git 태그를 푸시하면 Docker 이미지를 생성하고 자동으로 Nexus에 푸시하는 파이프라인을 구축한 적이 있다. 하지만 당시 우리 시스템은 Docker 기반이 아니었고, 특정 프로젝트에서만 Docker 이미지를 필요로 했기 때문에 자동 배포까지는 구현하지 않았다.

 

그러나 이번에 서버 이전을 진행하면서 여러 가지를 개선하는 과정에서, 서비스 운영을 Docker 기반으로 전환하게 되었다.

일반적으로 CI/CD에서는 이미지 생성 및 푸시 후 자동으로 서버에 배포하는 방식을 많이 사용하는 것 같았다. 이는 개발 서버나 스테이징 환경에 적합하다고 생각되었고 운영 서버에서는 보다 신중한 배포가 필요하다고 판단했다.

그래서 내가 구현하려는 방식은, Nexus에서 Docker 이미지 태그 목록을 가져와 특정 태그를 선택하여 서버에 배포하는 것이다.

 

1. Active Choices 플러그인 설치

- 동적으로 파라미터를 생성하는 플러그인들이 여러개 있는 것 같다. 나는 처음에 Extended Choice Parameter 플러그인을 사용했으나...Deprecated 된다고...대체 할 수 있는 플러그인을 알려주었는데 그 중에 하나가 Active Choices 였다.

https://plugins.jenkins.io/uno-choice/

 

Active Choices

This plug-in provides additional parameter types for jobs, that allow you to cascade changes and render images or other HTML elements instead of the traditional parameter.

plugins.jenkins.io

 

2. 매개변수를 위한 groovy scripts 작성하기

- 새로운 item을 선택하여 Freestyle project 혹은 Pipeline 을 선택한다.

- '이 빌드는 매개변수가 있습니다' 를 선택 한 후 '매개변수 추가' 에서 Active Choices Parameter를 선택한다.

- Name 을 지정(나는 tag로 지정) 하고 script의 Groovy Script를 선택 한 후 아래의 스크립트를 입력해준다.

// 태그를 가져 올 이미지 이름
def image= 'image'

// Nexus API 설정
def nexusUrl = "http://nexus주소/service/rest/v1/search"
def repository = "docker-hosted" //repository 이름
def username = " " //사용자명
def password = " " //비밀번호

// Nexus API 호출 URL 생성
def apiUrl = "${nexusUrl}?repository=${repository}&name=${image}"
// API 호출
def connection = new URL(apiUrl).openConnection()
connection.setRequestProperty("Authorization", "Basic " + "${username}:${password}".bytes.encodeBase64().toString())
connection.setRequestMethod("GET")
connection.connect()

// 응답을 JSON으로 파싱
def responseText = connection.content.text

def response = new groovy.json.JsonSlurper().parseText(responseText)

// 선택된 이미지 이름에 맞는 태그 목록 추출
def tags = []
response.items.each { item ->
    println "Item: ${item.name}"  // 아이템의 이름을 출력
    if (item.name == image) {
        tags.addAll(item.version)
    }
}

// 중복 제거 후 정렬하여 반환
return tags.unique().sort().toList()

 

여기까지 저장 한 후 해당 프로젝트의 좌측에서 '파라미터와 함께 빌드' 를 선택하면 아래와 같이 select box로 해당 이미지의 태그가 표시되는 것을 확인 할 수 있다.

*use Groovy sendbox를 선택하면 보안상의 문제로 네트워크 호출을 기본적으로 차단함으로, 해제해주자!

 

 

3.  파이프라인  작성하기

서버에 SSH로 접속한 뒤, docker-compose.yml 파일의 이미지 태그를 원하는 버전으로 변경하고, 이를 반영해 서비스를 다시 실행하는 방식으로 파이프라인을 구성할 예정이다.

pipeline {
    agent any

    environment {
        DOCKER_COMPOSE_PATH = "docker-compose.yml의 위치"
        IMAGE_NAME = "이미지명"
        SSH_HOST = "컨테이너가 배포 될 서버"
        REGISTRY_URL = "도커 저장소 URL"
    }

    stages {
        stage('Check Parameters') {
            steps {
                script {
                    echo "✅Docker TAG: ${tag}"
                }
            }
        }

        stage('Deploy to Server') {
            steps {
                script {
                    withCredentials([sshUserPrivateKey(credentialsId: 'ssh-credentials-devops', keyFileVariable: 'SSH_KEY', usernameVariable: 'SSH_USER')]) {
                        sh """
                        ssh -i "$SSH_KEY" -o StrictHostKeyChecking=no "$SSH_USER@$SSH_HOST" "
                          echo '✅이미지 태그 변경 중...'
                          sudo sed -i 's|image: ${REGISTRY_URL}/${IMAGE_NAME}:.*|image: ${REGISTRY_URL}/${IMAGE_NAME}:${tag}|g' ${DOCKER_COMPOSE_PATH}
                          echo '✅변경 된 docker-compose.yml 내용'
                          cat ${DOCKER_COMPOSE_PATH}

                          sudo docker-compose -f ${DOCKER_COMPOSE_PATH} up -d
                          RUNNING_CONTAINER=\$(sudo docker ps --format '{{.Names}}' | grep '${IMAGE_NAME}' || true)

                          if [ -n \"\$RUNNING_CONTAINER\" ]; then
                            echo '✅ 컨테이너 정상 실행 '
                            sudo docker ps --filter "name=${IMAGE_NAME}"
                            docker image prune -a -f
                          else
                            echo '❌ 컨테이너 실행 실패! 로그 확인 필요.'
                            exit 1
                          fi
                        "
                        """
                    }
                }
            }
        }
    }

    post {
        success {
            echo "✅ 배포 완료: ${IMAGE_NAME}:${tag}"
        }
        failure {
            echo "❌ 배포 실패!"
        }
    }
}

 

이후, 파라미터를 선택하여 배포를 하면 아래와 같이 성공 메세지를 확인 할 수 있다!

 

젠킨스를 구축하는거는 참 쉬우면서도 어려운 일인것 같다. 왜 안되는지 에러를 파악하기가 가끔 힘들때가 있다..특히 groovy sendbox 부분 때문에 애를 많이 먹었다 ㅜㅜㅜㅜㅜ 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/04   »
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
글 보관함