Я хотел бы упаковать свое приложение 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