SpringBoot 프로젝트 docker로 배포하기

xeonu·2023년 2월 3일
8

우분투 서버에 직접 배포하기

docker를 알기 전 내가 배포했던 방식에 대해 간략하게 설명하고자한다.

  1. NCP에서 우분투 이미지의 서버를 하나 생성하고 포트포워딩을 해준다.
  2. 우분투 서버에 jdk 11을 설치한다.
  3. 내 컴퓨터로 작업한 스프링 부트 프로젝트의 jar 파일을 생성한다.
  4. 이 jar 파일을 filezilla를 통해 우분투로 보낸다.
  5. 우분투 서버로 전송된 jar 파일을 실행한다.

1, 2 단계는 한번만 실행해서 이해할 수 있지만 매번 새로운 버전이 업데이트 될 때 마다 3, 4, 5 과정을 진행하면서 이건 매우 비효율적이다라고 생각했다. 여러 기업에서 에자일을 도입하고 있는 와중에 배포 하나로 이렇게 시간을 허비할 수 없다. 배포 속도를 향상 시키기 위해서 CD를 이용해 자동화 시킬 수 있지만 그 전에 도커로 배포하는 것도 좋은 경험일 것 같다.

도커란?

인터넷과 주변 개발자 분들을 보면 도커 이미지로 배포한다는 이야기를 많이한다. 필자는 고통스런 배포 과정을 수행하면서 도대체 도커가 무엇이고 이것을 사용하면 배포가 얼마나 간단해지는지 궁금했다. 도커를 알아보기 위해 시작하세요! 도커/쿠버네티스라는 책을 정독했다. 결론부터 말하자면 도커는 배포를 쉽게하는 치트키라기 보단 컨테이너라는 컴퓨터공학자들의 위대한 발명품이라는 것을 깨달았다.

가상화와 컨테이너

요즘은 맥북이 늘었지만 컴퓨터공학과 학생들 중 여전히 다수의 학생들은 윈도우 노트북을 사용한다. 그들이 리눅스를 다루는 전공수업을 들을 때면 교수님들은 VirtualBox와 같은 가상머신 프로그램을 설치하고 이를 통해 ubuntu와 같은 리눅스를 설치하여 수업에 참여하게했다. 이 때마다 컴퓨터는 버거워 했다. 이 버거움을 해소할 수 있는 개념이 컨테이너라는 개념이다.

기존 가상머신과 같은 가상화는 OS와 하드웨어 드라이버를 host의 운영체제 즉 커널 단이 아닌 유저 단에 띄워서 가상화를 구현했다. 하지만 우리가 가상화를 사용하는 주 목적은 Application을 사용하기 위함인데 매번 운영체제를 따로 설치해주는 것은 host 컴퓨터 입장에서는 부담스러운 일이다.

이를 개선하기 위해서 도커엔진을 이용하여 컨테이너라는 것을 띄운다. 컨테이너는 Application을 사용할 수 있는 가상 환경이고 별도의 운영체제가 필요하지 않다. 이를 통해 우리의 목적인 Application 사용도 가능하고 host환경에도 부담이 덜 간다.

이 때 저 컨테이너를 우리는 기록할 수 있고 그 형태를 이미지라고 한다. 도커엔진이 설치된 환경에서 이미지만 있다면 불필요하게 우분투와 같은 운영체제를 설치하지 않고 Application을 실행할 수 있다. 이 것이 스프링부트 배포를 간편하게 해주는 시발점이다.

도커파일

특정 이미지로 컨테이너를 생성하고 일련의 작업을 수행하는 과정을 기록한 파일이다. 우리가 자바배포 과정을 도커 컨테이너 환경에서 구축한다고 가정하자.
1. jdk 이미지로 컨테이너를 생성한다.
2. host에 저장되어 있는 jar 파일을 컨테이너 내부로 복사한다.
3. jar 파일을 빌드한다.

이런 과정을 거친다. 이 과정을 거치면서 터미널에 여러 명령어들을 매번 입력할 수도 있지만 서버가 100대라고 생각하면 쉽지 않은 일이다. 우리는 이런 과정을 도커파일에 기록하고 도커파일을 이미지화 해서 이 이미지를 실행할 때 마다 자동으로 스프링 프로젝트가 시작되도록 구현하고자한다.

도커 파일 작성법이 포스트의 주 컨텐츠는 아니지만 지시어 정도는 알아두면 이해하기 수월하다.

스프링 부트 프로젝트 도커로 배포하기

Jar 파일 생성

인텔리제이 우측 탭에 Gradle로 들어가 build/bootJar를 실행하여 Jar 파일을 생성해주자. Jar 파일은 build/libs 디렉토리에 생성될 것이다.

Dockerfile 작성 후 이미지생성

이제 원하는 위치에 Dockerfile이라는 이름의 file을 생성해주자. 필자는 프로젝트 디렉토리에 바로 생성했다.
FROM openjdk:11
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]

이 프로젝트는 jdk 11을 기준으로 제작되었으므로 openjdk:11을 베이스 이미지를 기반으로 dockerfile을 작성한다. build/libs에 존재하는 jar 파일을 복사하여 app.jar파일을 컨테이너에 생성해준다. 그 후 jar 파일을 실행해준다. 이 때 COPY를 하는 이유는 도커파일을 수정할 때 마다 COPY 부분의 이미지만 수정되면 커밋 후의 용량이 크게 변하지 않기 때문이다.

이제 터미널에서 dockerFile이 있는 디렉토리로 이동해준 후 dockerfile을 실행해주자

$ docker build --tag <도커계정명>/soccerfriend:1.0.1 .

필자는 M1 맥북을 보유하고 있으므로

$ docker build --platform amd64 --build-arg DEPENDENCY=build/dependency --tag <도커계정명>/soccerfriend:1.0.1 .

다음과 같이 별도로 playform 설정을 해주었다.

도커계정명 뒤에 오는 것이 이미지의 [이름:버전]을 의미한다. 도커 계정명을 작성하는 이유는 dockerhub에 push할 때 계정이름이 이미지에 작성되어야 하기 때문이다. 그 뒤에는 dockerfile의 경로를 작성하면되고 현재 디렉토리이므로 점 하나만 작성해주면된다.

$ docker images
docker image 목록을 확인해보면 성공적으로 soccerfriend:1.0.1라는 이름으로 생성된 것을 확인할 수 있고 docker desktop이 설치되었다면 한눈에 확인할 수 있다.

DockerHub로 push

위에서 만든 이미지로 컨테이너를 실행만 해주면 자동으로 스프링부트 프로젝트가 실행된다. 하지만 다른 서버 환경에서도 이 이미지에 접근하기 위해서는 docker hub에 push한 후 이미지가 필요할 때 pull 하는 것이 편하다.

$ docker login

먼저 도커에 로그인을 해준다.

$ docker push <이미지 이름>

해당 명령어로 도커허브로 push 해주면된다. 이 때 이미지 이름은 작성자명, 이름, 버전등이 모두 포함된 풀네임으로 작성해야한다.

이제 클라우드 환경에 방금 만들었던 도커 이미지가 공유되었다. 어디서든 도커가 설치된 환경이라면 도커허브에서 다운로드 받아 해당 이미지의 컨테이너를 생성할 수 있다.

배포하기

필자는 NCP 서버를 하나 생성한 후 SSH로 접속하였다. 새로운 서버에 접속했으므로 다시 도커에 로그인 해준다.

$ docker login

로그인을 해준 후 이미지를 도커 컨테이너에서 가져온다.

$ docker pull <이미지 이름>

도커 이미지 목록을 확인하면 방금 push 했던 도커이미지가 정상적으로 다운로드 되었을 것이다.

$ docker images

해당 image를 실행할텐데 이 프로젝트는 스프링 MVC 기반으로 이루어져 있기 때문에 도커와 로컬의 포트포워딩을 잘 설정해주어야한다. 해당 이미지는 8080포트를 할당해주었지만 이건 어디까지나 도커 컨테이너 내부의 포트이다. 도커 컨테이너의 8080포트를 로컬의 8080포트와 포트 포워딩을 해주기 위해서

$ docker run -i -t -p 8080:8080 <도커이미지> &

해당 명령어로 컨테이너를 백그라운드로 생성해준다. 성공적으로 해당 서버의 공인 ip의 8080포트로 접속되는 것을 확인할 수 있다.

profile
백엔드 개발자가 되기위한 여정

0개의 댓글