>  기사  >  Java  >  빌드팩을 사용하여 Spring Boot 애플리케이션의 Docker 이미지 만들기

빌드팩을 사용하여 Spring Boot 애플리케이션의 Docker 이미지 만들기

WBOY
WBOY원래의
2024-09-08 20:31:02872검색

Creating Docker Image of Spring Boot Application using Buildpacks

소개

Spring Boot 애플리케이션을 생성했습니다. 로컬 컴퓨터에서 잘 작동하므로 이제 다른 곳에 애플리케이션을 배포해야 합니다. 일부 플랫폼에서는 jar 파일을 직접 제출하면 배포됩니다. 어떤 곳에서는 가상 머신을 가동하고 소스 코드를 다운로드하여 빌드하고 실행할 수 있습니다. 그러나 대부분의 경우 컨테이너를 사용하여 애플리케이션을 배포해야 합니다. 대부분의 경우 Docker는 컨테이너에서 이미지를 빌드하고 실행하는 데 사용됩니다. 또한 일부 플랫폼에 jar 파일을 업로드하면 애플리케이션이 후드 아래 컨테이너 내부에서 실행됩니다.

그래서 이 블로그에서는 특정 Spring Boot 애플리케이션에 대한 Docker 이미지를 빌드하는 3가지 방법을 살펴보겠습니다. 시작해 보세요:

기본 컨테이너 이미지

모든 애플리케이션에 대한 Docker 이미지를 빌드하는 순진하고 불충분한 방법은 이미지 내부의 jar 파일을 복사하고 java -jar 명령을 사용하여 실행하는 간단한 Dockerfile을 사용하는 것입니다.

Dockerfile 만들기

다음은 프로젝트 루트에 넣을 수 있는 Dockerfile입니다.

FROM eclipse-temurin:21-jre-ubi9-minimal

ARG JAR_FILE

COPY ${JAR_FILE} application.jar

ENTRYPOINT ["java", "-jar", "/application.jar"]

사용할 jar 파일의 위치인 JAR_FILE 인수 하나를 지정했습니다.

Docker 이미지 빌드

위의 Dockerfile을 생성한 후 아래 단계에 따라 Docker 이미지를 생성합니다.

  1. Spring Boot 프로젝트용 jar 파일 빌드:

    ./gradlew bootJar # For Gradle build system
    

    또는

    ./mvnw spring-boot:build-jar # For Maven build system
    
  2. 최신 jar 파일을 사용하여 Docker 이미지를 빌드하려면 Dockerfile을 사용하세요. 아래 명령에서 {IMAGE_NAME}을 필수 이미지 이름으로 바꾸고 {JAR_FILE}을 생성된 jar 파일의 경로로 바꿉니다. 이미지 이름에는 - mycompany/product-service:0.0.1-SNAPSHOT:
    과 같은 태그도 포함되어 있습니다.

    docker build --build-arg JAR_FILE={JAR_FILE} --tag {IMAGE_NAME} .
    
  3. 다음 명령을 사용하여 Docker 이미지가 빌드되었는지 확인하세요. 위 명령에 지정된 이름의 이미지를 볼 수 있습니다.

    docker images
    

Layered Jar를 이용한 효율적인 컨테이너 이미지

Spring Boot uber jar를 Docker 이미지로 패키징하는 것이 가능하고 쉽지만(이전 방법에서 언급했듯이), fat jar를 Docker 이미지에서 그대로 복사하고 실행하는 데는 많은 단점이 있습니다. 예를 들어

  • Uber Jar를 포장을 풀지 않고 실행할 경우 추가 오버헤드가 발생합니다.
  • 애플리케이션의 코드와 모든 종속 항목을 단일 레이어에 배치하는 것은 최적이 아닙니다.

Spring Boot 버전을 업그레이드하는 것보다 코드를 더 자주 컴파일하므로 좀 더 분리하는 것이 좋습니다. 거의 변경되지 않는 jar 파일을 애플리케이션 계층 이전 계층에 배치하면 Docker는 종종 맨 아래 계층만 변경하면 되고 나머지는 캐시에서 선택할 수 있습니다.

계층화된 항아리 활성화

계층형 Docker 이미지를 생성하려면 먼저 계층형 jar을 생성해야 합니다. 요즘은 Gradle과 Maven에서 기본적으로 활성화되어 있습니다. 다음 설정을 사용하여 계층화된 jar 동작을 활성화하거나 비활성화할 수 있습니다.

// build.gradle
tasks.named("bootJar") {
    layered {
        enabled = false
    }
}
// build.gradle.kts
tasks.named7e534d3bd056dd41a31367722242bb81("bootJar") {
   layered {
      enabled.set(false)
   }
}
7a7963d93b467c9ab002af7a44e64bd4
c70346ba2d7be186a93fef826469bd2f
   5ac54a929980b32fdd2e48b6a8da067c
      c4222ff3007372f15ec728b963e717b6
         33ca7039399a4759a8764ea38765dd46
            05a8acc5c31084a4f61ade01873802caorg.springframework.boot192ca2f7b8c770b01c8f81e6bdd5b947
            9bc4cbb67f66e148869423c0d27e5f90spring-boot-maven-pluginb68fb17cb904a46b73e6272850323873
            f9d9f4a8f32d97f3ef0c10742ed31240
               e72a6d14eb9b15c1c12186917135155b
                  d79c9ed277a80783d30ca709c63bc2d1true1d1b3b9680fd03597e1ed3fa2b627c20
               98a78221d1c969529e0b9f39a24b39b0
            4b1b9d85fe86862ae3eab7e2045cf8a0
         9424ec9162a9b85f34067d0c54f34b32
      f3567a435ac6132b26525998d793443b
   f82c24fb6fac67972f6e79c18ccef56a
1755c7176d4002e2a322de4f48c796fa

레이어 생성 방법을 조정할 수도 있습니다. Gradle 또는 Maven 구성에 대한 문서를 참조하세요.

Dockerfile 만들기

다음은 계층화된 jar를 활용하고 Spring Boot 애플리케이션의 계층화된 Docker 이미지를 생성하는 데 사용할 수 있는 Dockerfile입니다.

# Perform the extraction in a separate builder container
FROM eclipse-temurin:21-jre-ubi9-minimal AS builder

WORKDIR /builder

# This points to the built jar file in the target folder
# Adjust this to 'build/libs/*.jar' if you're using Gradle
ARG JAR_FILE=target/*.jar

# Copy the jar file to the working directory and rename it to application.jar
COPY ${JAR_FILE} application.jar

# Extract the jar file using an efficient layout
RUN java -Djarmode=tools -jar application.jar extract --layers --destination extracted

# This is the runtime container
FROM eclipse-temurin:21-jre-ubi9-minimal

WORKDIR /application

# Copy the extracted jar contents from the builder container into the working directory in the runtime container
# Every copy step creates a new docker layer
# This allows docker to only pull the changes it really needs
COPY --from=builder /builder/extracted/dependencies/ ./
COPY --from=builder /builder/extracted/spring-boot-loader/ ./
COPY --from=builder /builder/extracted/snapshot-dependencies/ ./
COPY --from=builder /builder/extracted/application/ ./

# Start the application jar - this is not the uber jar used by the builder
# This jar only contains application code and references to the extracted jar files
# This layout is efficient to start up and CDS friendly
ENTRYPOINT ["java", "-jar", "application.jar"]

Docker 이미지 빌드

계층화된 Docker 이미지를 빌드하는 단계는 기본 Docker 이미지를 빌드하는 단계와 동일합니다. 거기 참고해주세요.

클라우드 네이티브 빌드팩

Dockerfile을 만들지 않고도 Docker 이미지를 만들 수 있다고 말하면 어떻게 되나요? Cloud Native Buildpack을 사용하여 Gralde 또는 Maven 플러그인에서 직접 Docker 이미지를 빌드할 수 있습니다. 일부 플랫폼(예: Heroku 또는 Cloud Foundry)은 Buildpack을 사용하여 제공된 jar 파일을 실행 가능한 이미지로 변환합니다.

Spring Boot에는 Maven 및 Gradle에 대한 빌드팩 지원이 직접 포함되어 있습니다. 추가 플러그인을 포함할 필요는 없습니다. 아래 명령을 실행하세요:

./gradlew bootBuildImage # For gradle build system

또는

./mvnw spring-boot:build-image # For maven build system

위 명령은 기본 이름이 {PROJECT_NAME}:${PROJECT_VERSION}인 이미지를 생성합니다. 생성된 이미지의 이름을 구성하려면 다음 단계를 따르세요.

Gradle 빌드 시스템의 이미지 이름 구성

다음과 같이 이미지 이름을 설정하도록 bootBuildImage 작업을 구성할 수 있습니다.

// For build.gradle.kts
val imagePrefix = "javarush"
val dockerImageName = "docker-example"
tasks.named2e00f062267875fb651ebdd74d6c6eb1("bootBuildImage") {
   imageName.set("${imagePrefix}/${dockerImageName}:${version}")
}
// For build.gradle
def imagePrefix = "javarush"
def dockerImageName = "docker-example"
tasks.named("bootBuildImage") {
   imageName = "${imagePrefix}/${dockerImageName}:${version}"
}

Maven 빌드 시스템의 이미지 이름 구성

다음과 같이 spring-boot-maven-plugin을 구성하여 다른 이미지 이름을 사용할 수 있습니다.

a01741acb88936e4cea4237317380dd9
   d025b153d4d19d25710ee358f3c66eafjavarush515db9ab99a6918e33f7eeaddd64c8cf
86cd8b5c0fbd401fb69261955cf13796

...

c70346ba2d7be186a93fef826469bd2f
    5ac54a929980b32fdd2e48b6a8da067c
        c4222ff3007372f15ec728b963e717b6
            33ca7039399a4759a8764ea38765dd46
                05a8acc5c31084a4f61ade01873802caorg.springframework.boot192ca2f7b8c770b01c8f81e6bdd5b947
                9bc4cbb67f66e148869423c0d27e5f90spring-boot-maven-pluginb68fb17cb904a46b73e6272850323873
                f9d9f4a8f32d97f3ef0c10742ed31240
                    dc0870658837139040642baa5555a380
                        8a11bc632ea32a57b3e3693c7987c420${imagePrefix}/${project.artifactId}:${project.version}df406f776eecbaf16b62325323196f14
                    f8e950ebc6c1ea27f76cf997b9216fe6
                4b1b9d85fe86862ae3eab7e2045cf8a0
            9424ec9162a9b85f34067d0c54f34b32
        f3567a435ac6132b26525998d793443b
    f82c24fb6fac67972f6e79c18ccef56a
1755c7176d4002e2a322de4f48c796fa

명령을 실행하는 동안 이미지 이름 구성

이미지를 빌드하는 명령을 실행하는 동안 이미지 이름을 정의할 수도 있습니다.

./gradlew bootBuildImage --imageName=javarush/docker-example:1.0.0 # For grade build system

./mvnw spring-boot:build-image -Dspring-boot.build-image.imageName=javarush/docker-example:1.0.0 # For maven build system

You can see the documentation to further configure Gradle or Maven plugin.
This is my go-to method to create a Docker image for any Spring Boot application.

Running Docker Container

Once you create a docker image, you need to make sure that it works as expected. After you make sure that the image is created, you can directly run it using the docker run command. For example,

docker run -p "8080:8080" {IMAGE_NAME}

But, this is not how images are used in production applications. Docker Compose is used to run and manage multiple docker images.

Conclusion

In this blog, we have seen how to build Docker images for Spring Boot applications using different methods. Being able to build docker images for your apps is a must skill to know because the image is what gets delivered. Thanks for reading the article till the end. I appreciate it. I will meet you in the next one. As always, all feedback and suggestions are welcome.

위 내용은 빌드팩을 사용하여 Spring Boot 애플리케이션의 Docker 이미지 만들기의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.