Использование Docker в разработке приложений Java EE
Я добавлю 300 очков в качестве награды
Недавно я начал более внимательно смотреть на Docker и как я могу использовать его для быстрого получения нового члена команды и работы с средой разработки, а также для доставки новых версий программного обеспечения на производство.
У меня есть некоторые вопросы относительно того, как и на какой стадии я должен добавить приложение Java EE в контейнер. Как я вижу, это несколько способов сделать это.
Это был обычный рабочий процесс (в моей команде) до Docker:
- Разработчик пишет код
- Разработчик создает код с Maven, производящим WAR
- Разработчик загружает WAR в консоль администратора JBoss/или с плагином Maven
Теперь, когда Docker пришел, я немного смущен, если я должен создать нужные мне изображения и настроить их так, чтобы все, что осталось сделать при запуске контейнера JBoss Wildfly, - это развернуть приложение через консоль администратора В интернете. Или я должен создать новый контейнер для каждого раза, когда я создам приложение в Maven и добавлю его с помощью команды ADD
в файл Dockerfile, а затем просто запустите контейнер, не создавая его после его запуска?
В производстве я предполагаю, что последний подход - это то, что он предложил? Поправьте меня, если я ошибаюсь.
Но в разработке, как это должно быть сделано? Существуют ли другие рабочие процессы?
Ответы
Ответ 1
Я долгое время использовал Docker с Glassfish и уже давно написал блог на эту тему здесь.
Это отличный инструмент для разработки JavaEE.
Для вашего образа производства я предпочитаю объединять все вместе, создавая статичное базовое изображение и слои в новой WAR. Мне нравится использовать CI-сервер для выполнения работы и иметь конфигурацию CI для производственных ветвей, которая будет захватывать базовый слой в сборке релиза, а затем публиковать артефакт. Обычно мы вручную развертываем в производство, но если вы действительно хотите получить фантазию, вы можете даже автоматизировать это с развертыванием сервера CI в производственной среде и с использованием прокси-серверов для обеспечения новых сеансов, которые приходят, чтобы получить обновленную версию.
В разработке мне нравится использовать тот же подход, когда приходит время локально запускать все, которые полагаются на контейнер (например, тесты интеграции в Arquillian) до проверки кода. Это позволяет окружающей среде как можно ближе к производству, что, на мой взгляд, важно, когда дело доходит до тестирования. Это одна из главных причин, по которой я против таких подходов, как тестирование со встроенными контейнерами, но развертывание на не встроенные. Я видел множество случаев, когда тест проходит во встроенной среде и не работает в производственном/не встроенном.
Во время цикла разработки/развертывания/ручной проверки, прежде чем совершать код, я думаю, что подход развертывания в контейнер (который является частью базового изображения) более экономичен с точки зрения скорости этого dev. цикл против здания в вашей WAR каждый раз. Это также лучший подход, если ваша среда для разработчиков использует инструмент JRebel или XRebel, где вы можете быстро развернуть свой код и просто обновить свой браузер, чтобы увидеть изменения.
Ответ 2
С последней версией Docker вы можете легко достичь этого с помощью Docker Links, Docker Volume и Docker Compose. Подробнее об этих инструментах можно найти на сайте Docker.
Вернитесь к своему рабочему процессу, как вы уже упоминали: для любого типичного приложения Java EE требуются сервер приложений и сервер базы данных. Поскольку вы не упоминаете в своем сообщении, как настроена база данных, я бы предположил, что ваша среда разработки будет иметь отдельный сервер базы данных для каждого разработчика.
Принимая все это в предположении, я мог бы предложить следующий рабочий процесс:
- Создайте базовый сервер приложений Wildfly с официального изображения. Вы можете добиться этого, выполнив команду "docker pull".
- Запустите базовый сервер приложений с помощью:
docker run -d -it -p 8080: 8080 -p 9990: 9990 - имя baseWildfly JBoss/wildfly
Сервер приложений теперь запущен, вам нужно настроить его для подключения к серверу базы данных, а также настроить параметры источника данных и другую конфигурацию, если необходимо, чтобы запустить приложение Java EE.
Для этого вам нужно войти в терминал bash контейнера Jboss:
docker exec -i -t baseWildfly/bin/ bash/
Теперь вы находитесь в терминале контейнера. Вы можете настроить сервер приложений так же, как и для любой среды Linux.
Вы можете проверить конфигурацию, вручную развернув WAR файл в Wildfly. Это можно легко сделать с помощью консоли администратора или плагина maven или команды ADD, как вы сказали. Обычно я делаю это с помощью консоли администратора, просто для тестирования быстро. Когда вы убедитесь, что конфигурация работает, вы можете удалить WAR файл и создать снимок вашего контейнера:
docker commit -change "добавить базовые настройки и конфигурации" baseWildfly yourRepository: тег
Теперь вы можете нажать созданное изображение в свой приватный репозиторий и поделиться им с вашей командой разработчиков. Теперь они могут вытащить изображение и запустить сервер приложений для развертывания сразу.
Мы не хотим разворачивать WAR файл для каждой сборки Maven с помощью консоли администратора, поскольку это слишком громоздко, поэтому следующей задачей является автоматизация его с помощью Docker Volume.
Предполагая, что вы сконфигурировали Maven для создания файла WAR на "../your_project/deployments/", вы можете связать это с каталогом развертывания контейнера Jboss следующим образом:
docker run -d -p 8080: 8080 -v../your_project/развертывания:/OPT/JBoss/wildfly/автономный/развертывания
Теперь, каждый раз, когда вы восстанавливаете приложение с помощью Maven, сервер приложений сканирует изменения и повторно развертывает ваш файл WAR.
Также весьма проблематично иметь отдельный сервер базы данных для каждого разработчика, поскольку они должны сами настраивать его в контейнере, потому что у них могут быть разные настройки (например, адрес db, имя пользователя, пароль и т.д.). Таким образом, это хорошо, чтобы вступить в докеризацию.
Предполагая, что вы используете Postgres как ваш сервер db, вы можете вытащить его из официального репозитория postgres. Когда у вас готово изображение, вы можете запустить сервер db:
docker run -d -p 5432: 5432 -t --name postgresDB postgres
или запустите сервер базы данных со связанным каталогом "данные":
docker run -d -p 5432: 5432 -v.. /your _postgres/data:/var/lib/postgresql -t --name postgresDB Postgres
Первая команда сохранит ваши данные в контейнере, а последняя сохранит ваши данные в хосте env.
Теперь вы можете связать свой контейнер базы данных с Wildfly:
docker run -d -p 8080: 8080 --link postgresDB: база данных -t baseWildfly
Ниже приведен вывод ссылки:
![введите описание изображения здесь]()
Теперь у вас может быть одна и та же среда для всех членов команды разработчиков, и они могут начать кодирование с минимальной настройкой.
Те же базовые изображения могут использоваться для производственной среды, поэтому, когда вы хотите опубликовать новую версию, вам просто нужно скопировать файл WAR в папку "your_deployment" хоста.
Хорошая вещь для докетирования сервера приложений и сервера db заключается в том, что вы можете легко сгруппировать его в будущем, чтобы масштабировать его или применить высокую доступность.
Ответ 3
Возможно, вам стоит взглянуть на rhuss/docker-maven-plugin. Это позволяет использовать бесшовную интеграцию для использования докеров в качестве блока развертывания:
- Используйте стандартный дескриптор сборки Maven для создания изображений с помощью
docker:build
, так что вы создали файл WAR, или ваш Microservice можно легко добавить к изображению Docker.
- Вы можете нажать созданное изображение с помощью
docker:push
- С
docker:start
и docker:stop
вы можете использовать свое изображение во время модульных тестов.
Этот плагин содержит исчерпывающую документацию, если есть какие-либо открытые вопросы, пожалуйста, откройте проблему.
И как вы могли заметить, я автор этого плагина;-). И, честно говоря, есть другие докеры-maven-плагины, которые все имеют немного другой фокус. Для простой проверки вы можете взглянуть на shootout-docker-maven, который предоставляет примеры конфигураций для четырех наиболее активных плагинов maven-docker.
Затем рабочий процесс просто переносит границу артефакта из WAR/EAR файлов на изображения Docker. mvn docker:push
перемещает их в реестр Docker, откуда он вытаскивается на разных этапах тестирования, используемых в конвейере непрерывной доставки.
Ответ 4
То, как вы обычно развертываете что-либо с Docker, - это создание нового изображения поверх базового изображения платформы. Таким образом, вы следуете философии привязки зависимостей Docker.
В терминах Maven вы можете создать сборку tarball (предположим, что она называется jars.tar
), а затем вызвать ADD jars.tar /app/lib
в файле Docker. Вы также можете реализовать плагин Maven, который также создает файл Docker.
Сегодня это самый разумный подход к Docker, другие подходы, такие как создание образа FROM scratch
, неприменимы для приложений Java.
См. также Java JVM на Docker/CoreOS.
Ответ 5
Сообщение в блоге о создании JRebel с Docker от Arun Gupta, вероятно, будет полезно здесь: http://blog.arungupta.me/configure-jrebel-docker-containers/
Ответ 6
Я попробовал симуляторный сценарий использования докера для запуска моего приложения. В моей ситуации я хотел начать докер с помощью tomcat, который вел войну. Затем на этапе интеграции-теста maven запускает тест интеграции огурца/фантома на докере.
Пример реализации описан в https://github.com/abroer/cucumber-integration-test. Вы можете расширить этот пример, чтобы нажать изображение докера на свое личное репо, когда тест будет успешным. Толкаемое изображение может использоваться в любой среде от разработки до производства.
Ответ 7
Для моего текущего процесса развертывания я использую Glassfish и этот трюк, который работает очень хорошо.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>${plugin.exec.version}</version>
<executions>
<execution>
<id>docker</id>
<phase>package</phase>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>docker</executable>
<arguments>
<argument>cp</argument>
<argument>${project.build.directory}/${project.build.finalName}</argument>
<argument>glassfish:/glassfish4/glassfish/domains/domain1/autodeploy</argument>
</arguments>
</configuration>
</plugin>
После запуска: mvn clean package, контейнеры запускают и начинают развертывание последней войны.