컴공생의 발자취

GitHub tag & Docker Image 자동 배포하기 (feat. Jenkins) 본문

🐳 Docker

GitHub tag & Docker Image 자동 배포하기 (feat. Jenkins)

MNY 2024. 10. 13. 17:41
728x90
반응형
Keyword
  1. Github release & tag
  2. docker tag

 

 버전 관리를 하는 이유 

  • 코드의 백업 및 복구: 버전 관리를 통해 코드의 모든 변경 이력을 저장하고, 필요시 특정 시점으로 쉽게 되돌아갈 수 있습니다. 이는 문제가 발생했을 때 빠른 복구를 가능하게 합니다.
  • 변경 이력 추적: 각 커밋마다 어떤 변경이 있었는지 기록되므로, 코드의 진화를 추적할 수 있습니다. 이를 통해 문제의 원인을 파악하고 수정하는 데 도움이 됩니다.
  • 협업 및 병합 관리: 팀 내 여러 개발자가 동시에 작업할 때, 각자의 작업 내용을 체계적으로 관리하고 병합할 수 있습니다. 깃에서 태그된 커밋이 특정 브랜치에 푸시 또는 머지될 때, 해당 버전을 명확하게 관리하여 프로젝트의 안정성과 품질을 유지할 수 있습니다.

 

추가로 고민해보면 좋은 것

→ Docker private repository setting

docker image를 관리하기 위해서 어떤 repository를 사용하면 좋을까?

  1. GitHub 컨테이너 레지스트리 : 유료
  2. Docker
    1. public
    2. private : 1개까지 무료

결론 : Docker public으로 해도 문제가 없는 프로젝트 규모

 

 Jenkins script 업데이트 

pipeline {
    agent any

    // 현재 다 삭제해놔서 문제 없음...
    environment { 
        // Docker Hub credentials
        DOCKER_HUB_CREDENTIALS = 'docker-hub-credentials'
        DOCKER_HUB_REPO = 'ysy561356/today-space-back'
        DOCKER_CONTAINER = 'today-space-back'
        
        // Github credentials
        GIT_CREDENTIALS_ID = 'github-token'
        GIT_BRANCH = 'release'
        GIT_URL = 'https://github.com/today-space/today-space-back.git'
        
        // EC2
        SSH_CREDENTIALS_ID = 'ec2-ssh-key'
        EC2_USER = 'ubuntu'
        EC2_DOMAIN = 'back.today-space.com'
        
        // DB
        DB_URL = 'jdbc:postgresql://postgresql.today-space.com:5432/space'
        DB_USERNAME = 'youngju'
        DB_PASSWORD = '4564'
        
        // JWT
        JWT_SECRET_KEY = '7Iqk7YyM66W07YOA7L2U65Sp7YG065+9c3ByaW5n7Ius7ZmU7KO87LCo7JWE7JuD7IaM7Iux7ZSE66Gc7KCd7Yq47YyM7J2067iM66CI7KCE65Oc7YyAand0c2VjcmV0a2V5'
        JWT_ACCESS_TOKEN_EXPIRATION = 1800000
        JWT_REFRESH_TOKEN_EXPIRATION = 1209600000
        
        // Social Login
        KAKAO_REST_API_KEY = '6cd61cbdb917a1046bf437980b1e2ac9'
        NAVER_REST_API_KEY = 'mgvICujU1zvQrtz_IQOA'
        NAVER_REST_API_SECRET_KEY = 'drUb2lRtGb'
        GOOGLE_REST_API_KEY = '878062679505-oh34mk7fm5mpipprk9o139i8if40b3qf.apps.googleusercontent.com'
        GOOGLE_REST_API_SECRET_KEY = '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'
        
    }

    stages {
	      stage('Clone Git Repository') {
            steps {
                script {
                    // GitHub 저장소에서 코드 클론
                    git credentialsId: "${GIT_CREDENTIALS_ID}", branch: "${GIT_BRANCH}", url: "${GIT_URL}"
                    
                    // gradlew 파일에 실행 권한 부여
                    sh 'chmod +x gradlew'
                    
                    // Gradle 빌드
                    sh './gradlew build'
                    
                    // destination 디렉토리 생성
                    sh 'mkdir -p ../destination'
                    sh 'mkdir -p ../destination/build/libs'
                    
                    // JAR 파일과 Dockerfile을 특정 경로로 이동
                    sh 'cp build/libs/*.jar ../destination/build/libs'
                    sh 'cp Dockerfile ../destination/'
                }
            }
        }
			  stage('Prepare .env') {
		        steps {
		            script {
		                sh '''
		                touch ../destination/back.env
		                echo DB_URL=$DB_URL > ../destination/back.env
				            echo DB_USERNAME=$DB_USERNAME >> ../destination/back.env
			              echo DB_PASSWORD=$DB_PASSWORD >> ../destination/back.env
			              echo JWT_SECRET_KEY=$JWT_SECRET_KEY >> ../destination/back.env
			              echo JWT_ACCESS_TOKEN_EXPIRATION=$JWT_ACCESS_TOKEN_EXPIRATION >> ../destination/back.env
			              echo JWT_REFRESH_TOKEN_EXPIRATION=$JWT_REFRESH_TOKEN_EXPIRATION >> ../destination/back.env
			              echo KAKAO_REST_API_KEY=$KAKAO_REST_API_KEY >> ../destination/back.env
			              echo NAVER_REST_API_KEY=$NAVER_REST_API_KEY >> ../destination/back.env
			              echo NAVER_REST_API_SECRET_KEY=$NAVER_REST_API_SECRET_KEY >> ../destination/back.env
			              echo GOOGLE_REST_API_KEY=$GOOGLE_REST_API_KEY >> ../destination/back.env
			              echo GOOGLE_REST_API_SECRET_KEY=$GOOGLE_REST_API_SECRET_KEY >> ../destination/back.env
			              echo FRONT_URL=$FRONT_URL >> ../destination/back.env
			              echo KAKAO_PAY_SECRET_KEY=$KAKAO_PAY_SECRET_KEY >> ../destination/back.env
			              echo KAKAO_PAY_URL=$KAKAO_PAY_URL >> ../destination/back.env
			              echo KAKAO_PAY_CID=$KAKAO_PAY_CID >> ../destination/back.env
			              '''
		            }
		        }
		    }
		    stage('Build and Push Docker Image') {
		        steps {
		            script {
		                dir('../destination') { // 특정 경로로 이동
				                // Git 태그를 이용해 버전 설정
				                def gitTag = sh(returnStdout: true, script: 'git describe --tags --always').trim()
				                def dockerImage = docker.build("${DOCKER_HUB_REPO}:${gitTag}", "./")
		                  
				                
		                    // Docker Hub에 로그인
		                    withCredentials([usernamePassword(credentialsId: DOCKER_HUB_CREDENTIALS, usernameVariable: 'DOCKER_USERNAME', passwordVariable: 'DOCKER_PASSWORD')]) {
		                        sh 'echo $DOCKER_PASSWORD | docker login -u $DOCKER_USERNAME --password-stdin'
		                    }
		                    
		                    // docker 이미지 태그별 push
		                    dockerImage.push("${gitTag}")
		                    dockerImage.push("latest")		                }
		            }
		        }
		    }
        stage('Deploy') {
            steps {
                script {
                    withCredentials([sshUserPrivateKey(credentialsId: "${SSH_CREDENTIALS_ID}", keyFileVariable: 'SSH_KEY')]) {
                        def sshKey = env.SSH_KEY
                        
                        // 권한 변경
                        sh 'chmod 400 ' + sshKey
                        
                        // docker-compose down
                        sh 'ssh -v -o StrictHostKeyChecking=no -i ' + sshKey + ' ${EC2_USER}@${EC2_DOMAIN} "docker-compose down"'
                        
                        // docker image pull
                        sh 'ssh -v -o StrictHostKeyChecking=no -i ' + sshKey + ' ${EC2_USER}@${EC2_DOMAIN} "docker pull ${DOCKER_HUB_REPO}:${DOCKER_IMAGE_TAG}"' // 이미지 명시

                        // 새로운 docker-compose 시작
                        sh 'ssh -v -o StrictHostKeyChecking=no -i ' + sshKey + ' ${EC2_USER}@${EC2_DOMAIN} "docker-compose up -d"'

                    }
                }
            }
        }
    }
    post {
        always {
            cleanWs()
        }
        success {
            echo 'Deployment successful!'
        }
        failure {
            echo 'Deployment failed!'
        }
    }
}

 

 

 Github 웹 인터페이스에서 태그 생성 

  1. GitHub 리포지토리 페이지로 이동합니다.
  2. Code 탭에서 Releases 버튼을 클릭합니다.
  3. Draft a new release 버튼을 클릭합니다.
  4. Tag version 필드에 태그 이름을 입력합니다.
  5. Target 필드에서 태그를 달고 싶은 커밋을 선택합니다.
  6. Release titleDescription을 입력하고, Publish release 버튼을 클릭합니다.

GitHub에서 릴리즈(Release) 생성하기

  1. GitHub 리포지토리 페이지로 이동합니다.
  2. Code 탭에서 Releases 버튼을 클릭합니다.
  3. Draft a new release 버튼을 클릭합니다.
  4. Tag version 필드에 태그 이름을 입력합니다.
    • 새 태그를 생성하려면 새 태그 이름을 입력하고, 기존 태그를 선택하려면 드롭다운에서 선택합니다.
  5. Release title 필드에 릴리즈 제목을 입력합니다.
  6. Describe this release 필드에 릴리즈에 대한 설명을 작성합니다.
  7. 필요에 따라 바이너리 파일이나 다른 자산을 업로드할 수 있습니다.
  8. Publish release 버튼을 클릭합니다.

 

 참고 자료 

 

dev-quiz-backend/Jenkinsfile at main · spartaSpringTeamA6/dev-quiz-backend

SpartaCodingClub 최종프로젝트 A6조 DevQuiz입니다. Contribute to spartaSpringTeamA6/dev-quiz-backend development by creating an account on GitHub.

github.com

 

 

728x90
반응형