[INFRA / EC2 /Jenkins] 서버 자동 배포 A to the Z (3) - 젠킨스/Docker를 활용한 SpringBoot 자동배포

sammy·2024년 8월 10일
0

INFRA

목록 보기
6/7
post-thumbnail

잘못된 부분 지적 및 피드백은 큰 힘이 됩니다 😃


이번 포스팅에서는 이전에 구매한 도메인으로 백엔드 서버를 리버스 프록시 적용해보고, 젠킨스와 Docker Hub를 활용하여, SpringBoot API 백엔드 서버를 자동 배포해보도록 하겠습니다. 우선 리버스 프록시가 무엇인지 알아보도록 하겠습니다.

리버스 프록시란?

리버스 프록시는 클라이언트(사용자)의 요청을 받아 다른 서버로 전달하고, 그 서버로부터 받은 응답을 다시 클라이언트에게 반환하는 역할을 하는 서버입니다. 쉽게 말해, 웹 서버가 외부의 클라이언트로부터 직접적인 요청을 받는 대신, 리버스 프록시가 그 요청을 가로채어 내부 서버로 전달해주는 중간 매개체 역할을 합니다.

이러한 리버스 프록시는 여러 가지 장점을 제공합니다.

  • 보안 강화: 내부 서버의 IP 주소와 구조를 외부에 노출하지 않아 보안을 강화할 수 있습니다.
  • 로드 밸런싱: 여러 대의 서버로 들어오는 트래픽을 균등하게 분배하여 서버의 부하를 줄일 수 있습니다.
  • SSL 종료: SSL/TLS 처리를 리버스 프록시가 대신함으로써, 내부 서버는 복잡한 SSL 설정 없이 HTTP로만 통신할 수 있습니다.

리버스 프록시 NginX 설정 파일에 적용하기

  • NginX 설정파일을 다음과 같이 수정합니다. 젠킨스가 8080 포트를 사용하기 때문에, 백엔드는 임의의 포트인 8084 포트를 사용하도록하겠습니다.
sudo vi /etc/nginx/sites-available/default
server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name 구매한도메인주소 www.구매한도메인주소;

    location /api/ {
        proxy_pass http://localhost:8084;  # 백엔드 서버 포트번호
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

다음으로 젠킨스를 설치하고, 기본 설정 및 Docker를 사용한 자동배포 설정을 진행해보도록 하겠습니다.

젠킨스

Docker로 Jenkins 설치

1. Jenkins Docker 이미지를 가져오고, 이미지를 잘 가져왔는지 확인해봅니다.

sudo docker pull jenkins/jenkins:lts
이미지 설명
이미지 설명

2. Jenkins 이미지를 활용해 컨테이너를 실행합니다.

  • 필요한 볼륨 마운트와 포트 매핑을 설정합니다.
  • localhost:8080/jenkins 이런식으로 접속하기 원하기 때문에 prefix 지정을 해줍니다.
    docker run -d -p 8080:8080 -p 50000:50000 --name jenkins -u root \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -v /jenkins:/var/jenkins_home \
    -e JENKINS_OPTS="--prefix=/jenkins" \
    jenkins/jenkins:lts
    • d: 백그라운드에서 컨테이너를 실행합니다.
    • p 8080:8080: 호스트의 8080 포트를 컨테이너의 8080 포트에 매핑합니다.
    • p 50000:50000: 호스트의 50000 포트를 컨테이너의 50000 포트에 매핑합니다 (Jenkins 에이전트 연결용).
    • -name jenkins: 컨테이너 이름을 jenkins로 지정합니다.
    • v jenkins_home:/var/jenkins_home: 볼륨을 마운트하여 Jenkins 데이터를 호스트의 jenkins_home 디렉토리에 저장합니다.

3. 방화벽과 인바운드 규칙을 편집해줍니다.

  • 방화벽을 열어줍니다.
     sudo ufw allow 8080
      sudo ufw reload
  • AWS 홈페이지에서 편집하고자 하는 EC2의 보안에 들어가 인바운드 규칙을 편집해줍니다.

4. Jenkins 초기 설정을 합니다.

  • Docker 컨테이너가 실행 중이면, 웹 브라우저에서 http://<your_server_ip>:8080/jenkins으로 접속합니다. 그럼 다음과 같은 화면이 나오는데, 초기 비밀번호를 확인하려면 다음 명령어를 사용합니다.

    이미지 설명
    sudo docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword
  • 비밀번호 입력 후, Install suggested plugins를 선택하면 웬만한 플러그인은 미리 다 설치됩니다.

    이미지 설명
  • ID, Password, Name, Email을 등록하여 아이디를 만듭니다.

  • Jenkins URL로는 일단 http://www.내도메인:8080/jenkins/로 작성해줍니다. (이후, SSL 인증서를 통해 https 처리를 한 후, 변경해줄 예정입니다.)

  • 설정이 완료되면 다음과 같은 화면을 볼 수 있습니다.

    이미지 설명

5. NginX 설정 파일에 Jenkins를 추가합니다.

  • Nginx 설정 파일을 엽니다.
    sudo vi /etc/nginx/sites-available/default
  • 다음과 같이 Jenkins 프록시 설정을 추가합니다.
    server {
        listen 80 default_server;
        listen [::]:80 default_server;
        server_name 구매한도메인 www.구매한도메인;
        
        location /api/ {
            proxy_pass http://localhost:8084;  # 백엔드 서버의 포트 번호
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    
        location /jenkins {
            proxy_pass http://localhost:8080/jenkins;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }
  • Nginx 설정을 저장하고 종료한 후, Nginx를 재시작합니다.
    sudo nginx -t
    sudo systemctl restart nginx

[Trouble Shooting] 접속시 CSS가 깨지는 오류 발생한다면? ⚠️

이미지 설명

💡 prefix 설정이 잘못되어 리버스 프록시에서 오류가 난 것이기 때문에 설정을 다시 한번 확인하시면 됩니다.

Github 젠킨스 연결

1. SSH 키 생성

아래 명령어를 사용하여 SSH 키를 생성합니다.

ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

여기서 "your_email@example.com"을 자신의 이메일 주소로 바꿉니다.

  1. 명령어 실행 후 몇 가지 질문이 나옵니다. 기본값을 사용하려면 Enter 키를 누릅니다.
  2. 패스프레이즈 설정을 원할 경우 입력하고, 아니면 그냥 Enter를 두 번 눌러 넘어갑니다.

이 과정을 마치면 id_rsaid_rsa.pub 두 파일이 생성됩니다.

2. Jenkins 컨테이너 내부 SSH 키 파일 권한 설정 및 github 리포지토리 접근 확인

Jenkins 컨테이너 내부에서 SSH 키 파일의 소유자와 권한을 올바르게 설정하여 Jenkins가 GitHub 리포지토리에 접근할 수 있도록 하는 과정입니다. 이를 통해 SSH 키 파일이 Jenkins 사용자에 의해 읽히고 사용될 수 있게 설정합니다.

문제를 해결하기 위해 다음 단계를 시도해 보세요:

1. Jenkins 컨테이너 내부에서 .ssh 디렉토리를 생성합니다.

 docker exec -it jenkins /bin/bash
 mkdir -p /var/jenkins_home/.ssh

2. 호스트에서 Jenkins 컨테이너로 SSH 키 파일을 복사합니다.

 # 호스트 시스템에서 실행
 docker cp /root/.ssh/id_rsa jenkins:/var/jenkins_home/.ssh/id_rsa
 docker cp /root/.ssh/id_rsa.pub jenkins:/var/jenkins_home/.ssh/id_rsa.pub

3. Jenkins 컨테이너 내부에서 복사한 파일의 권한을 설정합니다.

 docker exec -it jenkins /bin/bash
 
 # Jenkins 컨테이너 내부에서 실행
 chown jenkins:jenkins /var/jenkins_home/.ssh/id_rsa
 chown jenkins:jenkins /var/jenkins_home/.ssh/id_rsa.pub
 chmod 600 /var/jenkins_home/.ssh/id_rsa
 chmod 644 /var/jenkins_home/.ssh/id_rsa.pub
 

4. 연결 테스트

 # SSH 연결 테스트
 ssh -i /var/jenkins_home/.ssh/id_rsa -T git@github.com

3. Github Repository에서 Deploy Key 설정

Deploy 키 즉, 해당 레퍼지토리에만 접근할 수 있는 SSH 키를 설정해야 합니다.

  • 연결할 Github Repository에서 Setting > Deploy keys > Add deploy key를 클릭합니다.

    이미지 설명
  • Title은 마음대로 적어도 되지만, Jenkins로 지어 주고, Key 부분에 id_rsa.pub에 들어있는 public key 값을 넣어 주고, Add key 버튼을 클릭합니다. 이때, public key 값은 다음 명령어를 통해 확인할 수 있습니다.

    cat ~/.ssh/id_rsa.pub
    이미지 설명

4. Github AccessKey 발급

Settings > Developer settings > Personal access tokens

  • GitHub에 로그인한 후, 우측 상단의 프로필 사진을 클릭하고Settings > Developer settings > Personal access tokens을 선택합니다.
  • Generate new token 버튼을 클릭합니다.
  • Note 필드에 토큰의 용도를 적고, 필요한 권한을 선택합니다. 예를 들어, repo, admin:repo_hook 등이 있습니다.
    이미지 설명
  • Generate token 버튼을 클릭하면 액세스 토큰이 생성됩니다.

5. Jenkins에 Github 자격증명 추가

SSH key 등록

  1. Jenkins에 로그인한 후, Manage Jenkins > Manage Credentials를 클릭합니다.

     <div style="margin-top: -20px;">
    이미지 설명
  2. (global) 범위를 선택하고 Add Credentials를 클릭합니다.

    이미지 설명
  3. 그럼 다음과 같은 화면이 나오는데 다음과 같이 설정 내용을 적어줍니다.

    이미지 설명
    • Kind를 SSH Username with private key로 설정합니다.
    • Username 필드에 GitHub 사용자 이름을 입력합니다.
    • Private Key 섹션에서 Enter directly를 선택하고, 개인 키(id_rsa 파일)의 내용을 붙여넣습니다.
      cat ~/.ssh/id_rsa
    • IDDescription을 적절히 입력하고 create 버튼을 클릭합니다.
      • ID 필드는 Jenkins 내부에서 이 자격 증명을 참조할 때 사용할 식별자입니다. 이 필드는 다른 자격 증명과 구분하기 위해 입력해두는 것이 좋습니다.
    • 그럼 다음과 같이 자격 증명이 만들어진 것을 확인할 수 있습니다.
      이미지 설명

Personal Access Token (Access Key) 등록

  • kind를 Username with password로 설정하고, Username에는 Github 사용자 이름, Password에는 발급 받은 Access Token을 입력하고, 해당 자격 증명을 식별하기 위해 ID를 부여합니다.

Docker Hub

1. Docker Hub Repository 생성

  1. Docker Hub에 로그인:

    • Docker Hub 웹사이트에 로그인합니다.
  2. 새 리포지토리 생성:

    • 오른쪽 상단의 프로필 아이콘을 클릭하고 Repositories를 선택합니다.

    • Create Repository 버튼을 클릭합니다.

    • Repository Name을 입력합니다. 예를 들어, your-username/your-repository.

    • Visibility를 선택합니다 (저는 보안상 Private을 설정했습니다).


    • Create 버튼을 클릭하여 리포지토리를 생성합니다.

이제 Docker Hub에 리포지토리가 생성되었으므로 Jenkins Pipeline을 통해 이 리포지토리에 Docker 이미지를 푸시할 수 있습니다.

2. Docker Hub Access Token 생성

Access Token의 이점

비밀번호 대신 Access Token을 사용하면 다음과 같은 이점이 있습니다.

  • 보안 강화

    • 비밀번호보다 토큰을 사용하면 계정이 노출되었을 때 더 안전하게 관리할 수 있습니다. 비밀번호가 유출될 경우 계정 전체가 위험하지만, Access Token은 특정 권한과 범위로 제한될 수 있어 피해를 줄일 수 있습니다.
  • 관리 편의성

    • 여러 시스템에서 동일한 계정을 사용하는 경우, 각각의 시스템에 별도의 토큰을 발급해 사용할 수 있어 관리가 용이합니다. 필요시 토큰을 개별적으로 취소하거나 재발급할 수 있습니다.
  • 회전 가능성

    • Access Token은 필요시 쉽게 회전(재발급)할 수 있어, 주기적으로 보안을 강화하는데 유리합니다.

Access Token 생성하기

  • Docker Hub에 로그인: Docker Hub에 로그인합니다.

  • 오른쪽 상단의 프로필 아이콘을 클릭하고, "Account Settings"를 선택합니다.

  • "Security" 탭을 클릭합니다.

  • "New Access Token" 버튼을 클릭하고, 토큰에 대한 이름을 입력한 후, "Create"를 클릭합니다.

    이미지 설명
  • 토큰 복사: 생성된 토큰을 복사하고 안전한 곳에 저장합니다. 이 토큰은 이후 다시 볼 수 없으므로 반드시 저장해야 합니다.

    이미지 설명

3. Jenkins에 Docker Plugin 설치

Jenkins 대시보드 > Jenkins 관리 > 플러그인 관리 > 설치 가능 > Docker 검색 > Docker, Docker Pipeline 플러그인 설치 및 재실행

이미지 설명
이미지 설명

3. Docker Hub 자격 증명 추가

  1. Jenkins 대시보드에서 자격 증명을 추가합니다.

    이미지 설명
    • Jenkins 대시보드에서 Manage Jenkins > Manage Credentials로 이동합니다.
    • (global) 범위를 선택하고 Add Credentials를 클릭합니다.
    • KindUsername with password로 설정합니다.
    • Username에 Docker Hub 사용자 이름을 입력합니다.
    • Password에 직전에 만든 Docker Hub AccessKey를 입력합니다.
    • ID에 자격 증명의 식별자를 입력합니다.
    • Description에 자격 증명의 설명을 입력합니다.
    • OK를 클릭하여 저장합니다.
    • 자격증명이 잘 만들어진걸 확인합니다.
      이미지 설명

4. Jenkins Container 내부에 Docker 설치

이 과정을 통해 Jenkins 컨테이너 내부에 Docker를 설치하고, Jenkins Pipeline에서 Docker 명령어를 사용할 수 있게 됩니다.

우선, Jenkins 컨테이너에 접속하여 Docker가 기존에 설치가 되어있는지 확인한 결과 설치가 되어있지 않았습니다.

이미지 설명
  • Jenkins 컨테이너에 접속

    • 먼저, Jenkins 컨테이너에 root 권한으로 접속합니다.

       docker exec -it -u root 컨테이너명 bash
  • Docker 설치

    • 컨테이너 내부에 필요한 패키지를 설치합니다. Jenkins 컨테이너는 보통 최소한의 패키지만 포함되어 있으므로, 추가 패키지를 설치해야 합니다.

      # 필요한 패키지 설치
      apt-get update
      apt-get install -y sudo wget apt-transport-https ca-certificates curl software-properties-common
    • docker.io 설치하기

      apt-get update
      apt-get install -y docker.io
      chmod 666 /var/run/docker.sock
  • Docker 명령어 정상적으로 동작하는지 확인합니다.

     docker --version
    이미지 설명

EC2 서버 자격증명 추가

이 자격증명은 Jenkins가 SSH를 통해 EC2 인스턴스나 다른 서버에 접근하여 애플리케이션을 배포하거나 명령을 실행할 수 있게 합니다.

  • Jenkins 대시보드에서 자격 증명 관리로 이동:

    • Jenkins 대시보드에서 Manage Jenkins > Manage Credentials로 이동합니다.
    • (global) 범위를 선택하고 Add Credentials를 클릭합니다.
  • SSH 키 자격 증명 추가:

    이미지 설명
    • KindSSH Username with private key로 설정합니다.
    • ID를 입력합니다 (이 ID는 Jenkinsfile에서 참조됩니다).
    • Usernameubuntu를 입력합니다 (EC2 인스턴스의 기본 사용자 이름).
    • Private Key 섹션에서 Enter directly를 선택하고, 다운로드한 .pem 파일의 내용을 붙여넣습니다.
      • 이때 .pem 키는 Mac에서 터미널 열고, cat “pem키 있는 경로” 를 통해 얻을 수 있습니다.
    • Create를 클릭하여 저장합니다.

Jenkins Job

새로운 Job 생성

  • Jenkins 대시보드에서 Create a job 버튼을 클릭합니다.
  • 새로운 페이지에서 Job의 이름을 입력하고, Pipeline을 선택한 후 OK 버튼을 클릭합니다.
    이미지 설명

Jenkins, Github Webhook 연동

Github Repository에 push/merge event가 발생했을 때 자동으로 Build가 실행되게 하기 위해 Pipeline과 Github Webhook을 연동해야 합니다.

1. Github Integration Plugin 설치

Jenkins 대시보드 > Jenkins 관리 > 플러그인 관리 > 설치 가능 > Github Integration 플러그인을 검색하고 설치 및 재실행합니다.

이미지 설명

2. Jenkins Pipeline 설정

  • Github project 설정

    • Pipeline 구성 화면 > General 영역에서 Github project를 선택한다. Project url에 본인의 Github Repository Url을 입력한다. 이때, Repository Url은 Clone 시 사용하는 HTTPS Url을 입력합니다.
      이미지 설명
  • Build Triggers 설정

    • Pipeline 구성 화면 > Build Triggers 영역에서 GitHub hook trigger for GITScm polling을 선택합니다.
      이미지 설명

3. Github Webhook 추가

  • GitHub 리포지토리에서 Settings > Webhooks > Add Webhook으로 이동합니다.

  • Payload URL에 <Jenkins Server URL>:<Jenkins Server 포트>/github-webhook/을 입력합니다. 이때, 마지막에 / 붙이는거에 주의합니다.

  • Content type을 application/x-www-form-urlencoded으로 설정합니다.

  • Which events would you like to trigger this webhook?에서 'Let me select individual events.'를 클릭합니다.

    이미지 설명
    • Pull requestsPush 이벤트를 선택합니다.
      이미지 설명

4. Application.yml 파일 주입

Jenkins 파이프라인에서 application.yml 파일을 추가하거나 배포 환경에 전달하는 작업을 설정하는 가장 일반적인 방법은 application.yml 파일을 Jenkins의 Config File Provider 플러그인을 사용하여 관리하고, Jenkins Pipeline 스크립트에 이를 반영하는 것입니다.

Jenkins Config File Provider 플러그인 사용

  1. Config File Provider 플러그인 설치:

    • Jenkins의 Jenkins 관리 > Manage Plugins > Available에서 Config File Provider 플러그인을 설치합니다.
      이미지 설명
  2. Config File 설정:

    • Jenkins 관리 > Managed files로 이동하여 새로운 Config File을 추가합니다.
      이미지 설명
    • Custom file 또는 YAML 형식을 선택하고, application.yml 내용을 추가합니다. 또한, Jenkins Pipeline 스크립트에서 사용할 ID를 지정해줍니다. (만약, S3를 사용하기 위한 yml파일도 있다면, 같은 방법으로 추가해줍니다.)
      이미지 설명
  3. Jenkins Pipeline 스크립트 작성 파일 배포 추가:

    • Jenkins Pipeline 스크립트에서 해당 파일을 사용하는 단계에 파일을 배포하도록 설정합니다. 이 작업은 바로 다음 단계에서 이어가도록 하겠습니다.

5. Jenkins Pipeline 스크립트 작성

백엔드 SrpingBoot server는 젠킨스와 포트번호가 겹치지 않게 8084 포트로 돌립니다.

  • 우선, 8084 방화벽을 열어주고, 인바운드 규칙을 수정해줍니다.(인바운드 규칙은 사용자 지정 TCP 8084, 0.0.0.0/0으로 설정해줍니다.)
sudo ufw allow 8084
sudo ufw enable
sudo ufw status
  • 이전에 만든 젠킨스 파이프라인에 다음과 같이 작성해줍니다.

       pipeline {
           agent any
    
           environment {
               DOCKERHUB_CREDENTIALS = '직전에 만든 dockerhub 식별 ID'
               REPO_URL = 'https://github.com/your-repository.git'
               IMAGE_NAME = 'your-dockerhub-username/repository-name'
           }
    
           stages {
               stage('Checkout') {
                   steps {
                       git url: "${env.REPO_URL}", branch: 'your-branch', credentialsId: '직전에 만든 github-accesskey 식별 ID'
                   }
               }
               stage('Prepare Config Files') {
                   steps {
                       // Config File Provider 플러그인에서 관리하는 application.yml 파일을 작업 디렉토리에 복사
                       configFileProvider([
                           configFile(fileId: 'application-yml-config', targetLocation: '프로젝트명/src/main/resources/application.yml'),
                           configFile(fileId: 'application-aws-yml-config', targetLocation: '프로젝트명/src/main/resources/application-aws.yml')
                       ]
                       ) {
                           sh 'echo "Config file copied to resources folder"'
                       }
                   }
               }
               stage('Build Gradle') {
                   steps {
                       sh './gradlew build -x test'            
                   }
               }
    
               stage('Build Docker Image') {
                   steps {
                       script {
                           def image = docker.build("${env.IMAGE_NAME}:${env.BUILD_NUMBER}", "-f Dockerfile .")
                           docker.withRegistry('', "${env.DOCKERHUB_CREDENTIALS}") {
                               image.push()
                           }
                           sh """
                           docker images --filter=reference='${env.IMAGE_NAME}*' --format '{{.ID}}' | tail -n +4 | xargs -r docker rmi -f
                           """
                       }
                   }
               }
    
               stage('Deploy to Server') {
                   steps {
                       script {
                           sh "docker pull ${env.IMAGE_NAME}:${env.BUILD_NUMBER}"
                           sh "docker stop app-container || true"
                           sh "docker rm app-container || true"
                           sh "docker run -d --name app-container -p 8084:8084 ${env.IMAGE_NAME}:${env.BUILD_NUMBER}"
                       }
                   }
               }
           }
    
           post {
               always {
                   cleanWs()
               }
           }
       }
    

Trouble Shooting

저는 다음과 같은 오류가 발생했었습니다.

ERROR: Error cloning remote repo 'origin


SSH 키가 제대로 설정된 것 같지만, Jenkins가 GitHub에 접근할 때 known_hosts 파일이 없어서 문제가 발생하고 있습니다.
1. Jenkins 컨테이너 내부에서 known_hosts 파일 확인

 cat /var/jenkins_home/.ssh/known_hosts
  1. 만약 파일이 없다면
    ssh-keyscan 명령어를 사용해 GitHub의 호스트 키를 known_hosts 파일에 추가해야 합니다.

     ssh-keyscan github.com >> /var/jenkins_home/.ssh/known_hosts
  2. 파일 권한을 다시 설정

    chown jenkins:jenkins /var/jenkins_home/.ssh/known_hosts
    chmod 644 /var/jenkins_home/.ssh/known_hosts
  3. Jenkins에서 Git 플러그인 설정:

    • Jenkins 관리 > 보안 > Git Host Key Verification Configuration에서 "Known hosts file" 전략을 선택하고 경로를 /var/jenkins_home/.ssh/known_hosts로 설정합니다.
  4. 추가적으로 시도해본 사항

  • sudo: ./gradlew: command not found에러로 빌드가 진행되지 않았습니다.

    • chmod +x ./gradlew를 통해 권한 설정을 해주었고, ./gradlew명령어를 사용할 수 있게 되었습니다.
  • 도커 파일을 못찾는 이슈 ⚠️

    failed to read dockerfile: open /var/lib/docker/tmp/buildkit-mount2095907826/Dockerfile: no such file or directory
    • 현재 Github에서 springbootApp 디렉터리 안에 DockerFilegradlew이 들어 있기 때문에, pipeline 스크립트를 다음과 같이 설정해주어야 합니다.
      • 도커파일 경로를 잘 지정해주어야 합니다.
         def image = docker.build("${env.IMAGE_NAME}:${env.BUILD_NUMBER}", "-f path/to/Dockerfile .")
      • gradlew 경로를 잘 지정해주어야 합니다.
        stage('Build Gradle') {
           steps {
               dir('your-gradlew-folder') {
                   sh './gradlew build -x test'
               }
           }
        }
  • 결국 수정된 전체 코드는 다음과 같습니다.

    pipeline {
       agent any
    
       environment {
           DOCKERHUB_CREDENTIALS = '직전에 만든 dockerhub 식별 ID'
           REPO_URL = 'https://github.com/your-repository.git'
           IMAGE_NAME = 'your-dockerhub-username/repository-name'
       }
    
       stages {
           stage('Checkout') {
               steps {
                   git url: "${env.REPO_URL}", branch: 'your-branch', credentialsId: '직전에 만든 github-accesskey 식별 ID'
               }
           }
           stage('Prepare Config Files') {
               steps {
                   // Config File Provider 플러그인에서 관리하는 application.yml 파일을 작업 디렉토리에 복사
                   configFileProvider([
                       configFile(fileId: 'application-yml-config', targetLocation: '프로젝트명/src/main/resources/application.yml'),
                       configFile(fileId: 'application-aws-yml-config', targetLocation: '프로젝트명/src/main/resources/application-aws.yml')
                   ]
                   ) {
                       sh 'echo "Config file copied to resources folder"'
                   }
               }
           }
           stage('Build Gradle') {
               steps {
                   dir('your-gradlew-folder') {
                       sh './gradlew build -x test'
                   }
               }
           }
    
           stage('Build Docker Image') {
               steps {
                   script {
                       def image = docker.build("${env.IMAGE_NAME}:${env.BUILD_NUMBER}", "-f path/to/Dockerfile .")
                       docker.withRegistry('', "${env.DOCKERHUB_CREDENTIALS}") {
                           image.push()
                       }
                       sh """
                       docker images --filter=reference='${env.IMAGE_NAME}*' --format '{{.ID}}' | tail -n +4 | xargs -r docker rmi -f
                       """
                   }
               }
           }
    
           stage('Deploy to Server') {
               steps {
                   script {
                       sh "docker pull ${env.IMAGE_NAME}:${env.BUILD_NUMBER}"
                       sh "docker stop app-container || true"
                       sh "docker rm app-container || true"
                       sh "docker run -d --name app-container -p 8084:8084 ${env.IMAGE_NAME}:${env.BUILD_NUMBER}"
                   }
               }
           }
       }
    
       post {
           always {
               cleanWs()
           }
       }
    }

여기까지 완료 하셨으면, 다음과 같이 동작합니다.

  1. 특정 브랜치로 push/merge 이벤트가 들어온다.
  2. 젠킨스가 스크립트를 실행하면서, 특정 브랜치를 chekout 한다.
  3. build를 진행한다.
  4. 도커 이미지로 만들어 Docker Hub에 push하고, EC2 서버에서 이 이미지를 pull 받아 8084 포트로 백엔드 서버를 컨테이너를 띄운다.

다음 포스팅에서는 젠킨스 빌드 과정 가시화 및 Slack 연동을 진행해보도록 하겠습니다.

profile
누군가에게 도움을 주기 위한 개발자로 성장하고 싶습니다.

0개의 댓글

관련 채용 정보