Не могу упаковать приложение Spring Boot с помощью Jib

Я хотел бы упаковать свое приложение Spring Boot как контейнер Docker, используя Jib с Gradle.

Еще Помимо следующих readme Jib, Я скопировал образец из простого проекта JHipster. Угадай, что? Это не сработало.

Хорошо, вот код.

Генератор JHipster создает специальный gradle/docker.gradle файл, который применяется из основного файла сборки Gradle, и импортирует плагин Jib.

Поэтому я скопировал файл JH jib, чтобы начать

My gradle/jib.gradle

jib {
    from {
//        image = "adoptopenjdk:8-jre"
        image = "adoptopenjdk:11-jre-hotspot"
    }
    to {
        image = "myapp:latest"
    }
    container {
        entrypoint = ["bash", "-c", "/entrypoint.sh"]
        ports = ["8080"]
        environment = [
            SPRING_OUTPUT_ANSI_ENABLED: "ALWAYS",
            SPRBOOT_SLEEP: "0"
        ]
        creationTime = "USE_CURRENT_TIMESTAMP"
    }
    extraDirectories {
      paths = file("src/main/jib")
      permissions = ["/entrypoint.sh": "755"]
    }
}

Прокомментированная часть связана с тем, что я хочу использовать JDK8, но я пытаюсь использовать то, что сделал JHipster.

Во-вторых, я скопировал свой собственный entrypoint.sh на основе репозитория JH. Вот src/main/jib/entrypoint.sh

#!/bin/sh

echo "The application will start in ${SPRBOOT_SLEEP}s..." && sleep "${SPRBOOT_SLEEP}" # Author's note: it's pointless
exec java "${JAVA_OPTS}" -noverify \
  -XX:+AlwaysPreTouch \
  -Djava.security.egd=file:/dev/./urandom \
  -cp /app/resources/:/app/classes/:/app/libs/* \
  "com.acme.MyApplication" "$@"

И, конечно же, мне пришлось добавить jib плагин 3.0.0 в свой файл Gradle, применив jib.gradle скрипт

plugins {
    id 'org.springframework.boot' version '2.4.2'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'java'
    id 'war'
    id "com.google.cloud.tools.jib" version '3.0.0'
    id 'org.unbroken-dome.test-sets' version '3.0.1'
    id 'org.flywaydb.flyway' version '7.5.4' apply false
    id 'com.telenia.gradle.MybatisGenerator' version '2.1.5'
    id 'net.ltgt.apt-eclipse' version '0.21' apply false
}

apply from: 'gradle/jib.gradle'

Время объяснения

Теперь я ожидаю, что gradle jibDockerBuild создаст контейнер с файлами моего приложения в /app и запустит исполняемый файл Spring Boot, используя точку входа. Меня не волнует сон, он равен 0 и наследуется JH

Конечно, когда я создаю образ Docker из проекта JHipster, он работает как шарм. Когда я создаю свой собственный контейнер, запускать его не удается с классической ошибкой Unable to locate main class.

The application will start in 0s...

Error: Could not find or load main class

Caused by: java.lang.ClassNotFoundException:

Я пробовал bash в контейнер, а /app каталога вообще нет. Под встроенным контейнером JHipster есть каталог /app.

Пытаясь изучить оба изображения при написании этого сообщения, я обнаружил несколько отличий. JHipster развертывает файлы под /app, а мой скрипт Gradle развертывает jar-файлы под /var/lib/jetty/webapps/ROOT. Мое приложение включает плагин war последовательно, в то время как JHipster включает плагин, только если установлена ​​переменная -Pwar.

Я не забочусь об использовании в образе войны или встроенного сервера, как только результат будет производственным. Мне все еще нужно создать файл войны.

Вопрос

Как правильно настроить существующий проект Spring Boot на основе Gradle для создания контейнера Docker с использованием Jib? Что не так в моем коде, учитывая, что я отдал приоритет существующему коду от JHipster, основанному на Spring Boot?

Редактировать 1

Круто: в проекте JHipster gradle -Pwar jibDockerBuild развертывает файлы в /jetty/webapps внутри контейнера, и когда я запускаю приложение, я получаю волшебную ошибку Could not find or load main class


person usr-local-ΕΨΗΕΛΩΝ    schedule 10.05.2021    source источник


Ответы (2)


Моя ошибка заключалась в том, что я не читал полностью документацию по Jib.

Jib решает, что делать с военными проектами.

Jib также занимается контейнеризацией проектов WAR. Если проект Gradle использует подключаемый модуль WAR, Jib по умолчанию будет использовать причал в качестве базового образа для развертывания WAR проекта. Никакой дополнительной настройки не требуется, кроме использования подключаемого модуля WAR для создания образов WAR Jib.

И это, вероятно, причина, по которой JHipster требует свойство запуска -Pwar для раскрытия военных задач, чтобы вы могли либо создать контейнерную версию Spring Boot jar, либо контейнер, созданный на веб-сервере, для итогового файла войны.

Как мне не стыдно за то, что не прочитал документы

person usr-local-ΕΨΗΕΛΩΝ    schedule 10.05.2021

Для тех, кто может просто начать использовать Jib с Spring Boot, но у него возникла проблема по каким-либо причинам:

В большинстве случаев Jib должен работать из коробки с Spring Boot. Вот минимальная демонстрация:

  1. Создайте приложение Spring Boot, например, с помощью Spring Initializr. Неважно, проект это Maven или Gradle:
    $ curl https://start.spring.io/starter.tgz \
        -d type=gradle-project \
        -d dependencies=web \
        -d baseDir=demo | tar -xzvf -
    
  2. Откройте build.gradle и примените плагин Jib.
     plugins {
         id 'org.springframework.boot' version '2.4.5'
         id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    +    id 'com.google.cloud.tools.jib' version '3.0.0'
         id 'java'
     }
    
  3. Контейнеровоз с Jib.
    $ ./gradlew jibDockerBuild
    
  4. Запускаем образ. (Приложение будет доступно по адресу localhost:8080.)
    $ docker run --rm -p8080:8080 demo:0.0.1-SNAPSHOT
    

Это была минимальная настройка, но вы наверняка захотите дополнительно настроить конфигурацию Jib.

Наконец, по возможности предпочитайте <packaging>jar war.

person Chanseok Oh    schedule 10.05.2021