본문 바로가기

Docker,Jenkins

[jenkins] docker build 후 amazon ECR로 이미지 업로드하기

728x90

1. plugin 설치

먼저 젠킨스에 Amazon ECR, docker pipeline 플러그인을 설치하고 젠킨스를 재부팅 해주세요.

2. ECR Repository 생성

ECR에 이미지를 업로드 하려면 당연히 이미지 저장소가 있어야하겠죵.
하나의 github repository마다 하나의 ECR 이미지 저장소가 필요합니다.

Create Repository를 눌러 이미지 별로 레포지토리를 생성해줍니다.

3. AWS Credentials 설정

aws credential 등록부분을 참고하여 AWS CRedentials를 등록해줍니다.
해당 계정은 ECR에 이미지를 업로드하는 권한을 가지고 있어야 합니다.

만약 aws ECR, ECS와 같은 서비스를 젠킨스에서 사용하고자 한다면 젠킨스가 aws 리소스에 접근하여 명령어를 사용할 수 있도록 credential을 등록해야합니다.

1. aws 사용자 생성


aws IAM으로 들어가 jenkins가 사용할 사용자를 추가합니다. aws cli를 사용할 예정이므로 AWS 자격 증명 유형을 프로그래밍 방식 액세스로 선택합니다.

2. aws 사용자에 권한 부여


그 다음 aws 리소스 접근에 필요한 권한을 사용자에 부여합니다.

4. 액세스 키 발급


사용자를 생성하면 이와같이 액세스 키와 비밀 액세스 키가 발급됩니다.
이를 젠킨스가 활용할 수 있도록 Jenkins Credentials에 등록하여야 합니다.

4. 액세스 키 등록


젠킨스 관리 -> manage credentials -> add credentials를 누르고
secret text 타입으로 global scope를 주어 액세스 키와 비밀 액세스 키를 따로 등록합니다.


ID를 지정해주면 파이프라인에서는 이런 형태로 불러와 환경변수로 사용할 수 있습니다.

5. aws Credentials 등록


ID(유니크하게), Access Key, Secret Access Key를 등록하여 aws 계정을 사용할 수 있도록 합니다.

 

5. 파이프라인 작성

pipeline {
    agent any
    options {
    timeout(time: 1, unit: 'HOURS') // set timeout 1 hour
    }
    
    environment {
        
        TIME_ZONE = 'Asia/Seoul'
        
        //github
        TARGET_BRANCH = 'main'
        REPOSITORY_URL= 'https://github.com/SWM-304/TeamPlanner-BE-CICD.git'

        //docker-hub
        registryCredential = 'docker-hub'

        //aws ecr
        
        CONTAINER_NAME = 'teamplanner-backend-container'
        AWS_CREDENTIAL_NAME = 'AWS_ECR'
        ECR_PATH = '129715120090.dkr.ecr.ap-northeast-2.amazonaws.com'
        IMAGE_NAME = '129715120090.dkr.ecr.ap-northeast-2.amazonaws.com/teamplanner-backendserver'
        REGION = 'ap-northeast-2'
    }

    

    stages {


        stage('init') {
            steps {
                echo 'init stage'
                deleteDir()
            }
            post {
                success {
                    echo 'success init in pipeline'
                }
                failure {
                    error 'fail init in pipeline'
                }
            }
        }
        
        stage('Prepare') {
            steps {
                echo 'Cloning Repository'
                git branch: 'main', 
                    credentialsId: 'repo-and-hook-access-token-credentials', 
                    url: 'https://github.com/SWM-304/TeamPlanner-BE-CICD.git'
            }
            post {
                success {
                    echo 'Successfully Cloned Repository'
                }
                failure {
                    error 'This pipeline stops here...'
                }
            }
        }
       // 일단은 테스트없이 빌드
        stage('Build Gradle') {
            steps {
                echo 'Build Gradle'

                dir('.'){
                    sh '''
                        pwd
                        cd /var/jenkins_home/workspace/teamPlannerBackEnd_jenkinsFile
                        chmod +x ./gradlew
                        ./gradlew build --exclude-task test
                    '''
                }
            }
            post {
                failure {
                    error 'This pipeline stops here...'
                }
            }
        }
       // 도커 이미지를 만든다. build number로 태그를 주되 latest 태그도 부여한다.
        stage('Build Docker') {
            steps {
                echo 'Build Docker'
                sh """
                    cd /var/jenkins_home/workspace/teamPlannerBackEnd_jenkinsFile
                    docker builder prune
                    docker build -t $IMAGE_NAME:$BUILD_NUMBER .
                    docker tag $IMAGE_NAME:$BUILD_NUMBER $IMAGE_NAME:latest
                """
            }
            post {
                failure {
                    error 'This pipeline stops here...'
                }
            }
        }
       // 빌드넘버 태그와 latest 태그 둘 다 올린다.
        stage('Push Docker') {
            steps {
                echo 'Push Docker'
                script {
                    // cleanup current user docker credentials
                    sh 'rm -f ~/.dockercfg ~/.docker/config.json || true'
                    
                    docker.withRegistry("https://${ECR_PATH}", "ecr:${REGION}:${AWS_CREDENTIAL_NAME}") {
                        docker.image("${IMAGE_NAME}:${BUILD_NUMBER}").push()
                        docker.image("${IMAGE_NAME}:latest").push()
                    }
                }
            }
            post {
                failure {
                    error 'This pipeline stops here...'
                }
            }
        }
  
    stage('Clean Up Docker Images on Jenkins Server') {
        steps {
            echo 'Cleaning up unused Docker images on Jenkins server'

            // Clean up unused Docker images, including those created within the last hour
            sh "docker image prune -f --all --filter \"until=1h\""
        }
    }


        
}

    post {
        success {
            slackSend (channel: '#cicd-notification', color: '#00FF00', message: "SUCCESSFUL: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})")
        }
        failure {
            slackSend (channel: '#cicd-notification', color: '#FF0000', message: "FAILED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})")
        }
    }
}

 

728x90