본문 바로가기

[DevOps]/[CI&CD]

[AWS EC2 + Docker + Jenkins ] FastAPI 배포 자동화

728x90
 

[AWS EC2 + Docker + Jenkins ] Spring Boot 배포 자동화 - Jenkins 설치

[ 시작하며.. ] 언제 한번 쭉 정리할까 고민이였는데, 마침 배포 자동화를 할 일이 생겨서 기록으로 남기기로 한다. 한번 해보고 나면 과정은 그렇게 어렵지 않다. PC와 깃헙(혹은 깃랩 등)에서 작

buildabetterworld.tistory.com

 

[FastAPI 배포]

    EC2에 docker, docker-compose, jenkins 를 설치하는 과정은 이전과 동일하다. 다만 이번에는 새로운 커밋이 발생하면-> 이미지를 빌드해서 허브에 올리고 -> 허브에서 다시 해당 이미지를 당겨와서 -> compose로 실행하는 형태이다.

사실 Spring-boot를 배포 자동화 할 때랑 별 차이가 없으므로 바로 Jenkins를 설치해 주도록 한다.

 

[Jenkins 부분]

sudo docker pull jenkins/jenkins:lts

  아래의 명령어를 입력하여 jenkin를 실행한다.이전과 동일한 jenkins/jenkins 이미지 이다. docker 관련 볼륨을 설정해줘야 젠킨스에서 docker 명령어 사용 시 문제가 발생하지 않는다.

docker run -d --name my_jenkins \ 
-p 8080:8080 \ 
-v /jenkins:/var/jenkins_home \ 
-v /var/run/docker.sock:/var/run/docker.sock \ 
-v $(which docker):/usr/bin/docker \ 
-v /usr/local/bin/docker-compose:/usr/local/bin/docker-compose \ 
-u root jenkins/jenkins

  그 다음은 이전 포스팅과 동일하게 관리 비번을 저장해 둔다. 

docker exec my_jenkins cat /var/jenkins_home/secrets/initialAdminPassword​

  이어서 젠킨스 설치과정이다. 이 역시 동일하므로 설명은 생략한다.

 

[jenkins 작업 생성하기]

 다음은 jenkins 작업을 생성해본다. docker hub 접속을 위해 Credentials 를 생성하고, pipeline를 이용해서 스테이지 작업을 생성한다.

 

[pipeline 생성]

  pipeline를 이용해서 스테이지 별 작업을 생성한다. 이때부터는 각자 필요한 상황에 맞게 설정해주면 된다. 나는 하나의 빌드가 진행중일때, 연속으로 빌드를 진행하지 않도록 했고, Github-project의 git-url을 입력해줬다.

 

  • Do not allow concurrent builds 체크: 한 빌드가 진행 중이면 연속적인 빌드를 진행하지 않도록 한다
  • GitHub project: 자동화하고자 하는 프로젝트 git url를 입력한다.

 

 

[pipeline script 작성]

  이제 구체적인 스테이지를 작성해 준다. 과정은 총 6단계이며, 1. Pull 2. Unit Test(pass) 3. Build 4. Tag 5. Push 6. Deploy 순서이다. 먼저 git poll에 있는 url에 자신의 git repository url을 넣어줍니다. withCredentials 위에서 docker hub 접속을 위해 Credentials를 연결하기 위해 생성한 것이다.  각 스테이지의 의미는 다음과 같다.

  1. Pull: git-repository 소스를 당겨온다.
  2. Unit Test: Unit-Test를 진행하기 위한 단계이다. 아직은 비워둔다.
  3. Build: docker-compose를 이용해 build한다.
  4. Tag: docker image tag를 설정한다.
  5. Push: docker hub에 빌드된 이미지를 push 한다.
  6. Deploy: docker-compose 명령어로 이미지를 실행한다.
node { 
    git poll: true, url:'https://github.com/Seungyeup/Recommender.git' 
    withCredentials([[$class: 'UsernamePasswordMultiBinding', 
        credentialsId: 'docker-hub', 
        usernameVariable: 'DOCKER_USER_ID', 
        passwordVariable: 'DOCKER_USER_PASSWORD']]) 
        { 
            stage('Pull') { 
                git 'https://github.com/Seungyeup/Recommender.git' 
            } 
            stage('Unit Test') { 
        
            } 
            stage('Build') { 
                sh(script: 'docker-compose build fastapi') 
            } 
            stage('Tag') { 
                sh(script: '''docker tag fastapi:latest ${DOCKER_USER_ID}/fastapi:${BUILD_NUMBER}''') 
            } 
            stage('Push') { 
                sh(script: 'docker login -u ${DOCKER_USER_ID} -p ${DOCKER_USER_PASSWORD}') 
                sh(script: 'docker push ${DOCKER_USER_ID}/fastapi:${BUILD_NUMBER}') 
                sh(script: 'docker push ${DOCKER_USER_ID}/fastapi:${BUILD_NUMBER}') 
            } 
            stage('Deploy') { 
                sh(script: 'docker-compose up -d') 
            }  
            
    } 
}

 

빌드 성공시 pipeline 화면

 

[Build Trigger로 자동배포 확인]

직접 "build now" 클릭해서 배포하는 것이 아닌 build trigger을 이용해 소스가 변경되면 자동으로 배포되도록 변경해 준다. "구성"에 들어가 build trigger 부분으로 이동한 뒤 "poll scm"을 클릭한 후, H/2 * * * *를 입력하여 2분마다 소스가 변경되었는지 확인하도록 한다.

이제 실제로 동작하는지 확인해보면 된다. 아래에서 확인할 수 있듯이, 커밋을 하게되면 jenkins에서 레포지토리의 변화를 보고 있다가, 다음과 같이 파이프라인을 구성해 자동적으로 배포를 진행하게 된다. 

그리고 도메인으로 접속해 보면 원하는 방식으로 무사히 배포가 완료된 것을 알 수 있다. 혹시 문제가 발생하더라도 젠킨스 파이프라인에서 에러 로그를 확인할 수 있고, 빌드된 도커이미지의 로그를 2차 검증한다면 어디가 문제인지 웬만해서는 알아서 고칠 수 있다.

실제 배포된 모습

  자동으로 빌드 배포환경을 구성한다면, 팀원 중 어느 누가 release 혹은 deploy branch에 머지를 하고, 커밋을 하더라도 서버환경에 자동으로 배포되기 때문에, '인간 젠킨스'가 되는 것을 피할 수 있다. 모두 즐!코! 

728x90