본문 바로가기

기술/Docker

Docker) Dockerfile로 Jar 실행 도커 이미지 생성하기 (Java 11 + Spring Boot + Gradle)

스프링부트로 개발한 웹 어플리케이션을 개발 서버에서 배포 및 운영 서버로 이관할 때 설치해야되는 패키지가 많아서 굉장히 애를 먹었다. 그래서 이번 기회에 처음으로 도커로 실행 환경을 셋팅해보았다.  

 


프로젝트  개발 환경 

  • Java 11
  • Spring Boot
  • Gradle 
  • dev 서버 : Ubuntu
  • prod 서버 :  RedHat 

 

RedHat에 Docker 이미지 생성하기 

1. 서버에 도커 설치하기 

2. 서버에는 아직 자바가 설치되어 있지 않은 상황 -> 도커에 있는 자바 11 이미지 땡겨오기 

  • 자바 이미지 찾기
$ docker search openjdlk

$ docker pull adoptopenjdk/openjdk11

이 명령어로 찾을 수 있는데 2021년 9월 기준 아래와 같이 보이고 그 중에서 빨간색으로 표시한 저 이미지를 내려받는다. 이렇게 간단하게 자바를 설치할 수 있다니 너무 행복하고 편하다 ㅠㅠ 원래는 다운받고 경로 설정 다시 하고 난리쳤던 것 같은데 

 

3. jar 파일 생성하고 필요한 파일 및 폴더 가져오기 

  • jar 생성하기 with Gradle
$ gradle clean 
$ gradle build
$ gradle bootJar

요래 하면 스프링부트 프로젝트 파일 내에 build라는 폴더가 생기고 그 안에 libs라는 폴더 안에 jar 파일이 생성된다. 옮기기 전에 파일이 제대로 실행이 되는지 부터 확인해보는게 좋다. 

java -jar {jar파일명}.jar

나는 일단 개발서버와 달리 배포 및 운영서버가 특정 윈도우 환경에서만 접근되는 서버였기 때문에 굉장히 번거로웠다. 

일단 맥에서 개발서버에 접근해서 jar 파일을 내려받았다. 그냥 드래그하거나 vscode에서 다운로드 버튼을 눌러 로컬로 내려받으면 파일이 깨져서 scp 명령어를 통해 파일을 옮겼다. 

  • 원격 서버(개발) -> 로컬 파일 가져오기 
scp -v -i pem/{pem파일명}.pem {사용자명}@{ip 주소}:{프로젝트 파일 위치}/build/libs/{파일명}.jar {로컬 디렉토리경로}

여기서 -v 옵션을 주면 scp 과정의 로그?를 같이 보여준다. 그리고 해당 서버에 pem 파일로 보안이 걸려있다면 -i 옵션과 함께 scp 명령어를 치면 된다. 원격 서버 주소:가져올 파일 경로를 첫번째 인자로 주고, 두번째 인자로 로컬에 그 파일을 저장할 경로를 두번째 인자로 주면된다. 

  • 윈도우 로컬 서버 -> 원격 서버(운영)

이 과정 역시 scp로 해줬다. 위와 같은 방식으로 scp 를 하면되는데 로컬 -> 원격일때는 첫번째 인자에 로컬 파일을 두번째 인자에 그 파일을 전달할 서버 주소:경로를 주면 된다. 

 

4. Dockerfile 작성

이 파일을 이용해서 도커 이미지를 빌드한다. 

  • 조건

처음에 설치했던 자바 11 이미지 위에다 이미지 생성한다.

jar파일과 앱 실행에 필요한 파일 및 폴더들을 모두 한 폴더에 넣어둔다. 

그 폴더에다가 Dockerfile을 만든다. 

FROM adoptopenjdk/openjdk11
WORKDIR {jar파일과 필요한 파일들이 있는 경로}
COPY {jar파일명}.jar .
COPY {앱 실행에 필요한 파일} .
CMD java -jar {jar파일명}.jar

이렇게 작성하면 되는데 이때 앱에 실행에 필요한 파일이 여러개라면 그냥 위와같이 COPY 명령어를 여러번 입력하면 되고 폴더를 이미지에 함께 올리고 싶다면 그 폴더를 다 명시해줘야 한다.

예를들어 a/b/c.txt 폴더가 앱 실행에 필요한 것이라면 COPY a/b/c.txt ./a/b/ 이렇게 경로를 정확히 명시해야 한다. 그냥 COPY a . 이렇게 하면 a 폴더 내부에 있는 건 카피되지 않는다. 물론 이 경우 a/b/c.txt가 현재 dockerfile을 생성하는 경로에 위치한 경우이다. 

 

5. 도커 이미지 빌드

Dockerfile을 작성한 경로에서 이미지를 빌드한다. 

$ sudo docker build --tag {도커이미지 이름}:{tag 이름} ./

루트 권한이 필요했고, 다음과 같은 명령어를 쓴다. --tag  옵션으로 태그를 달 수도 있다. 태그로 주로 버전을 명시한다. 예를들어 app:0.1로 하는 것! 그리고 도커파일이 있는 경로를 인자로 주면 되는데 지금 이 명령어를 도커파일이 있는 경로에서 실행한다면 위와같이 ./만 입력하면 된다. 

빌드가 성공했다면 이미지를 확인해본다. 

$ docker images

이렇게 도커 이미지가 생성된 것을 확인할 수 있다. 

 

6. 도커 이미지 실행하기 

$ sudo docker run -it -p {도커가 실행될 포트}:{도커 내 파일이 실행되는 포트} {이미지 이름}:{태그 이름}

ex) sudo docker run -it -p 80:8080 app:0.1

스프링부트 프로젝트에서 디폴트 포트는 8080이다. 프로퍼티 파일에서 포트넘버를 지정해줄 수 있는데 이때 8081로 했다면 jar 파일을 8081로 실행되니까 -p *:8081로 하면 된다. 그리고 운영 서버에서 이 도커 이미지를 80으로 열어주고 싶다면 80:8081로 하면 된다. 운영 서버에서는 대부분 80포트로 열어준다고 한다. 그래야 사용자들이 포트넘버를 명시하지 않고 도메인 이름으로만 접근할 수 잇으니까!

도커는 stop 명령어를 치지 않는 이상 터미널을 닫는다고 종료되지 않는다. 

 

* 도커 실행 종료 

$ docker ps

이렇게 현재 실행 중인 컨테이너를 확인할 수 있다. 

이 컨테이너를 중지하고 싶다면 ps로 컨테이너 아이디를 확인해서 아래와 같이 하면 된다. 

$ docker stop {컨테이너 아이디}

 


 

처음으로 스프링부트로 웹 서비스 하나를 온전히 만들어보고 직접 운영 및 배포 과정에 참여해보니 뿌듯하다 ㅎㅅㅎ 그리고 맨날 듣기만 하던 도커가 왜 중요한지도 알게 되었다 ㅋㅋㅋ 앞으로 더 공부해 봐야 겠당