보통 SpringBoot 프로젝트를 배포시 jar 파일로 빌드된 내용을 클라우드에서 실행하거나, IDE에서 제공되는 기능을 사용합니다. 즉, 클라우드에 배포시 jar 파일을 직접 배포하고 서버를 작동시키는 방법으로 많이 사용합니다. 이 포스팅에서는 Docker 를 활용해 Docker 이미지를 생성하고 클라우드 서버에 배포하는 방법을 알아보겠습니다.
본격적인 시작전에, 어떻게 Docker 로 생성한 이미지가 컨테이너에 감싸져서 배포가 이루어지는지 알아봅시다.
우선 본인의 로컬에서 진행한 프로젝트 내용이 있을겁니다. 해당 프로젝트의 내용을 하나의 jar 파일로 압축시킨 후, 이를 Dockerfile 를 통해 이미지화 시킨 후 DockerHub 에 push 하는 겁니다.
그 후 클라우드 EC2 서버에서 직전에 push 했던 도커 이미지를 내려받은 후(pull), Docker run을 통해 해당 이미지를 감싸고 있는 도커 컨테이너를 실행시켜서 서버를 배포시키는 방식입니다.
gradle 의 bootJar 라는 것이 있습니다. 이를 활용해 jar 파일을 빌드해주셔야 합니다.
jar 파일을 여러개의 클래스 파일들과 관련 리소스 및 메타 데이터를 하나의 파일로 모아서 배포를 위해 만들어진 SW 패키지 파일 포맷입니다. 또 jar는 zip 으로 이루어진 압축 파일입니다.
빌드에 성공하셨다면 아래와 같이 build/libs 디렉토리에 jar 파일이 성공적으로 빌드된 모습을 확인할 수 있습니다.
다음으로는 DockerFile 을 생성할 차례입니다. 도커 파일이란 도커 이미지를 생성하기 위한 DSL으로서 몇가지 명령어들 커스텀 이미지를 만들 수 있게 해줍니다.
Dockerfile 은 직전에 생성한 jar 파일이 위치한 곳, 즉 build/libs 파일에서 생성되어야 합니다. 따라서 이 경로로 이동하여 Docker 파일을 작성해주도록 합시다.
cd /build/libs
ls
도커파일의 내용은 아래와 같습니다.
FROM openjdk:11
ARG JAR_FILE=*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
FROM : 기반이 되는 이미지를 의미하고, jdk 11 버전을 사용함을 명시했습니다.
ARG : 컨테이너 내에서 사용할 수 있는 변수를 지정할 수 있습니다. 즉, 여기서는 확장자가 " .jar " 인 변수(파일)을 Docker 컨테이너에서 사용하겠음을 명시한 것입니다.
COPY : ARG의 JAR_FILE 변수를 컨테이너의 app.jar에 복사한다는 뜻입니다.
ENTRYPOINT : 컨테이너가 시작됐을 떄 실행할 스크립트를 명시합니다. 직전에 COPY 를 통해 app.jar 에 카피한 jar 파일을 도커 컨테이너가 시작됐을 때 실행하기 위해 명시한 것입니다.
다음으로 도커 이미지를 생성할 차례입니다. Dockerfile을 빌드해줌으로써 도커 이미지가 생성되는데, 터미널에 Dockerfile이 있는 위치에서 다음 명령어를 써주면 Dockerfile이 빌드가 됩니다.
docker build -t '도커에 가입한 본인의 계정'/'프로젝트명':'버전' '경로'
docker build `옵션` `도커에가입한 계정`/`프로젝트명`:`버전` `경로`
>>> docker build -t msung99/maestroproject:0.1.0 .
이때 맥북 M1 칩을 사용하시는 분들을 주의하셔야 할 사항이 있습니다. 현재 본인이 사용중인 맥북이 Apple M1칩이라면 도커가 해당 이미지를 빌드할때 생성된 빌드 플랫폼이 클라우드 서버(linux) 와 m1 맥북간의 호환성이 안맞는 문제가 발생합니다.
맥북 m1 의 경우 아래의 명령을 통해 호환성을 맞춰주도록 사전에 제대로 이미지를 빌드해주도록 합시다.
docker build -platform linux/amd64 -t `도커에가입한 계정`/`프로젝트명`:`버전` `경로`
이미지가 정상적으로 생성되었는지는 아래와 같이 확인할 수 있습니다.
docker images // 모든 도커 이미지 조회
이제 도커허브에 이미지를 올릴 차례입니다. 도커허브의 레포지토리에 방금 생성한 이미지를 push 하고, 추후 클라우드 서버에서 해당 레포지토리로 부터 도커 이미지를 가져오는 방식입니다.
>>> docker push '이미지명'
docker push msung99/maestro
도커허브에서 해당 레포지토리에 접속하시면 정상적으로 이미지가 push 된 모습을 확인할 수 있습니다.
이제 EC2 서버에 도커를 설치하고, 아까 도커허브에 올렸던 도커 이미지를 pull 받은 후 이 서버에서 스프링부트 프로젝트를 실행시키면 됩니다. 아래와 같이 도커를 위한 환경셋팅을 진행해줍시다.
참고로 저는 Ubuntu18.04 LTS 버전을 기반으로 클라우드 서버를 구축했습니다.
sudo apt update
sudo apt install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable"
sudo apt update
apt-cache policy docker-ce
sudo apt install docker-ce
직전에 설명드렸듯이 이제 도커 이미지를 레포지토리로부터 서버에 내려받으면 됩니다. 아래와 같이 내려받도록 해줍시다.
sudo docker pull '레포지토리명'
sudo docker pull msung99/maestro:0.1.0
아래와 같이 pull 을 정상적으로 실행했다면 성공입니다!
마지막 단계입니다. 내려받은 도커 이미지를 컨테이너에 감싸서 실행시켜주면 끝입니다.
sudo docker run --name '컨테이너명' -d -p '호스트 포트':'컨테이너 포트' '레포지토리명'
sudo docker run --name 'container' -d -p 8080:8080 msung99/maestro:0.1.0
docker build --platform linux/amd64 -t msung99/maestro:0.1.0 .
=> 두번째는 맥북 m1 칩의 경우일때 실행하면 됩니다. 아까 말씀드렸던 호환성 문제 때문입니다.
또는 아래와 같이 실행시킬 수도 있습니다.
docker run -p 호스트 포트':'컨테이너 포트' '레포지토리명'
docker run -p 9001:9001 msung99/maestro:0.1.0
이렇게까지 잘 따라해주셨다면 도커 이미지가 컨테이너에 감싸서 정상적으로 실행되고 있을겁니다. 혹시 모르니 정상적으로 실행되고 있는지를 확인해보고 싶다면, 아래와 같은 명령를 통해 컨테이너의 상태를 조회해봅시다.
docker ps -a
만일 STATUS 가 EXITED 라면 정상 실행되지 않은 것으로, 어떤 문제가 발생했는지 다시 확인해봐야 합니다. 방금 생성한 도커 컨테이를 삭제시켜주고, 각자 발생한 문제를 해결하고 와야합니다.
docker stop container
docker rm container
아래와 같이 생성한 IP주소를 9001번 포트로 접속해보면 정상적으로 서버가 구축되었음을 확인할 수 있습니다.
이렇게 로컬에서 작업했던 스프링부트 프로젝트를 도커를 통해 EC2서버에 배포하는 과정까지 다루어보았습니다. 다만 현 포스팅에서 내용을 담지못해 아쉬웠던 점은 다음과 같습니다.
- 도커란 무엇인가?
- 호스트 포트와 컨테이너 포트란 무엇이며, 둘의 차이는 무엇인가?
- 호환성 : 맥북 m1에 기반한 서버는 왜 linux amd64 서버와 호환이 안되는가?
이번에 도커를 학습하며 함께 학습했던 내용이나, 위 내용들을 모두 다루기엔 포스팅 내용이 너무 길어진다 판단하여 추후에 다루기로 결정했습니다.
궁금하신 점이나 도움을 받고 싶은 내용이 있다면 댓글로 남겨주시면 도와드리겠습니다.
[Docker](이미지 플랫폼 관련 에러 The requested image's platform (linux/arm64/v8) does not match the detected host platform (linux/amd64) ...
Django-Docker로-배포하기#5-도커이미지를-도커허브에-푸시하기git-push랑-비슷
[Docker] 도커에서 Container 포트와 Host 포트의 개념
Docker를 이용한 Spring 프로젝트 배포
Spring jar 배포