Использование 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.

Ответ 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, контейнеры запускают и начинают развертывание последней войны.