Рубрики
Без рубрики

Докеризация приложения Spring Boot

В статье объясняется запуск двух приложений Spring Boot в разных контейнерах docker, но они взаимодействуют с хост-системой и отображаются как единое целое.

Автор оригинала: baeldung.

1. Обзор

В этой статье мы сосредоточимся на том, как докеризировать приложение Spring Boot для запуска его в изолированной среде, известной как контейнер .

Кроме того, мы покажем, как создать композицию контейнеров, которые зависят друг от друга и связаны друг с другом в виртуальной частной сети. Мы также посмотрим, как ими можно управлять вместе с помощью отдельных команд.

Давайте начнем с создания простого приложения Spring Boot, которое мы затем запустим в легком базовом образе под управлением Alpine Linux .

2. Докеризация автономного приложения Spring Boot

В качестве примера приложения, которое мы можем докеризировать, мы создадим простое приложение Spring Boot docker-message-server , которое предоставляет одну конечную точку и возвращает статическое сообщение:

@RestController
public class DockerMessageController {
    @GetMapping("/messages")
    public String getMessage() {
        return "Hello from Docker!";
    }
}

С помощью правильно настроенного файла Maven мы можем создать исполняемый файл jar:

$> mvn clean package

И запустите приложение Spring Boot:

$> java -jar target/docker-message-server-1.0.0.jar

Теперь у нас есть работающее приложение Spring Boot, к которому мы можем получить доступ по адресу localhost:8888/messages.

Чтобы докеризировать приложение, мы сначала создаем файл с именем Dockerfile со следующим содержимым:

FROM openjdk:8-jdk-alpine
MAINTAINER baeldung.com
COPY target/docker-message-server-1.0.0.jar message-server-1.0.0.jar
ENTRYPOINT ["java","-jar","/message-server-1.0.0.jar"]

Этот файл содержит следующую информацию:

  • ИЗ : В качестве основы для нашего образа мы возьмем Java -enabled Alpine Linux , созданный в предыдущем разделе.
  • СОПРОВОЖДАЮЩИЙ : Сопровождающий изображения.
  • КОПИРОВАТЬ : Мы позволяем Докеру скопировать наш файл jar в изображение.
  • ТОЧКА ВХОДА : Это будет исполняемый файл, который будет запущен при загрузке контейнера. Мы должны определить их как JSON-Array , потому что мы будем использовать ENTRYPOINT в сочетании с CMD для некоторых аргументов приложения.

Чтобы создать образ из нашего Dockerfile , мы должны запустить ‘docker build’ , как и раньше:

$> docker build --tag=message-server:latest .

Наконец, мы можем запустить контейнер из нашего образа:

$> docker run -p8887:8888 message-server:latest

Это запустит наше приложение в Docker, и мы сможем получить к нему доступ с хост-машины по адресу localhost:8887/messages . Здесь важно определить сопоставление портов, которое сопоставляет порт на хосте (8887) с портом внутри Docker ( 8888 ), который является портом, который мы определили в свойствах приложения Spring Boot.

Примечание: Порт 8887 может быть недоступен на машине, на которой мы запускаем контейнер. В этом случае сопоставление может не сработать, и нам нужно выбрать порт, который все еще доступен.

Если мы запустим контейнер в отдельном режиме, мы можем проверить его детали, остановить его и удалить с помощью следующих команд:

$> docker inspect message-server
$> docker stop message-server
$> docker rm message-server

2.1. Изменение базового изображения

Мы можем легко изменить базовый образ, чтобы использовать другую версию Java. Например, если мы хотим использовать дистрибутив Corretto от Amazon, мы можем просто изменить файл Dockerfile :

FROM amazoncorretto:11-alpine-jdk
MAINTAINER baeldung.com
COPY target/docker-message-server-1.0.0.jar message-server-1.0.0.jar
ENTRYPOINT ["java","-jar","/message-server-1.0.0.jar"]

Кроме того, мы можем использовать пользовательский базовый образ. Мы рассмотрим, как это сделать позже в этой статье.

3. Докеризованные приложения в составном

Команды Docker и Dockerfiles особенно подходят для создания отдельных контейнеров. Но если вы хотите работать в сети изолированных приложений , управление контейнерами быстро становится захламленным.

Чтобы решить эту проблему, Docker предоставляет инструмент с именем Docker Compose . Он поставляется с собственным файлом сборки в формате YAML и лучше подходит для управления несколькими контейнерами. Например, он может запускать или останавливать набор служб в одной команде или объединять выходные данные журнала нескольких служб вместе в один псевдо-tty .

3.1. Второе приложение Spring Boot

Давайте построим пример двух приложений, работающих в разных контейнерах Docker. Они будут взаимодействовать друг с другом и представляться хост-системе как “единое целое”. В качестве простого примера мы создадим второе приложение Spring Boot docker-product-server :

@RestController
public class DockerProductController {
    @GetMapping("/products")
    public String getMessage() {
        return "A brand new product";
    }
}

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

3.2. Файл Docker Compose

Мы можем объединить конфигурацию для обеих служб в одном файле с именем docker-compose.yml :

version: '2'
services:
    message-server:
        container_name: message-server
        build:
            context: docker-message-server
            dockerfile: Dockerfile
        image: message-server:latest
        ports:
            - 18888:8888
        networks:
            - spring-cloud-network
    product-server:
        container_name: product-server
        build:
            context: docker-product-server
            dockerfile: Dockerfile
        image: product-server:latest
        ports:
            - 19999:9999
        networks:
            - spring-cloud-network
networks:
    spring-cloud-network:
        driver: bridge
  • версия : Указывает, какая версия формата должна использоваться. Это обязательное поле. Здесь мы используем более новую версию, в то время как устаревший формат равен “1”.
  • сервисы : Каждый объект в этом ключе определяет сервис , он же контейнер. Этот раздел является обязательным.

    • build : Если задано, docker-compose может создать образ из Dockerfile

      • контекст : Если задан, он указывает каталог сборки, в котором ищется файл Dockerfile|/. dockerfile
      • : Если задано, он задает альтернативное имя для Dockerfile. image
    • : Указывает Docker , какое имя он должен дать образу при использовании функций сборки. В противном случае он ищет этот образ в библиотеке или удаленном реестре. сети
    • : Это идентификатор используемых именованных сетей. Заданное имя-значение должно быть указано в разделе сети . сети
  • : В этом разделе мы указываем сети , доступные для наших сервисов . В этом примере мы позволяем docker-compose создать именованную сеть типа ‘bridge’ для нас. Если параметр external имеет значение true , он будет использовать существующий с заданным именем.

Прежде чем мы продолжим, мы проверим ваш файл сборки на наличие синтаксических ошибок:

$> docker-compose config

Наконец, мы можем построить наши образы, создать определенные контейнеры и запустить их в одной команде:

$> docker-compose up --build

Это приведет к запуску сервера сообщений и сервера продуктов за один раз.

Чтобы остановить контейнеры, удалите их из Docker и удалите из него подключенные сети , мы можем использовать противоположную команду:

$> docker-compose down

Более подробное введение в docker-compose вы можете прочитать в нашей статье Введение в Docker Compose .

3.3. Услуги масштабирования

Приятной особенностью docker-compose является возможность масштабирования сервисов . Например, мы можем указать Docker запустить три контейнера для сервера сообщений и два контейнера для сервера продуктов .

Но для того, чтобы это работало должным образом , мы должны удалить container_name из нашего docker-compose.yml , чтобы позволить Docker выбрать один , и мы должны изменить конфигурацию открытого порта , чтобы избежать столкновений.

Для портов мы можем указать Docker сопоставить диапазон портов на хосте с одним конкретным портом внутри Docker:

ports:
    - 18800-18888:8888

После этого мы можем масштабировать наши сервисы следующим образом (обратите внимание, что мы используем модифицированный yml-файл ):

$> docker-compose --file docker-compose-scale.yml up -d --build --scale message-server=1 product-server=1

Эта команда запустит один сервер сообщений и один сервер продуктов .

Чтобы масштабировать наши службы, мы можем выполнить следующую команду:

$> docker-compose --file docker-compose-scale.yml up -d --build --scale message-server=3 product-server=2

Эта команда запустит два дополнительных сервера сообщений и один дополнительный сервер продуктов. Работающие контейнеры не будут остановлены.

4. Пользовательское Базовое изображение

Базовый образ ( openjdk:8-jdk-alpine ), который мы использовали до сих пор, содержал дистрибутив операционной системы Alpine с уже установленным JDK 8. Кроме того, мы можем создать ваш собственный базовый образ (на основе Alpine или любой другой операционной системы).

Для этого мы можем использовать файл Dockerfile с Alpine в качестве базового образа и установить JDK по нашему выбору:

FROM alpine:edge
MAINTAINER baeldung.com
RUN apk add --no-cache openjdk8
  • FROM : Ключевое слово FROM указывает Docker использовать данное изображение с его тегом в качестве базы сборки. Если этого образа нет в локальной библиотеке, выполняется онлайн-поиск в Docker Hub или в любом другом настроенном удаленном реестре
  • СОПРОВОЖДАЮЩИЙ :/| СОПРОВОЖДАЮЩИЙ обычно представляет собой адрес электронной почты, идентифицирующий автора изображения RUN
  • : С помощью команды RUN мы выполняем командную строку оболочки в целевой системе. Здесь мы Alpine Linux менеджер пакетов apk для установки Java 8 OpenJDK

Чтобы окончательно создать образ и сохранить его в локальной библиотеке, мы должны запустить:

docker build --tag=alpine-java:base --rm=true .

ОБРАТИТЕ ВНИМАНИЕ: Опция –tag даст изображению его имя и –rm=true удалит промежуточные изображения после того, как оно будет успешно построено. Последний символ в этой команде оболочки-точка, выступающая в качестве аргумента каталога сборки.

Теперь мы можем использовать созданный образ вместо openjdk:8-jdk-alpine .

5. Поддержка пакетов сборки в Spring Boot 2.3

Spring Boot 2.3 добавлена поддержка buildpacks . Проще говоря, вместо того , чтобы создавать наш собственный файл Dockerfile и создавать его с помощью чего-то вроде docker build , все, что нам нужно, это выполнить следующую команду:

$ mvn spring-boot:build-image

Или в Gradle:

$ ./gradlew bootBuildImage

Чтобы это сработало, нам нужно, чтобы Docker был установлен и запущен.

Основной мотивацией buildpacks является создание такого же опыта развертывания, который некоторое время предоставляют некоторые известные облачные сервисы, такие как Heroku или Cloud Foundry. Мы просто запускаем цель build-image , и сама платформа заботится о создании и развертывании артефакта.

Более того, это может помочь нам более эффективно изменить способ создания изображений Docker . Вместо того, чтобы применять одно и то же изменение ко множеству файлов Dockerfile в разных проектах, все, что нам нужно сделать, это изменить или настроить конструктор изображений buildpacks.

В дополнение к простоте использования и лучшему общему опыту разработчиков, он также может быть более эффективным . Например, подход buildpacks создаст многоуровневый образ Docker и использует разнесенную версию файла Jar.

Давайте посмотрим, что произойдет после выполнения приведенной выше команды.

Когда мы перечислим доступные образы докеров:

docker image ls -a

Мы видим линию для только что созданного изображения:

docker-message-server 1.0.0 b535b0cc0079

Здесь имя и версия образа соответствуют имени и версии, которые мы определили в файле конфигурации Maven или Gradle. Хэш – код – это сокращенная версия хэша изображения.

Чтобы запустить наш контейнер, мы можем просто запустить:

docker run -it -p9099:8888 docker-message-server:1.0.0

Как и в случае с нашим встроенным образом, нам нужно сопоставить порт, чтобы наше приложение Spring Boot было доступно извне Docker.

6. Заключение

Как мы уже видели, теперь мы можем создавать пользовательские образы Docker , запускать приложение Spring Boot в качестве контейнера Docker и создавать контейнеры с помощью docker-compose .

Для получения дополнительной информации о файлах сборки мы ссылаемся на официальную ссылку Dockerfile и docker-compose.ссылка на yml .

Как обычно, исходные коды для этого учебника можно найти на Github .