Study Note

Github + Jenkins + Docker로 빌드 / 배포 자동화 본문

Jenkins

Github + Jenkins + Docker로 빌드 / 배포 자동화

moreLearn 2020. 4. 5. 01:24

저번에 Github에 Commit을 하면 Jenkins에서 다운로드와 Build를 하고 다른 EC2에 자동 배포하는 것까지 했습니다. 

이번에는 저번 사용하던 jenkins 서버와 docker를 사용하여 빌드 / 배포 자동화를 해보겠습니다.

 

  1. 저번에 Jenkins로 Build하여 jar파일을 만드는 부분까지 같습니다. [ ]
  2. Dockerfile과 jar파일로 docker image를 생성하여 docker hub에 업로드 합니다.
  3. 배포서버인 ec2에 접속하여 docker hub에 업로드 되어있는 docker image를 다운받고 실행합니다.

이전 글을 보고 이 글을 보시는걸 추천드립니다.

2020/02/22 - [Jenkins] - Github + Jenkins 연동과 Jenkins로 Build 후 ssh로 배포하기 1

 

Github + Jenkins 연동과 Jenkins로 Build 후 ssh로 배포하기 1

다음 그림과 같은 형식 CI/CD를 구현해 보겠습니다. Jenkins 설치 OS가 ubuntu인 ec2에 jenkins를 설치하겠습니다. jenkins는 java가 설치되어 있어야 하기 때문에 java를 설치하겠습니다. 다음과 같이 openjdk-8..

more-learn.tistory.com

2020/02/23 - [Jenkins] - Github + Jenkins 연동과 Jenkins로 Build 후 ssh로 배포하기 2

 

Github + Jenkins 연동과 Jenkins로 Build 후 ssh로 배포하기 2

저번에는 jenkins에서 build 하는 것까지 했습니다. 이번에는 build를 한 후에 다른 ec2에 ssh로 연동을 통해서 배포를 하겠습니다. 먼저 이전에 jenkins가 설치되어 있는 ec2에서 cat /home/ubuntu/.ssh/id_rsa.p..

more-learn.tistory.com

 

Docker Hub

Docker Hub을 사용하기 때문에 기본적으로 Docker Hub에 회원가입 되어 있어야 합니다.

다음 이미지 처럼 docker hub에 repository를 생성합니다.

저는 private로 생성했습니다.

Dockerfile

Dockerfile을 통해서 Docker image를 생성 할 수 있습니다.

github에 Dockerfile을 추가하여 jenkins 서버에서 사용할 수 있도록 했습니다.

 

저는 다음과 같이 Dockerfile을 설정했습니다.

FROM openjdk:8-jdk-alpine
VOLUME /tmp
ADD ./target//CodePressoSB-0.0.1-SNAPSHOT.jar app.jar
ENV JAVA_OPTS=""
ENTRYPOINT ["java","-jar","/app.jar"]
FROM <이미지>
VOLUME <컨테이너 디렉터리>
ADD <복사할 파일 경로> <이미지에서 파일이 위치할 경로>
ENV <환경 변수> <값>
ENTRYPOINT <명령>

Docker 설치

jenkins서버EC2 배포서버에 다음 명령어를 통해 docker를 설치합니다.

sudo apt-get update
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo apt-key fingerprint 0EBFCD88
sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"
sudo apt-get update
sudo apt-get install docker-ce

 

docker을 모두 설치하면 다음과 같이 버전을 확인할 수 있습니다.

 

Jenkins 권한 주기

저의 경우 jenkins에서 docker을 build해야 하기 때문에 jenkins에게 권한을 주어야 합니다.

  1. ubuntu에서 sudo vim /etc/sudoers 명령어로 sudoers를 편집합니다.
  2. jenkins ALL=(ALL) NOPASSWD: ALL를 추가합니다.

 

Jenkins item 구성

Build 이전의 설정은 이전 글과 동일합니다.

Execute shell을 통해서 /home/ubuntu/ 밑에 저장되어 있던 application.properties와 배포 서버에서 실행할 deploy.sh를 복사하여 /var/lib/jenkins/workspaw:/var/lib/jenkins/workspace/<item 이름>/ 에 복사합니다.

 

"저의 경우 ip와 같은 보안상의 이유로 application.properties는 EC2에서 개별 관리하여 사용 중 입니다."

 

Build에서 Invoke top-level Maven targets을 사용하여 Maven으로 Build합니다.

 

다음으로 docker_build_and_push.sh를 실행하여 docker build와 docker hub에 push 합니다.

 

docker_build_and_push.sh의 내용입니다. 저는 tag를 통해 버전 관리를 하기 위해서 다음과 같이 작성했습니다.

latest를 생성하는 이유는 docker에서 tag를 지정하지 않고 pull을 하면 default로 latest를 pull하기 때문에 latest를 push 합니다.

#bin/bash
#docker image의 첫 tag를 일고 다음 버전의 image를 생성
sudo docker build -t ish2852/spring_boot_project:$(docker images | awk '($1 == "ish2852/spring_boot_project") {print $2 += .01; exit}') .

#docker hub에 push 하기위해 login
sudo docker login -u "docker id" -p "docker password"

#docker hub에 push
sudo docker push ish2852/spring_boot_project:$(docker images | awk '($1 == "ish2852/spring_boot_project") {print $2; exit}')

#tag가 latest인 image를 최신 버전을 통해 생성
sudo docker tag ish2852/spring_boot_project:$(docker images | awk '($1 == "ish2852/spring_boot_project") {print $2; exit}') ish2852/spring_boot_project:latest

#latest를 docker hub에 push
sudo docker push ish2852/spring_boot_project:latest

#버전 관리에 문제가 있어 latest를 삭제
sudo docker rmi ish2852/spring_boot_project:latest

해당 방식은 docker images의 첫 image의 tag를 읽고 버전을 확인하기 때문에 중간에 다른 tag가 오면 다음과 같이 버전 관리에 문제가 생깁니다. 

 

 

빌드 후 조치에서 아까 복사한 deploy.sh를 배포 서버에 복사하여 실행합니다.

#bin/bash
#docker hup에서 pull하기 위해 login 합니다.
sudo docker login -u "docker id" -p "docker password"

#tag를 지정하지 않고 pull 하여 docker hub에서 latest를 가져옵니다.
sudo docker pull ish2852/spring_boot_project

#이전에 사용 중이던 서버를 종료합니다.
sudo kill -9 $(ps aux | grep java | grep app.jar| awk '{print $2}')

#docker run을 통해 image를 실행합니다.
#-d : 백그라운드 실행, --rm : 컨테이너 안의 프로세스가 종료되면 컨테이너를 자동으로 삭제, -p 80번 포트 열기
sudo docker run -d --rm -p 80:80 ish2852/spring_boot_project

 

확인

모든 설정이 끝나면 jenkins에서 Build합니다. (github에 commit을 하여 build해도 됩니다.)

저의 docker hub에 다음과 같이 추가 되었습니다.

 

배포용 EC2에서 docker image를 확인하면 latest가 추가되었습니다.

 

서버에 접속하면 다음과 같이 저의 서버가 실행 중입니다.