Установить пакет в образ Docker, созданный плагином Spring Boot Maven
Мой проект Spring Boot содержит плагин Spring Boot Maven, который я использую для создания образа Docker, запустив
mvn spring-boot:build-image
.
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>build-image</goal>
</goals>
</execution>
</executions>
</plugin>
При развертывании этого образа в стеке Docker мне нужно запустить проверку работоспособности с помощью
curl
команда но к сожалению
curl
не устанавливается пакетом сборки по умолчанию.
Можно ли дополнительно настроить процесс создания образа, чтобы
curl
устанавливается в iamge? Я не смог найти нужную информацию
2 ответа
TLDR;
Установите в образ сборки с помощью:
Идентификатор крабового контейнера остановленного контейнера с:
Создайте новый образ контейнера на основе того, в который мы установили:
Запустите новый контейнер, определяющий правильный запуск приложения Spring Boot:
Теперь все должно быть готово внутри вашего контейнера.
Детали решения:
Обоснование Cloud Native Buildpacks (CNB) и Paketo.io, которые в основном абстрагируются от
build-image
цель состоит в том, чтобы освободить нас от необходимости писать/обслуживать собственные
Dockerfiles
. Итак, инверсия: легко настроить процесс сборки, но нелегко изменить такие вещи, как установленные пакеты.
Причина в том, что эти пакеты хранятся в так называемом build
-время и
run
изображения времени. И если стек не определяет
Но есть другое решение.Поскольку мы не хотим создавать свои собственные стеки/пакеты сборки, мы можем настроить образ контейнера, созданный CNB/
spring-boot-maven-plugin
. Потому что официальные документы показывают нам, mvn spring-boot:build-image
команда создала образ контейнера с именем
my-app:0.0.1-SNAPSHOT
.
Затем сначала мы устанавливаем в образ с помощью:
docker run --user="root" --entrypoint launcher my-app:0.0.1-SNAPSHOT "apt-get update && apt-get install curl -y"
Нам нужно использовать
--user="root"
здесь для того, чтобы команда
apt-get update && apt-get install curl -y
будет работать успешно (иначе мы столкнулись бы с такими ошибками, как
List directory /var/lib/apt/lists/partial is missing. - Acquire (13: Permission denied)
). Это установит curl, но мы не должны использовать полученный контейнер в продакшене. Потому что наше приложение Spring Boot будет работать от имени пользователя root, что создаст множество проблем с безопасностью. Также мы перезаписали наш контейнер, поэтому он не сможет запустить наше приложение.
Поэтому мы просто docker ps -a
:
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2ff7db32825f my-app:0.0.1-SNAPSHOT "launcher 'apt-get u…" 44 minutes ago Exited (0) 44 minutes ago reverent_swanson
И создайте новый образ контейнера на основе того, который мы установили.
curl
в с:
docker commit 2ff7db32825f my-app-with-curl
Наконец , запустите новый контейнер на основе этого нового изображения, определив правильный
ENTRYPOINT
чтобы запустить наше приложение Spring Boot, а также с помощью
cnb
снова пользователем (как определено в Cloud Native Buildpacks):
docker run --rm -p 8080:8080 --user="cnb" --entrypoint /cnb/process/web my-app-with-curl
Не по теме, но актуально :
В настоящее время ведутся дискуссии о целесообразности установки curl в производственном контейнере.
В итоге я использовал смонтированный том (
/utils
например) со статическим скомпилированным завитком (https://github.com/moparisthebest/static-curl) и настроенной проверкой работоспособности, например
/utils/curl http://localhost:8080/actuator/health