Прочитав статью об упаковке JVM приложения в Docker, я остался в смятении. Я, как и любой разработчик, хочу чтоб мои волосы развевались на ветру контейнер собирался за одну команду, сразу, без лишних телодвижений. Чтобы конфигурация проекта и сборки была собрана в одном файле, и чтобы не было зависимостей от внешних систем.

Далее последует альтернативный способ сборки Java-приложений в Docker контейнер используя Maven.
Для сборки нам понадобится Java проект, Maven и немного терпения, чтоб все это завести.
В это раз, мы будем использовать Maven-плагин от fabric8io.
Предположим, что у нас микро-сервис, который упаковывается в jar-файл, содержащий main метод, который и надо запустить для старта приложения. Добавляем плагин в build секцию:
И, в общем то, все. Разберем поподробнее, что у нас там написано.
В начале идёт типичное определение плагина с версией. Далее идёт определение в какие фазылуны сборки мы хотим собирать и пушить наш контейнер. В моем случае сборка контейнера (build) будет происходить во время упаковки проекта (phase: package).
Пуш (push) контейнера в репозиторий будет происходить во время фазы деплой (deploy).
Определяем имя образа и репозиторий:
Если репозиторий не указан, то будет использоваться репозиторий Docker-а. Документация для дальнейшего чтения.
Описание сборки образа осуществляется в секции <build>. По сути это отражение Docker файла в Maven.
В моем примере:
Это типичная строка запуска Java приложения, завернутая в shell форму Docker-а, в представлении Maven-а.
assembly — самая интересная часть плагина. Она определяет, что будет упаковано в образ контейнера и как. Есть несколько вариантов как можно описать упаковку, я выбрал inline, но есть и другие варианты.
В примере, я хочу взять все зависимости проекта и сложить в папку «jars»:
А так же, артефакт проекта, собственно наше приложение, туда же, а конфигурационный файл в корень контейнера.
Подробнее о возможн��стях ассемблирования в документации, на этот раз Maven-а.
И все! В результате:
Несколько слов о плагине: разработка идет активно, мейнтейнер оперативно отвечает и охотно мерджит пул-реквесты.
» Сам плагин может ещё много чего: возможности
» Пример проекта выложен на github-е

Далее последует альтернативный способ сборки Java-приложений в Docker контейнер используя Maven.
Для сборки нам понадобится Java проект, Maven и немного терпения, чтоб все это завести.
Дисклеймер
Я предполагаю, что читатель уже знаком Java, Maven и Docker. Представляет, что написано в Docker-файле, зачем все ему это надо и вообще ниндзя
В это раз, мы будем использовать Maven-плагин от fabric8io.
Предположим, что у нас микро-сервис, который упаковывается в jar-файл, содержащий main метод, который и надо запустить для старта приложения. Добавляем плагин в build секцию:
<plugin> <groupId>io.fabric8</groupId> <artifactId>docker-maven-plugin</artifactId> <version>0.16.4</version> <executions> <execution> <id>Build docker container</id> <phase>package</phase> <goals> <goal>build</goal> </goals> </execution> <execution> <id>Push docker container</id> <phase>deploy</phase> <goals> <goal>push</goal> </goals> </execution> </executions> <configuration> <images> <image> <name>${project.artifactId}</name> <registry>registry.io</registry> <build> <from>java:8</from> <tags> <tag>${project.version}</tag> </tags> <ports> <port>8080</port> </ports> <cmd> <shell>java -cp 'jars/*' com.myapp.MainClass '/config.file'</shell> </cmd> <assembly> <basedir>/</basedir> <inline> <dependencySet> <outputDirectory>jars</outputDirectory> </dependencySet> <files> <file> <source>${project.build.directory}/${project.build.finalName}.jar</source> <outputDirectory>jars</outputDirectory> </file> <file> <source>${project.basedir}/src/main/config/config.yml</source> <outputDirectory>/</outputDirectory> </file> </files> </inline> </assembly> </build> </image> </images> </configuration> </plugin>
И, в общем то, все. Разберем поподробнее, что у нас там написано.
В начале идёт типичное определение плагина с версией. Далее идёт определение в какие фазы
Пуш (push) контейнера в репозиторий будет происходить во время фазы деплой (deploy).
<executions> <execution> <id>Build docker container</id> <phase>package</phase> <goals> <goal>build</goal> </goals> </execution> <execution> <id>Push docker container</id> <phase>deploy</phase> <goals> <goal>push</goal> </goals> </execution> </executions>
Внимание Maven!
Maven имеет скотскую привычку запускать различные плагины одной фазы в прядке их упоминания в effective pom. Построить effective pom можно следующей командой:
Если Вам никакими ухищрениями не удается получить правильный порядок, то перенесите построение контейнера в следующую фазу: install, deploy.
Например в моем случае перенесение в фазу deploy выглядит так:
mvn help:effective-pom
Если Вам никакими ухищрениями не удается получить правильный порядок, то перенесите построение контейнера в следующую фазу: install, deploy.
Например в моем случае перенесение в фазу deploy выглядит так:
<executions> <execution> <id>Build & Push docker container</id> <phase>deploy</phase> <goals> <goal>build</goal> <goal>push</goal> </goals> </execution> </executions>
Определяем имя образа и репозиторий:
<name>${project.artifactId}</name> <registry>registry.io</registry>
Если репозиторий не указан, то будет использоваться репозиторий Docker-а. Документация для дальнейшего чтения.
Описание сборки образа осуществляется в секции <build>. По сути это отражение Docker файла в Maven.
from — базовый образ
tags — теги с которыми будет собран образ
ports — открытые порты
cmd — строка запуска, так же можно указать entryPoint, о все доступных опциях можно почитать в документации.
В моем примере:
<shell>java -cp 'jars/*' com.myapp.MainClass '/config.file'</shell>
Это типичная строка запуска Java приложения, завернутая в shell форму Docker-а, в представлении Maven-а.
assembly — самая интересная часть плагина. Она определяет, что будет упаковано в образ контейнера и как. Есть несколько вариантов как можно описать упаковку, я выбрал inline, но есть и другие варианты.
В примере, я хочу взять все зависимости проекта и сложить в папку «jars»:
<dependencySet> <outputDirectory>jars</outputDirectory> </dependencySet>
А так же, артефакт проекта, собственно наше приложение, туда же, а конфигурационный файл в корень контейнера.
<files> <file> <source>${project.build.directory}/${project.build.finalName}.jar</source> <outputDirectory>jars</outputDirectory> </file> <file> <source>${project.basedir}/src/main/config/config.file</source> <outputDirectory>/</outputDirectory> </file> </files>
Подробнее о возможн��стях ассемблирования в документации, на этот раз Maven-а.
И все! В результате:
- Вся конфигурация сборки Docker контейнера у нас сосредоточенна в файле проекта.
- Мы можем использовать все прелести Maven-а, его переменные и плагины.
- Сборка контейнера осуществляется прозрачно, в момент сборки проекта, результат доступен локально.
- Версионирование контейнера идет нога в ногу с нашим проектом.
- Мы можем продолжать использовать все тот же CI/CD инструмент, что и раньше (надо установить Docker на сервере).
Несколько слов о плагине: разработка идет активно, мейнтейнер оперативно отвечает и охотно мерджит пул-реквесты.
» Сам плагин может ещё много чего: возможности
» Пример проекта выложен на github-е
