안녕하세요. J4J입니다.
이번 포스팅은 GitLab Runner + Docker + Ubuntu를 이용한 SpringBoot 환경 구축하는 방법에 대해 적어보는 시간을 가져보려고 합니다.
들어가기에 앞서 다음 글을 참고하시면 좋을 것 같습니다.
사전 준비
[ 1. GitLab Runner와 GitLab Repository 연결 ]
[GitLab] GitLab Runner 설치하기 (Ubuntu 20.04) 참고 부탁드립니다.
저는 연결된 Repository는 다음과 같이 구성되어 있습니다.
[ 2. Dockerfile 내용 수정 ]
[Docker] SpringBoot 환경 구축에 작성해 둔 Dockerfile의 수정 작업을 진행해야 합니다.
왜냐하면 링크의 Dockerfile에서는 maven을 이용한 build작업이 Dockerfile에서 이루어지고 있습니다.
그렇기 때문에 관련 코드들을 Ubuntu로 모두 copy 해야 합니다.
하지만 이번에 GitLab Runner를 사용하면서 build작업을 GitLab에서 수행하게 함으로 써 관련 코드들을 Ubuntu에 모두 copy하지 않고 서비스 실행에 필요한 jar파일만 copy 하는 방식으로 수정하려고 합니다.
그러므로 다음과 같이 수정을 해주시면 됩니다.
# jdk 이미지 불러오기
FROM openjdk:11-jre-slim
# Docker Container에서 작업이 이루어지는 위치
WORKDIR /root
# 현재 경로/target/be-0.0.1-SNAPSHOT.jar에 해당하는 파일을 Docker Container의 WORKDIR 위치로 복사 (이미지 생성할 때 동작)
COPY ./target/be-0.0.1-SNAPSHOT.jar ./
# COPY된 jar파일 실행하기 (컨테이너 실행할 때 동작)
CMD ["java", "-jar", "be-0.0.1-SNAPSHOT.jar"]
GitLab CI 작성 (1) - build
위의 설정이 모두 완료되었다면 자동 배포를 위해 사용되는 파일인 .gitlab-ci.yml 파일을 작성해보도록 하겠습니다.
해당 파일은 다음과 같이 root경로에 생성해주시면 됩니다.
먼저 build부터 다뤄보도록 하겠습니다.
build는 말 그대로 작성된 코드 파일들을 build 하는 단계입니다.
SpringBoot는 일반적으로 maven과 gradle을 사용하여 build를 하는데 위에 링크에서 했던 것처럼 저는 maven을 이용하여 build를 할 것입니다.
그렇기 때문에 .gitlab-ci.yml파일을 다음과 같이 작성해보도록 하겠습니다.
# 실행될 stage 지정 (위에서 아래로 차례대로 실행)
stages:
- build
build: # JOB 이름
# 사용될 이미지 설정
image: maven:3.8.4-jdk-11
# stage 설정
stage: build
# 실행될 script 설정
script:
- mvn clean package -DskipTests
# artifacts 설정 (bulld를 통해 생성된 파일을 job artifacts에 보관하여 다음에 수행되는 JOB에서 가져다 활용할 수 있게 도와줌)
artifacts:
# 보관이 이루어질 경로 설정
paths:
- target/*.jar
# 유효기간 설정
expire_in: 1 days
# JOB이 수행될 branch 설정 (설정된 branch에 push가 발생될 시 JOB 수행)
only:
- master
파일 작성이 이루어졌다면 Repository에 push를 해보도록 하겠습니다.
push가 정상적으로 이루어졌다면 GitLab → CI/CD → Editor에 다음과 같이 .gitlab-ci.yml파일에 작성한 내용을 확인할 수 있습니다.
또한 GitLab → CI/CD → Pipelines를 확인해보면 다음과 같이 push에 의해 trigger가 발생한 것을 확인할 수 있습니다.
모든 처리가 완료되고 또한 정상 동작이 되었다면 Status에 passed라는 것을 확인할 수 있고 다음과 같이 Stages 체크 버튼 클릭 → build 클릭을 할 수 있습니다.
그러면 이처럼 build수행과 관련된 로그들을 확인할 수 있고 또한 문제없이 정상 동작되었다면 build 작업에 의해 artifacts에 보관되는 파일들을 우측에 Browse버튼을 클릭하여 확인할 수 있습니다.
GitLab CI 작성 (2) - test
이번엔 그다음 단계로 test를 다뤄보겠습니다.
test는 말 그대로 코드들이 정상 동작되는지 test 하는 단계입니다.
test가 정상적으로 수행될 때만 다음 단계로 넘어가기 때문에 서버에 배포하기 전 수행이 이루어져야만 하는 단계입니다.
test도 수행될 수 있도록 다음과 같이 .gitlab-ci.yml파일을 수정해보겠습니다.
# 실행될 stage 지정 (위에서 아래로 차례대로 실행)
stages:
- build
- test
build: # JOB 이름
# 사용될 이미지 설정
image: maven:3.8.4-jdk-11
# stage 설정
stage: build
# 실행될 script 설정
script:
- mvn clean package -DskipTests
# artifacts 설정 (bulld를 통해 생성된 파일을 job artifacts에 보관하여 다음에 수행되는 JOB에서 가져다 활용할 수 있게 도와줌)
artifacts:
# 보관이 이루어질 경로 설정
paths:
- target/*.jar
# 유효기간 설정
expire_in: 1 days
# JOB이 수행될 branch 설정 (설정된 branch에 push가 발생될 시 JOB 수행)
only:
- master
test: # JOB 이름
# 사용될 이미지 설정
image: maven:3.8.4-jdk-11
# stage 설정
stage: test
# 실행될 script 설정
script:
- mvn test
# JOB이 수행될 branch 설정 (설정된 branch에 push가 발생될 시 JOB 수행)
only:
- master
파일에 내용을 모두 작성했다면 Repository에 변경된 내용을 다시 push 하여 trigger가 발생되도록 해줍니다.
그런 뒤 다시 Pipelines를 확인해보면 다음과 같이 stage가 하나 더 늘어난 trigger를 확인할 수 있습니다.
GitLab CI 작성 (3) - package
이번엔 package입니다.
package에서 수행되는 것은 build 된 파일을 기반으로 docker 이미지를 만드는 단계입니다.
또한 만들어진 docker 이미지를 배포되는 Ubuntu서버에서도 가져와 사용할 수 있도록 저장소에 업로드를 해줘야 하는데 저는 여기서 GitLab에서 제공하는 Container Registry를 활용해보겠습니다.
package까지 수행될 수 있도록 .gitlab-ci.yml파일을 다음과 같이 수정해보겠습니다.
# 실행될 stage 지정 (위에서 아래로 차례대로 실행)
stages:
- build
- test
- package
build: # JOB 이름
# 사용될 이미지 설정
image: maven:3.8.4-jdk-11
# stage 설정
stage: build
# 실행될 script 설정
script:
- mvn clean package -DskipTests
# artifacts 설정 (bulld를 통해 생성된 파일을 job artifacts에 보관하여 다음에 수행되는 JOB에서 가져다 활용할 수 있게 도와줌)
artifacts:
# 보관이 이루어질 경로 설정
paths:
- target/*.jar
# 유효기간 설정
expire_in: 1 days
# JOB이 수행될 branch 설정 (설정된 branch에 push가 발생될 시 JOB 수행)
only:
- master
test: # JOB 이름
# 사용될 이미지 설정
image: maven:3.8.4-jdk-11
# stage 설정
stage: test
# 실행될 script 설정
script:
- mvn test
# JOB이 수행될 branch 설정 (설정된 branch에 push가 발생될 시 JOB 수행)
only:
- master
# 전역 변수 설정
variables:
IMAGE_NAME: $CI_REGISTRY_IMAGE:latest # 이미지 이름
package: # JOB 이름
# 사용될 이미지 설정
image: docker:latest
# stage 설정
stage: package
# service 설정 (설정한 image가 작업이 이루어지는 동안 실행되는 docker 이미지)
services:
- docker:dind
# script가 실행 전 수행 될 script
before_script:
- docker login $CI_REGISTRY -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD # GitLab Container Registry에 로그인
# 실행될 script 설정
script:
- docker build -t $IMAGE_NAME . # Dockerfile로 build
- docker push $IMAGE_NAME # Container Registry에 image push
# script가 실행된 후 수행 될 script
after_script:
- docker logout # GitLab Container Registry 로그아웃
# JOB이 수행될 branch 설정 (설정된 branch에 push가 발생될 시 JOB 수행)
only:
- master
여기서 사용되는 $CI_~들은 GitLab에서 default로 제공해주는 변숫값들입니다.
해당 변숫값들이 어떤 값들로 저장되어 있는지 확인하고 싶다면 아무 JOB에서나 script에 다음을 추가하시면 로그에서 확인할 수 있습니다.
echo $CI_REGISTRY $CI_REGISTRY_USER $CI_REGISTRY_PASSWORD $CI_REGISTRY_IMAGE
또한 package에서는 작성된 Dockerfile을 이용하여 이미지를 build 해주는데 위에서 보셨다시피 해당 Dockerfile의 COPY에 있는 jar파일은 artifacts에 보관되어 있는 jar파일을 사용하는 것입니다.
push 한 뒤 발생된 trigger가 정상적으로 동작 완료되었다면 Pipelines에서 다음과 같이 stage가 추가된 것을 확인할 수 있습니다.
모든 수행이 정상적으로 되었다면 Container Registry에 Docker 이미지가 정상적으로 업로드되었는지 확인할 수 있습니다.
GitLab → Packages & Registries → Container Registry에 접속하면 다음과 같이 이미지가 생성된 것을 확인할 수 있습니다.
GitLab CI 작성 (4) - deploy
이제 마지막 단계인 deploy입니다.
deploy에서는 Container Registry에 보관되어 있는 이미지를 Ubuntu에서 가져와 Docker Container를 생성 및 실행해주면 됩니다.
deploy도 추가해주기 위해 다음과 같이 .gitlab-ci.yml을 수정해보겠습니다.
# 실행될 stage 지정 (위에서 아래로 차례대로 실행)
stages:
- build
- test
- package
- deploy
build: # JOB 이름
# 사용될 이미지 설정
image: maven:3.8.4-jdk-11
# stage 설정
stage: build
# 실행될 script 설정
script:
- mvn clean package -DskipTests
# artifacts 설정 (bulld를 통해 생성된 파일을 job artifacts에 보관하여 다음에 수행되는 JOB에서 가져다 활용할 수 있게 도와줌)
artifacts:
# 보관이 이루어질 경로 설정
paths:
- target/*.jar
# 유효기간 설정
expire_in: 1 days
# JOB이 수행될 branch 설정 (설정된 branch에 push가 발생될 시 JOB 수행)
only:
- master
test: # JOB 이름
# 사용될 이미지 설정
image: maven:3.8.4-jdk-11
# stage 설정
stage: test
# 실행될 script 설정
script:
- mvn test
# JOB이 수행될 branch 설정 (설정된 branch에 push가 발생될 시 JOB 수행)
only:
- master
# 전역 변수 설정
variables:
IMAGE_NAME: $CI_REGISTRY_IMAGE:latest # 이미지 이름
package: # JOB 이름
# 사용될 이미지 설정
image: docker:latest
# stage 설정
stage: package
# service 설정 (설정한 image가 작업이 이루어지는 동안 실행되는 docker 이미지)
services:
- docker:dind
# script가 실행 전 수행 될 script
before_script:
- docker login $CI_REGISTRY -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD # GitLab Container Registry에 로그인
# 실행될 script 설정
script:
- docker build -t $IMAGE_NAME . # Dockerfile로 build
- docker push $IMAGE_NAME # Container Registry에 image push
# script가 실행된 후 수행 될 script
after_script:
- docker logout # GitLab Container Registry 로그아웃
# JOB이 수행될 branch 설정 (설정된 branch에 push가 발생될 시 JOB 수행)
only:
- master
deploy: # JOB 이름
# stage 설정
stage: deploy
# tag 설정 (수행이 이루어질 GitLab-Runner tag 등록)
tags:
- dev-be
# script가 실행 전 수행 될 script
before_script:
- docker login $CI_REGISTRY -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD # GitLab Container Registry에 로그인
# 실행될 script 설정
script:
- docker rm -f be-con || true # 기존에 존재하던 Container 삭제
- docker rmi $IMAGE_NAME || true # 기존에 존재하던 이미지 삭제
- docker pull $IMAGE_NAME # Container Registry에서 이미지 가져오기
- docker run --name be-con -p 8080:8080 -d $IMAGE_NAME # Container 생성 및 실행
# script가 실행된 후 수행 될 script
after_script:
- docker logout # GitLab Container Registry 로그아웃
# JOB이 수행될 branch 설정 (설정된 branch에 push가 발생될 시 JOB 수행)
only:
- master
작성이 완료되었다면 push를 해주고 그에 따른 stage가 추가된 trigger가 다음과 같이 Pipelines에서 확인 가능합니다.
정상 동작이 완료되었다면 tag에 해당하는 GitLab Runner가 설치된 Ubuntu 서버를 확인하면 Container Registry에서 내려받은 이미지와 해당 이미지로 실행한 Docker Container를 확인할 수 있습니다.
이상으로 GitLab Runner + Docker + Ubuntu를 이용한 SpringBoot 환경 구축하는 방법에 대해 간단하게 알아보는 시간이었습니다.
읽어주셔서 감사합니다.
댓글