Kubernetes

[Docker] SpringBoot jar - 도커 이미지 생성

운덩하는 개발자 2023. 6. 5.
반응형

1. SpringBoot 간단한 코드 작성

package com.example.test;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@SpringBootApplication
public class TestApplication {

	@RequestMapping("/")
	String home() {
		return "Hello Docker!";
	}

	public static void main(String[] args) {
		SpringApplication.run(TestApplication.class, args);
	}
}


2. Jar 파일 생성

도커를 만들기 전, SpringBoot로 만든 앱의 jar 파일을 생성해야한다.
Gadle Tasks탭에서 빌드 실행
build가 끝나면 bootjar 기능으로 jar 파일 생성


빌드가 끝나면 /build/libs 경로에 [프로젝트명]-[버전]-SNAPSHOT.jar 형식으로 jar파일이 생성.
해당 파일을 FTP를 이용해 도커가 설치된 환경으로 옮겨준다

여기서 말하는 도커가 설치된 환경을 도커 엔진이 설치되어 있는 서버 또는 호스트 시스템을 의미, 따라서 FTP를 사용하여 jar 파일을 도커가 설치된 환경으로 옮기는 것은 도커 호스트로 전송하는 것

FTP를 사용하여 애플리케이션 jar 파일을 도커 호스트로 전송하는 이유:

  • 도커 파일 내부에서 앱 jar 파일의 경로를 지정하고 해당 경로에 jar 파일이 존재해야 도커 이미지에 포함된다.
  • 도커 호스트에서는 앱 jar 파일이 없기 때문에 jar 파일을 도커 호스트로 전송해야 한다.
  • FTP를 통해 jar 파일을 도커 호스트로 전송하면,, 도커 이미지가 실행되는 도커 호스트에서 해당 jar파일을 사용하여 앱 실행 가능
  • 앱 파일을 도커 이미지에 포함시키는 것은 도커를 사용한 배포의 일반적인 방법. 이를 통해 도커 이미지를 독립적으로 배포하고 실행할 수 있으며, 호스트 환경에 직접적인 의존성을 갖지 않으며 독립적이게 된다.

요약하자면, FTP를 사용하여 jar파일을 도커 호스트로 전송하는 이유는 도커 이미지를 빌드하고 실행하는 과정에서 앱 파일이 필요하기 때문. FTP를 통해 jar파일을 도커 호스트로 전송하여 도커 이미지를 독립적으로 배포하고 실행.

 

3. Dockerfile 작성

jar 파일이 있는 곳에 Dockerfile을 만들고 다음과 같이 코드를 작성한다.

FROM openjdk:11
ARG JAR_FILE=*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
  • FROM  :
    • Docker Base Image (기반이 되는 이미지, <이미지 이름>:<태그> : JAVA 11버전
  • ARF :
    • 컨테이너 내에서 사용할 수 있는 변수를 지정
  • COPY :
    • 위에 선언했던 JAR_FILE 변수를 컨테이너의 app.jar로 복사
  • ENTRYPOINT :
    • 컨테이너가 시작되었을 때 스크립트 실행

 

cd 명령어를 통해 jar 파일이 있는 곳으로 터미널 위치를 옮긴다. (cd build/libs)

docker build -t springio/gs-spring-boot-docker .
  •  

(docker build -t {이미지명} .)

docker images

이미지가 생성되었는지 확인

4. 컨테이너 실행

docker run -p 5000:8080 springio/gs-spring-boot-docker

호스트 포트 5000을 컨테이너 포트 8080과 매핑

오류 발생

org.springframework.boot.loader.JarLauncher 클래스의 컴파일된 Java클래스 버전이 호환되지 않아 오류가 발생했다.
현재 Java Runtime 클래스 파일 버전은 61.0인데 현재 사용 중인 Java Runtime은 55.0까지만 지원되기에 오류가 발생하였다.

  • 해결 방법
    1. Java Runtime 업그레이드 : 현재 사용 중인 Java Runtime을 최신버전으로 업그레이드 Java16버전 이상 설치.
    2. 더 오래된 버전의 이미지 사용 : 호환되는 Java Runtime 버전을 사용하는 이미지의 더 오래된 버전을 찾아서 사용

 

 Java 16을 적용하고 하였으나 Java Rutnime은 클래스 파일 버전 60.0까지만 인식 할 수 있으나 현재 클래스 파일 버전이 61.0으로 클래스 파일 버전과 Java Runtime이 호환되지 않아 발생한 에러이다.

 이 경우, JDK17은 클래스 파일 버전 61.0을 지원하므로 JDK17으로 업데이트 한 후 다시 실행해보겠다.
다시 도커파일, 프로젝트 JDK, depedency 등에서 Java17로 바꿔준 후, 도커 컨테이너를 삭제후 다시 생성하여 실행하혔다.

컨테이너가 정상적으로 실행한다.

 스프링 부트가 정상적으로 실행되었고 tomcat웹 서버가 포트 8080에서 정상 시작되었다.
도커 컨테이너가 Running 상태이며, 도커 이미지도 inuse 상태이다.
방화벽 또는 보안 그룹 설정에서 포트 5000이 차단되어 있는지 확인을 해야겠다.

포트 5000번에 대해 액세스를 허용하였다.

여전히 Hello Docker!가 나오지 않는다.
 다른 프로세스가 5000번을 사용 중인지 확인 해봐야겠다.

11380 : Docker Desktop Backend
17980 : Microsoft windows 하위 시스템 서비스 호스트
로 딱히 문제가 없다

application.properties에 가보니 서버 포트에 대한 설정이 없었다.
server.port = 5000으로 다시 설정 해주었다..

혹시 변경사항이 적용되지 않고 이전의 파일들로 계속해서 돌린거가 하여 Intelij를 껐다 키고 gradle build, gradle bootjar도 다시 시작하여 컨테이너와 이미지를 지우고 새로 생성하여 실행하였다.

이제는 서버로부터 응답을 아예 받지 못한다.
build bootjar을 할 당시 이전의 jar파일을 지우지 않고 bootjar을 하여 다른이름의 jar파일이 하나 더 생겼었다 이게 문제였던거 같다.

드디어 제대로 문구가 출력되었다.

반응형

댓글