본문 바로가기

study/CICD

CICD 스터디 1주차 두번째

젠킨스를 사용해 보겠습니다.

 

Jenkins Item 생성 : item name(first) - docker 명령 실행 확인

Build Steps : Execute shell ⇒ Save 후 지금 빌드 : Console Output 확인

echo "docker check" | tee test.txt
docker ps

 

 

 

 

Gogs Repo 자격증명 설정(gogs-dev-app) : Jenkins 관리 → Credentials → Globals → Add Credentials

 

 

Jenkins Item 생성 : item name(second) - 소스코드관리(Git) 설정 + 빌드 파라미터

+아래 사진처럼 설정

 

 

Build Steps : Execute shell

echo "{$FirstPara}"
cat VERSION

 

 

 

확인(버전 정보 출력)

 

 

파이프라인

 

파이프라인 Pipeline : CD 파이프라인을 구현하고 통합할 때 사용하는 플러그인 스크립트 모음 - Docs

 

Pipeline

Jenkins – an open source automation server which enables developers around the world to reliably build, test, and deploy their software

www.jenkins.io

https://www.jenkins.io/doc/book/pipeline/

 

위 과정을 자동화 하자!! -> 전체과정을 코드로 만들어서 진행!

 

 

파이프라인 2가지 구문 : 선언형 파이프라인(권장)과 스크립트형 파이프라인

https://velog.io/@kku64r/pipeline

 

 

Jenkins Plugin 설치

  • Pipeline Stage View - Docs
  • Docker Pipeline : building, testing, and using Docker images from Jenkins Pipeline - Docs
  • Gogs : Webhook Plugin - Docs

Jenkins 도커 계정/암호 자격 증명 설정 : Add Credentials(Global) - Kind(Username with password)

  • Username : <도커 계정명>
  • Password : <도커 계정 암호 혹은 토큰>
  • ID : dockerhub-credentials ⇒ 자격증명 이름으로, pipeline 사용 예정

 

 

Jenkins Item 생성(Pipeline) : item name(pipeline-ci)

Pipeline script

pipeline {
    agent any
    environment {
        DOCKER_IMAGE = '<자신의 도커 허브 계정>/dev-app' // Docker 이미지 이름
    }
    stages {
        stage('Checkout') {
            steps {
                 git branch: 'main',
                 url: 'http://192.168.254.124:3000/devops/dev-app.git',  // Git에서 코드 체크아웃
                 credentialsId: 'gogs-dev-app'  // Credentials ID
            }
        }
        stage('Read VERSION') {
            steps {
                script {
                    // VERSION 파일 읽기
                    def version = readFile('VERSION').trim()
                    echo "Version found: ${version}"
                    // 환경 변수 설정
                    env.DOCKER_TAG = version
                }
            }
        }
        stage('Docker Build and Push') {
            steps {
                script {
                    docker.withRegistry('https://index.docker.io/v1/', 'dockerhub-credentials') {
                        // DOCKER_TAG 사용
                        def appImage = docker.build("${DOCKER_IMAGE}:${DOCKER_TAG}")
                        appImage.push()
                    }
                }
            }
        }
    }
    post {
        success {
            echo "Docker image ${DOCKER_IMAGE}:${DOCKER_TAG} has been built and pushed successfully!"
        }
        failure {
            echo "Pipeline failed. Please check the logs."
        }
    }
}

 

 

성공!

 

도커허브도 확인

 

 

 

도커 기반 애플리케이션 CI/CD 구성

 

Gogs Webhooks 설정 : Jenkins Job Trigger

gogs 에 app.ini 파일 수정 후 컨테이너 재기동 - issue

 

Clone address resolved to a local network address that is implicitly blocked · Issue #7109 · gogs/gogs

Gogs version 0.13.0+dev Git version Server: 2.32.2 Client: 2.20.1 Operating system debian11 Database SQLite 3 Describe the bug my gogs is on the docker, ip: 192.168.1.184 I use another machine to a...

github.com

 

[security]
INSTALL_LOCK = true
SECRET_KEY   = j2xaUPQcbAEwpIu
LOCAL_NETWORK_ALLOWLIST = 192.168.254.124 # 각자 자신의 PC IP

 

 

Payload URL : http://192.168.254.124:8080/gogs-webhook/?job=**SCM-Pipeline**/

Content Type : application/json

Secret : qwe123

When should this webhook be triggered? : Just the push event

Active : Check

 

설정완료

 

 

 

Jenkins Item 생성(Pipeline) : item name(SCM-Pipeline)

  • GitHub project : http://***<mac IP>***:3000/***<Gogs 계정명>***/dev-app ← .git 은 제거
  • Use Gogs secret : qwe123
  • Build Triggers : Build when a change is pushed to Gogs 체크
  • Pipeline script from SCM
    • SCM : Git
      • Repo URL(http://***<mac IP>***:3000/***<Gogs 계정명>***/dev-app)
      • Credentials(devops/***)
      • Branch(*/main)
    • Script Path : Jenkinsfile

Jenkinsfile 작성 후 Git push

jenkins 컨테이너(혹은 로컬에서 git 작업)에서 아래 작업

# Jenkinsfile 빈 파일 작성
docker compose exec jenkins touch /var/jenkins_home/dev-app/Jenkinsfile

# 버전 0.0.2 수정 : 아래 입력 잘 안될 경우 VSCODE(Docker플러그인)에서 직접 수정
docker compose exec jenkins sh -c 'echo "0.0.2" > /var/jenkins_home/dev-app/VERSION'

 

VSCODE 로 jenkins 컨테이너 내부 파일 Open 후 작성

pipeline {
    agent any
    environment {
        DOCKER_IMAGE = '<자신의 도커 허브 계정>/dev-app' // Docker 이미지 이름
    }
    stages {
        stage('Checkout') {
            steps {
                 git branch: 'main',
                 url: 'http://192.168.254.124:3000/devops/dev-app.git',  // Git에서 코드 체크아웃
                 credentialsId: 'gogs-dev-app'  // Credentials ID
            }
        }
        stage('Read VERSION') {
            steps {
                script {
                    // VERSION 파일 읽기
                    def version = readFile('VERSION').trim()
                    echo "Version found: ${version}"
                    // 환경 변수 설정
                    env.DOCKER_TAG = version
                }
            }
        }
        stage('Docker Build and Push') {
            steps {
                script {
                    docker.withRegistry('https://index.docker.io/v1/', 'dockerhub-credentials') {
                        // DOCKER_TAG 사용
                        def appImage = docker.build("${DOCKER_IMAGE}:${DOCKER_TAG}")
                        appImage.push()
                    }
                }
            }
        }
    }
    post {
        success {
            echo "Docker image ${DOCKER_IMAGE}:${DOCKER_TAG} has been built and pushed successfully!"
        }
        failure {
            echo "Pipeline failed. Please check the logs."
        }
    }
}

 

작성된 파일 push : jenkins 컨테이너 bash 내부 진입해서 작업 진행 ← 호스트에서 직접 작업하셔도 됩니다.

#
docker compose exec jenkins bash
---------------------------------
cd /var/jenkins_home/dev-app/
git add . && git commit -m "Jenkinsfile add & VERSION 0.0.2 Changed" && git push -u origin main

 

돌아간다!

 

한 번 실패 후 다시..!

 

 

확인

 

 

Final : 도커 빌드 후 기존 컨테이너 중지/제거 후 신규 컨테이너 실행 Jenkinsfile pipeline 수정 후 빌드 (SCM-Pipeline)

Jenkinsfile 수정 후 git push → tcp (기본값:4000) 는 파라미터로 입력 받게 설정하게 해볼것

pipeline {
    agent any
    environment {
        DOCKER_IMAGE = '<자신의 도커 허브 계정>/dev-app' // Docker 이미지 이름
        CONTAINER_NAME = 'dev-app' // 컨테이너 이름
    }
    stages {
        stage('Checkout') {
            steps {
                 git branch: 'main',
                 url: 'http://192.168.254.124:3000/devops/dev-app.git',  // Git에서 코드 체크아웃
                 credentialsId: 'gogs-dev-app'  // Credentials ID
            }
        }
        stage('Read VERSION') {
            steps {
                script {
                    // VERSION 파일 읽기
                    def version = readFile('VERSION').trim()
                    echo "Version found: ${version}"
                    // 환경 변수 설정
                    env.DOCKER_TAG = version
                }
            }
        }
        stage('Docker Build and Push') {
            steps {
                script {
                    docker.withRegistry('https://index.docker.io/v1/', 'dockerhub-credentials') {
                        // DOCKER_TAG 사용
                        def appImage = docker.build("${DOCKER_IMAGE}:${DOCKER_TAG}")
                        appImage.push()
                        appImage.push("latest")  // 빌드 이미지 push 할 때, 2개의 버전(현재 버전, latest 버전)을 업로드
                    }
                }
            }
        }
        stage('Check, Stop and Run Docker Container') {
            steps {
                script {
                    // 실행 중인 컨테이너 확인
                    def isRunning = sh(
                        script: "docker ps -q -f name=${CONTAINER_NAME}",
                        returnStdout: true
                    ).trim()
                    
                    if (isRunning) {
                        echo "Container '${CONTAINER_NAME}' is already running. Stopping it..."
                        // 실행 중인 컨테이너 중지
                        sh "docker stop ${CONTAINER_NAME}"
                        // 컨테이너 제거
                        sh "docker rm ${CONTAINER_NAME}"
                        echo "Container '${CONTAINER_NAME}' stopped and removed."
                    } else {
                        echo "Container '${CONTAINER_NAME}' is not running."
                    }
                    
                    // 5초 대기
                    echo "Waiting for 5 seconds before starting the new container..."
                    sleep(5)
                    
                    // 신규 컨테이너 실행
                    echo "Starting a new container '${CONTAINER_NAME}'..."
                    sh """
                    docker run -d --name ${CONTAINER_NAME} -p 4000:80 ${DOCKER_IMAGE}:${DOCKER_TAG}
                    """
                }
            }
        }
    }
    post {
        success {
            echo "Docker image ${DOCKER_IMAGE}:${DOCKER_TAG} has been built and pushed successfully!"
        }
        failure {
            echo "Pipeline failed. Please check the logs."
        }
    }
}

 

 

컨테이너 확인

docker image
docker ps
curl http://127.0.0.1:4000

 

 

server.py 수정 후 VERSION 수정 후 push 후 생성된 컨테이너 접속 후 반영 확인

# server.py 수정
response_string = now.strftime("The time is %-I:%M:%S %p, Study 1week End.\n")

# VERSION 수정

# Jenkins 컨테이너 내부에서 git push
jenkins@5c1ba7016f9e:~/dev-app$ git add . && git commit -m "VERSION $(cat VERSION) Changed" && git push -u origin main

# 호스트 PC에서 반복 접속 실행 : 서비스 중단 시간 체크!
while true; do curl -s --connect-timeout 1 http://127.0.0.1:4000 ; date; sleep 1 ; done

 

 

확인

'study > CICD' 카테고리의 다른 글

CICD 스터디 3주차 두번째  (0) 2024.12.22
CICD 스터디 3주차 첫번째  (0) 2024.12.22
CICD 스터디 2주차  (1) 2024.12.15
CICD 스터디 1주차 첫번째  (1) 2024.12.06