Создавайте разные Docker изображений на основе результатов Maven (с Jenkins) - PullRequest
0 голосов
/ 17 июня 2020

У меня есть приложение Java с некоторыми зависимостями, которые я хотел бы разбить на несколько Docker изображений:

  • Ядро с прокси (nginx), JVM и драйверы базы данных -> практически не меняется
  • Зависимости: все файлы Jar, от которых зависит мое приложение -> иногда меняется
  • приложение: один дополнительный Jar -> меняется ежедневно или чаще (во время разработки)

Что-то вроде этого:

Docker layers

Я знаю, как создать эти Docker изображения вручную. Я также могу создать изображение docker в maven:

<plugin>
                <groupId>com.spotify</groupId>
                <artifactId>dockerfile-maven-plugin</artifactId>
                <version>${dockerfile-maven-version}</version>
                <executions>
                    <execution>
                        <phase>pre-integration-test</phase>
                        <id>default</id>
                        <goals>
                            <goal>build</goal>
                            <goal>push</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <dockerfile>src/main/docker/dockerfile</dockerfile>
                    <repository>myprivateregistry.io:5000/repourl</repository>
                    <tag>${project.version}</tag>
                    <buildArgs>
                        <JAR_FILE>myapp.jar</JAR_FILE>
                    </buildArgs>
                </configuration>
            </plugin>

Полагаю, я могу добавить плагин дважды, чтобы создать средний и верхний слой?

Однако я бы хотел чтобы начать только среднюю сборку, и только если содержимое target/libs, которое содержит все Jar-файлы зависимостей, изменилось (новые Jar-файлы, новая версия Jar-файлов, удаление Jar-файлов)

Как мне это сделать?

В настоящее время мы используем Jenkins для запуска наших сборок (я бы предпочел решение «внутри maven»).

Ответы [ 2 ]

1 голос
/ 17 июня 2020

К сожалению, это невозможно с maven. Maven не отслеживает, какие модули были созданы в прошлом, и поэтому он не может знать, какие библиотеки могли быть изменены. Существуют плагины, такие как maven-compiler-plugin, которые принимают временную метку исходных файлов и сравнивают с файлами классов, чтобы пропустить компиляцию, но я сомневаюсь, что есть плагин, который может делать то, что вам нужно.

Однако просто всегда создается оба изображения, как вы предложили. Просто сначала создайте образ зависимости, а затем образ вашего приложения. Docker довольно хорошо умеет кэшировать слои. Это означает, что если ваши библиотеки не изменились, он просто извлекает изображение из кеша. В противном случае будет создан новый образ. ВАЖНО: это будет работать, только если демон docker на вашем Jenkins всегда один и тот же. Если у вас кластерный Jenkins, будет много промахов кеша. Но в целом он по-прежнему будет работать, но при этом потеряно какое-либо ускорение.

0 голосов
/ 17 июля 2020

Оказывается, Google подумал об этой проблеме и создал для этого плагин Maven. Google делает именно это.

Плюс: требуется автоматическая c забота обо всех уровнях:

  • Ресурсы
  • Зависимости
  • Код

Обратная сторона: он не использует файлы docker, но полностью определяет изображение в Maven POM

A образец будет выглядеть так:

                    <plugin>
                        <groupId>com.google.cloud.tools</groupId>
                        <artifactId>jib-maven-plugin</artifactId>
                        <version>${jib.maven.plugin.version}</version>
                        <configuration>
                            <from>
                                <image>some.base.image:latest</image>
                            </from>
                            <to>
                                <image>destination.image</image>
                                <tags>${project.version}</tags>
                            </to>
                            <extraDirectories>
                                <paths>
                                    <path>
                                        <from>src/main/docker/scripts</from>
                                        <into>/opt/myapp/scripts</into>
                                    </path>
                                </paths>
                                <permissions>
                                    <permission>
                                        <file>/opt/shutdown_script</file>
                                        <mode>555</mode>
                                    </permission>
                                    <permission>
                                        <file>/opt/startup_script</file>
                                        <mode>555</mode>
                                    </permission>
                                </permissions>
                            </extraDirectories>
                            <container>
                                <creationTime>USE_CURRENT_TIMESTAMP</creationTime>
                                <appRoot>/opt/myapp</appRoot>
                                <entrypoint>
                                    <entry>/opt/myapp/entry_point.sh</entry>
                                </entrypoint>
                                <ports>
                                    <port>80</port>
                                    <port>389</port>
                                    <port>8880</port>
                                    <port>8889</port>
                                    <port>8890</port>
                                </ports>
                                <user>appuser</user>
                                <volumes>
                                    <volume>/local/data</volume>
                                </volumes>
                            </container>
                        </configuration>
                        <executions>
                            <execution>
                                <phase>package</phase>
                                <goals>
                                    <goal>dockerBuild</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>

Кажется, соответствует моим потребностям

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...