IT/CI_CD

AWS EC2 젠킨스, 도커로 배포 자동화하기

binary? 2024. 9. 27. 07:35

AWS EC2 젠킨스, 도커로 배포 자동화하기

 

이번에 취업한 회사는 Jenkins와 Docker를 이용하여 배포 자동화 시스템이 구축되어 있습니다. 젠킨스는 첫 회사에서 사용해 보았지만 이미 구축된 시스템에 빌드 및 배포를 하고 에러 발생 시 에러 잡아주곤 했었습니다.

개인 프로젝트에 젠킨스와 도커를 도입하면서 어떻게 동작하는 건지 좀 더 자세히 알아보겠습니다. 아래에 배포 자동화하는 방법을 정리해 보겠습니다. 이번에는 깔끔한 정리보다는 중간에 에러 나는 것도 다 집어넣었습니다.

AWS - EC2 환경에서 젠킨스 및 도커를 설치하는 방법은 아래 포스팅에 정리해놨습니다.

https://jindduya.tistory.com/92

 

AWS EC2 ubuntu 젠킨스 설치

AWS EC2 ubuntu 젠킨스 설치 개인 프로젝트에서 AWS EC2를 사용하고 있습니다. 취직해서 개인 프로젝트에 조금 뜸해졌는데 드디어 젠킨스와 도커를 도입하려고 합니다. ㅎㅎ 먼저 AWS에 젠킨스 설치부

jindduya.tistory.com

https://jindduya.tistory.com/93

 

AWS Docker 설치

AWS Docker 설치 이번 포스팅에서는 AWS EC2에 도커를 설치해보겠습니다. 이전 포스팅에서 젠킨스를 설치했기 때문에 도커도 설치가 된다면 다음 포스팅에서는 배포자동화를 해보도록 하겠습니다.

jindduya.tistory.com

 

 

 

환경을 구축하는 것은 프로젝트마다 다르겠지만 제가 진행한 방법은 아래와 같습니다.

배포자동화 요약

1. 수정한 코드를 Github에 Push한다.

2. Jenkins에서 push되는 직후 자동으로 Clone을 받고 build하여 War파일을 생성한다.

3. 도커의 기존 컨테이너와 이미지를 삭제한다.

4. Dockerfile에 작성된 내용을 기반으로 War파일을 이미지로 만든다.

5. 이미지와 컨테이너를 실행하여 서버를 기동한다.

1. Dockerfile 생성

  • 프로젝트 최상단에 Dockerfile을 생성합니다.

  • Dockerfile을 작성합니다.
  • 프로젝트마다 다르겠지만 저는 Jenkins에서 빌드하여 생성된 war파일을 실행하는 이미지를 만들도록 작성하였습니다.

2. 젠킨스 자동화 파이프라인 구축

  • Jenkins 관리 - Plugins 클릭

  • Availablu plugins 메뉴에서 docker 검색 후 Docker Pipline 설치

  • Jenkins 파이프라인 구축

  • 파이프라인 생성

  • 파이프라인 스크립트 작성
  • 저도 처음 구축하면서 글을 작성하다 보니 에러가 많이 발생했습니다.
  • 바로 아래에 있는 스크립트는 최종 스크립트가 아니므로 최종 스크립트는 포스팅 하단 부근에서 확인해 보시길 바랍니다.
  • 스크립트 작성 후 저장 클릭
pipeline {
    agent any
    stages {
        stage('Clone Repository') {
            steps {
                git 'https://github.com/ljs14741/bitcoin.git'
            }
        }
        stage('Build Docker Image') {
            steps {
                script {
                    dockerImage = docker.build("bitcoin-app")
                }
            }
        }
        stage('Run Docker Container') {
            steps {
                script {
                    dockerImage.run('-p 8080:8080')
                }
            }
        }
    }
}
 

 

젠킨스 빌드하기

  • 에러 발생

  • 빌드번호를 클릭하고 Console Output에서 확인해 보면 왜 에러가 났는지 확인할 수 있습니다.

  • 에러 내용을 보면 인증에 실패한 것을 볼 수 있습니다.
  • git 인증하러 가보겠습니다.

3. 깃허브 Personal Access Tocken (PAT) 생성하기

  • 깃허브에서 프로필 사진을 클릭합니다.

  • Settings - Developer settings 클릭

  • Generate new token(classic) 클릭

  • 기간 설정하면 귀찮아질 거 같아서 No expiration 선택

  • repo를 체크해야 Jenkins가 리포지토리에서 코드를 클론할 수 있다고 합니다.
  • repo: 프라이빗 저장소에 대한 접근을 포함하여, 저장소에 대한 풀 액세스 권한을 제공합니다. 이 스코프는 소스 코드 체크아웃, 브랜치 생성, 커밋 푸시 등 저장소 관련 작업을 할 때 필요합니다.
  • admin:repo_hook: 저장소의 webhook 관리할 수 있게 합니다. 이는 Jenkins가 GitHub 저장소에 webhook 자동으로 추가하거나 수정할 때 필요할 수 있습니다.

  • 한번 생성한 토큰은 다시 볼 수 없으므로 저장해둬야 합니다.

  • Jenkins 관리 - Credentials 클릭

  • Store scoped to Jenkins - system 클릭

  • Global credentials 클릭

  • Add Credentials 클릭

  • 아래처럼 작성하고 Create 클릭
  • username: github ID
  • password: PTA 토큰

  • 생성 완료

  • Pipeline script 수정 - 방금 생성한 credentials ID 추가
pipeline {
    agent any
    stages {
        stage('Clone Repository') {
            steps {
                git credentialsId: 'github_binary', url: 'https://github.com/ljs14741/bitcoin.git'
            }
        }
        stage('Build WAR') {
            steps {
                sh './gradlew clean build'
            }
        }
        stage('Build Docker Image') {
            steps {
                script {
                    dockerImage = docker.build("bitcoin-app")
                }
            }
        }
        stage('Run Docker Container') {
            steps {
                script {
                    dockerImage.run('-p 8080:8080')
                }
            }
        }
    }
}
 

 

  • 다시 젠킨스 빌드 실행 시 또 에러 발생
  • 이번엔 빌드 시 권한이 없어서 에러가 난 것으로 보입니다.

  • 권한 설정하러 AWS-EC2로 이동
cd /var/lib/jenkins/workspace/bitcoin 
ls -l ./gradlew // 파일 권한 확인
sudo chmod +x ./gradlew // 파일 실행 권한 추가

 

 

 

  • 확인 결과 쓰기 권한 추가된 것을 확인하였습니다.

  • 하지만 다시 젠킨스 빌드 실행 시 또 에러 발생
  • 또 실패해서 확인해 보니 파일 권한이 원래대로 돌아감. -> Jenkins가 새로 Clone하면서 권한이 덮어씌워진 걸로 보입니다.
  • 파이프라인에다가 추가해버렸습니다.
pipeline {
    agent any
    stages {
        stage('Clone Repository') {
            steps {
                git credentialsId: 'github_binary', url: 'https://github.com/ljs14741/bitcoin.git'
            }
        }
        stage('Grant Permissions') {
            steps {
                sh 'chmod +x ./gradlew'
            }
        }
        stage('Build WAR') {
            steps {
                sh './gradlew clean build'
            }
        }
        stage('Build Docker Image') {
            steps {
                script {
                    dockerImage = docker.build("bitcoin-app")
                }
            }
        }
        stage('Run Docker Container') {
            steps {
                script {
                    dockerImage.run('-p 8080:8080')
                }
            }
        }
    }
}
 

 

  • 다시 젠킨스 빌드 실행 시 또 에러 발생
  • ㅋㅋㅋ 아 무슨 에러가 이렇게 많은지 모르겠네요. 이번엔 Docker에 권한 없다고 하는 거 같습니다.

  • EC2에서 젠킨스가 도커를 사용할 수 있게 권한 설정
sudo usermod -aG docker jenkins
sudo systemctl restart jenkins
groups jenkins
 

 

  • groups jenkins 했을 때 docker가 나오면 된다고 합니다.

  • 다시 젠킨스 실행
  • 홀리쮓~~! 드디어 된다 ㅋㅋ
  • 서버 올라갈 때 로그도 나오고, docker run까지 에러 없이 실행되며 SUCCESS가 나왔습니다.

  • 잘 되는지 확인하기 위해 빌드하기 전에 서버 내려놨었는데 서버도 올라간 것을 확인했습니다.

  • 아래 명령어로 도커가 잘 실행됐는지 확인할 수 있습니다.
sudo docker ps -> 컨테이너 및 이미지 확인
sudo systemctl status docker -> 도커 상태 확인
docker logs [Container ID] -> 서버 로그 확인
sudo docker exec -it [Container ID] /bin/bash -> Dockerfile에서 만든 app폴더 확인
 

4. 파이프라인 재구축 (파이프라인 최종 스크립트)

  • 젠킨스 파이프라인을 구축하여 도커 이미지를 만들고 실행하는 작업은 완료되었습니다.
  • 추가적으로 기존의 컨테이너와 이미지를 지우는 작업도 추가했습니다.
pipeline {
    agent any
    stages {
        stage('Clone Repository') {
            steps {
                git credentialsId: 'github_binary', url: 'https://github.com/ljs14741/bitcoin.git'
            }
        }
        stage('Grant Permissions') {
            steps {
                sh 'chmod +x ./gradlew'
            }
        }
        stage('Build WAR') {
            steps {
                sh './gradlew clean build'
            }
        }
        stage('Cleanup Old Container') {
            steps {
                script {
                    // 기존 컨테이너 중지 및 삭제
                    sh "docker stop bitcoin-app || true"  // 컨테이너가 없으면 무시
                    sh "docker rm bitcoin-app || true"    // 삭제
                }
            }
        }
        stage('Build Docker Image') {
            steps {
                script {
                    dockerImage = docker.build("bitcoin") // 이미지 명칭 
                }
            }
        }
        stage('Run Docker Container') {
            steps {
                script {
                    dockerImage.run('-p 8080:8080 --name bitcoin-app') //컨테이너 명칭
                }
            }
        }
        stage('Cleanup Old Images') {
            steps {
                script {
                    // 사용하지 않는 Docker 이미지 정리
                    sh "docker image prune -f"
                }
            }
        }
    }
}
 
  • 위 스크립트로 빌드를 해보면 설정한 이미지 명칭, 컨테이너 명칭들로 생성
  • 컨테이너 ID가 삭제되고 새로 생성되면서 신규 ID로 생성

5. Github Push하면 자동으로 Jenkins 빌드하기

  • 드디어 자동 배포의 마지막 설정입니다.
  • Github 프로젝트 - Settings - Webhooks - Add webhook

  • 웹훅
  • Webhook(웹훅)이란, 특정 이벤트가 발생하였을 때 타 서비스나 응용프로그램으로 알림을 보내는 기능입니다. 웹훅을 사용하지 않는다면 젠킨스는 폴링 기술로 깃허브 레포지토리에 업데이트가 발생했는지 주기적으로 확인해 주어야 합니다.
  • 웹훅을 사용하면 깃허브에 변화사항이 발생하면 젠킨스에게 알림을 보내주기 때문에 젠킨스에서는 주기적으로 레포지토리의 변화사항을 체크할 필요가 없습니다.

  • payload URL 은 젠킨스url/github-webhook/
  • 사진처럼 payload URL 마지막에 '/' 슬러시를 안 넣으면 에러 나서 꼭 넣어주세요.
  • 아래처럼 체크하고 Add webhook 클릭

  • Jenkins로 와서 Build -Triggers - Github hook trigger for GITScm polliing 체크

  • 이제 IntelliJ에서 Github로 Push를 진행했습니다.
  • 하지만 Jenkins의 빌드가 실행되지 않았습니다.
  • Github에 Webhooks를 확인해 보니 302에러가 발생했습니다.

  • Payload URL의 마지막에 '/' 슬러시를 추가해 주니까 에러가 해결되었습니다.

  • 이후 다시 IntelliJ에서 Push를 진행했습니다.
  • Jenkins를 확인해 보니 자동으로 빌드가 진행되고 있었습니다!!

  • 젠킨스 로그 보는 방법
  • Jenkins 관리 - System Log

  • 젠킨스 로그를 보면 깃허브에 푸시 이후에 자동으로 빌드가 돌아가고 있음을 확인할 수 있습니다.

  • 드디어 끝났습니다~~ ㅋㅋㅋ
  • 처음에 말한 대로 이렇게 설정하면 Github에 푸시 하면 자동으로 서버가 종료했다가 재기동하게 되므로 정말 편해졌습니다.
  • 중간에 에러도 많이 나고 해서 잘 정리된 포스팅은 아니지만 문득 에러 과정을 포함하는 게 더 나을 거 같아서 지우지 않았습니다.
  • AWS EC2 환경에서 Jenkins와 Docker로 자동 배포하는 방법을 알아보았습니다.
  • 혼자서 처음 구축하는 거라 굉장히 시간도 많이 들고 어려웠는데 역시 하면 되네요!
  • 포스팅 보고 도움이 되셨으면 좋겠습니다. 감사합니다~

'IT > CI_CD' 카테고리의 다른 글

AWS EC2 Potainer 설치  (3) 2024.10.01
젠킨스 환경변수 설정하는 방법  (0) 2024.09.29
AWS EC2 ubuntu 젠킨스 설치  (2) 2024.09.23
jenkins 젠킨스 다운로드하는 방법  (2) 2024.05.23