Поддержка Docker Compose в Spring Boot 3.1

от автора

Иногда перед разработчиком встает задача воссоздания некоторого окружения локально. В него часто входят различные компоненты инфраструктуры, такие как:

  • PostgreSQL

  • Kafka

  • RabbitMQ

  • Redis

И так далее. Менеджить целый зоопарк таких сервисов локально бывает не очень удобно. К счастью, у команды Spring Boot для вас есть небольшой помошник — Spring Boot Docker Compose.

Комментарий от Михаила Поливахи:
Друзья, хоть на дворе уже Spring Boot 4, мы знаем, что большинство из вас сидит на Spring Boot 3. И мы посчитали очень нужным рассказать о таком Spring Boot инструменте, который, на наш взгляд, делает локальную разработку со Spring Boot намного более приятной.


Поддержка Docker Compose в Spring Boot 3.1 построена поверх абстракции ConnectionDetails, о которой мы рассказывали в отдельном посте блога. Если вы ещё не читали его, пожалуйста, сделайте это перед чтением этой статьи.

Docker Compose «— это инструмент для определения и запуска многоконтейнерных Docker-приложений». Файл конфигурации Docker Compose, обычно называемый docker-compose.yaml или compose.yaml, позволяет определять сервисы. У таких сервисов должно быть имя и Docker-образ. Опционально можно также задавать переменные окружения, проброшенные порты, метки, взаимосвязи сервисов друг с другом и так далее.

Вот типичный пример простого файла Docker Compose:

services:  database:  image: 'postgres:15.2'  ports:    - '5432'  environment:    - 'POSTGRES_USER=myuser'    - 'POSTGRES_DB=mydatabase'    - 'POSTGRES_PASSWORD=secret'

Он определяет один сервис с именем database, который использует Docker-образ postgres:15.2. Он открывает порт контейнера 5432 (это порт PostgreSQL по умолчанию), а Docker при запуске выбирает случайный порт на хосте. Кроме того, в нём заданы переменные окружения, которые настраивают пользователя, пароль и имя базы данных.

Если вы выполните docker compose up в каталоге, где лежит этот файл, Docker Compose сначала проверит, запущен ли уже этот сервис. Если нет, он запустит новый контейнер на основе образа postgres:15.2 и настроит его.

Теперь можно выполнить docker compose ps и увидеть, что контейнер запущен:

$ docker compose psNAME IMAGE COMMAND SERVICE CREATED STATUS PORTSdocker-compose-test-database-1 postgres:15.2 "docker-entrypoint.s…" database 7 seconds ago Up 6 seconds 0.0.0.0:32768->5432/tcp, :::32768->5432/tcp

Чтобы разрабатывать против этого сервиса в приложении, написанном до Spring Boot 3.1, вам нужно добавить некоторые свойства конфигурации — возможно, в каком-нибудь «developer»-профиле:

spring.datasource.url=jdbc:postgresql://localhost:32768/mydatabasespring.datasource.username=myuserspring.datasource.password=secret

Это настраивает Spring Boot на использование базы PostgreSQL, работающей внутри Docker-контейнера (подключение идёт к порту хоста 32768).

Когда вы заканчиваете работу с сервисом, обычно выполняют docker compose down, чтобы остановить и удалить контейнеры. Но когда вы запустите их снова, вы увидите, что динамический порт изменился:

$ docker compose psNAME IMAGE COMMAND SERVICE CREATED STATUS PORTSdocker-compose-test-database-1 postgres:15.2 "docker-entrypoint.s…" database 4 minutes ago Up 1 second 0.0.0.0:32769->5432/tcp, :::32769->5432/tcp

О нет — значит, теперь вам придётся обновлять конфигурацию приложения!

К счастью, у Docker Compose есть решение. Не используйте случайные порты — используйте фиксированный порт хоста:

services:  database:  image: 'postgres:15.2'  ports:    - '15432:5432'  environment:    - 'POSTGRES_USER=myuser'    - 'POSTGRES_DB=mydatabase'    - 'POSTGRES_PASSWORD=secret'

Теперь каждый раз при запуске контейнер будет доступен на localhost:15432.

Это работает, но возникает другая проблема. Если вы разрабатываете несколько приложений, и у каждого приложения своя база данных (что довольно распространено в микросервисных архитектурах), вам нужно помнить о разных портах хоста. Если не помнить, некоторые команды docker compose up будут падать, потому что порт уже занят.

А теперь хорошие новости. В Spring Boot 3.1 всё становится для вас значительно проще. Вы можете продолжать использовать случайные порты хоста, но вам не нужно задавать свойства конфигурации и не нужно дублировать имена пользователей, пароли и так далее в нескольких местах. Также вам не нужно помнить о том, что перед запуском приложения надо выполнить docker compose up.

Spring Boot 3.1 обнаружит, что рядом есть файл Docker Compose, и сам выполнит docker compose up перед подключением к сервисам. Если сервисы уже запущены, он тоже это определит и будет использовать их. Он также выполнит docker compose stop при завершении работы приложения — уходят в прошлое времена, когда зависшие Docker-контейнеры пожирали вашу драгоценную память.

Образы, запущенные Docker Compose, автоматически обнаруживаются и используются для создания бинов ConnectionDetails, указывающих на сервисы. Это означает, что вам не нужно прописывать свойства в конфигурации, не нужно помнить, как правильно составлять JDBC-URL для PostgreSQL, и так далее.

В Spring Boot 3.1 вам достаточно предоставить файл compose.yaml и позволить Spring Boot самому разобраться с остальным. Это просто работает!

На момент написания мы поддерживаем следующие Docker-образы:

Cassandra — cassandra
Elasticsearch — elasticsearch
Oracle Database — gvenzl/oracle-xe
MariaDB — mariadb
Microsoft SQL Server — mssql/server
MySQL — mysql
PostgreSQL — postgres
MongoDB — mongo
RabbitMQ — rabbitmq
Redis — redis
Zipkin — openzipkin/zipkin

Хотите попробовать сами? Мы подготовили документацию, которая поможет начать.

Мы также добавили поддержку Docker Compose на start.spring.io, чтобы вы могли стартовать ещё быстрее! Например, если вы сгенерируете проект с зависимостями «Docker Compose support» и «PostgreSQL driver», вы бесплатно получите разумный compose.yaml! Разве это не невероятно круто?!

«Ладно, ладно, — слышу я, — а что насчёт нашего кастомного Redis-образа, который мы используем в компании?». Мы и тут вас прикрыли: вы можете собрать свой образ, поставить на него метку, и Spring Boot будет считать его официальным образом. Просто убедитесь, что вы используете те же имена переменных окружения, что и официальный образ.

Мы также поддерживаем игнорирование сервисов, Docker Compose-файлы с необычными именами и профили Docker Compose.

Присоединяйтесь к русскоязычному сообществу разработчиков на Spring Boot в телеграм — Spring АйО, чтобы быть в курсе последних новостей из мира разработки на Spring Boot и всего, что с ним связано.

ссылка на оригинал статьи https://habr.com/ru/articles/1031216/