Mic*_*hal 4 spring buildpack docker docker-compose paketo
我正在使用 Spring Boot 2.3.0.M1引入的 Spring buildpacks来创建基于 Spring 的应用程序的 Docker 映像。一切顺利,我可以通过执行./gradlew bootBuildImage
Gradle 任务为每个应用程序创建 docker 图像,将 docker-compose 文件指向创建的图像(例如image: spring-test:latest
),最后成功运行所有应用程序(docker-compose up
)。
即使我有一个 bash 脚本来自动化构建过程,我还是想摆脱这个额外的步骤,让 Spring buildpacks 任务在我运行docker-compose up --build
命令时自动执行,这样每个应用程序的 docker 镜像都会被构建并上传到主机的本地 docker 存储库,docker compose 将从该存储库中接管。
我的第一次尝试是为bootBuildImage
在主机上执行任务的每个应用程序创建一个虚拟 Dockerfile ,但这需要从 docker 到主机的 SSH 连接,甚至不确定它是否能正常工作。
另一个想法是使用类似的方法,唯一的变化是首先将应用程序的源代码挂载或复制到 docker,配置 buildpacks 将图像存储到主机的本地 docker 镜像 repo(可能是 SSH 连接),最后在 docker 上执行 buildpacks。
我想知道是否有更好,更优雅的解决方案。
这个问题真的让我发疯,因为我已经玩了很长一段时间 Spring Boot 和 Paketo Buildpacks -我真的很喜欢 Docker-Compose 的简单性。所以这些问题已经在我的脑海里了,但后来你问了它:)
我没有找到 100% 完美的解决方案,但我认为有一些想法。让我们假设一个包含多个 Spring Boot 应用程序的示例项目,这些应用程序由 Maven 多模块设置组成(我知道您正在使用 Gradle,但是在 spring.io指南中有关于使用 Gradle进行多模块设置的指南) :
github.com/jonashackt/cxf-spring-cloud-netflix-docker。我创建了一个buildpacks-paketo
包含我们需要的所有内容的新分支- 并Dockerfiles
从相应的 Spring Boot 应用程序中删除了所有内容。由于我们不再需要使用Cloud Native Buildpacks(这是他们的设计目标)。
TLDR:我的想法是使用spring-boot-maven-plugin
(或它的 Gradle 等价物)在每个“docker-compose up
像这样的正常”之前发布一个新的 Paketo 构建:
mvn clean spring-boot:build-image && docker-compose up
Run Code Online (Sandbox Code Playgroud)
示例项目父项pom.xml
如下所示(缩短):
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.jonashackt</groupId>
<artifactId>cxf-spring-cloud-netflix-docker-build-all</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.1</version>
</parent>
<modules>
<module>eureka-serviceregistry</module>
<module>spring-boot-admin</module>
<module>zuul-edgeservice</module>
<module>weatherbackend</module>
<module>weatherservice</module>
<module>weatherclient</module>
</modules>
</project>
Run Code Online (Sandbox Code Playgroud)
该示例项目docker-compose.yml
看起来简单,使用由Paketo(这是由Maven插件触发)开发生产的集装箱图像-这些被命名为这样的:eureka-serviceregistry:0.0.1-SNAPSHOT
。以下是docker-compose.yml
所有 Spring Boot 服务的完整内容:
version: '3.3'
services:
eureka-serviceregistry:
image: eureka-serviceregistry:0.0.1-SNAPSHOT
ports:
- "8761:8761"
tty:
true
restart:
unless-stopped
spring-boot-admin:
image: spring-boot-admin:0.0.1-SNAPSHOT
ports:
- "8092:8092"
environment:
- REGISTRY_HOST=eureka-serviceregistry
tty:
true
restart:
unless-stopped
# no portbinding here - the actual services should be accessible through Zuul proxy
weatherbackend:
image: weatherbackend:0.0.1-SNAPSHOT
ports:
- "8090"
environment:
- REGISTRY_HOST=eureka-serviceregistry
tty:
true
restart:
unless-stopped
# no portbinding here - the actual services should be accessible through Zuul proxy
weatherservice:
image: weatherservice:0.0.1-SNAPSHOT
ports:
- "8095"
environment:
- REGISTRY_HOST=eureka-serviceregistry
tty:
true
restart:
unless-stopped
zuul-edgeservice:
image: zuul-edgeservice:0.0.1-SNAPSHOT
ports:
- "8080:8080"
environment:
- REGISTRY_HOST=eureka-serviceregistry
tty:
true
restart:
unless-stopped
Run Code Online (Sandbox Code Playgroud)
===可能的改进======================
这个想法让我也有“单独docker-compose.yml
使用,仅docker-compose up
按您的要求使用 - 没有额外的命令。因此,我创建了另一个“Docker Compose构建服务”,它应该只构建这样的服务镜像:
version: '3.3'
services:
paketo-build:
image: maven:3.6-openjdk-15
command: "mvn clean spring-boot:build-image -B -DskipTests --no-transfer-progress" # build all apps
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro" # Mount Docker from host into build container for Paketo to work
- "$HOME/.m2:/root/.m2" # Mount your local Maven repository into build container to prevent repeated downloads
- "$PWD:/workspace" # Mount all Spring Boot apps into the build container
working_dir: "/workspace"
Run Code Online (Sandbox Code Playgroud)
我首先在docker-compose.yml
我已经拥有的服务中集成了这项服务。运行 adocker-compose up paketo-build
做了我想要的:在 Compose 设置中构建我们所有的 Spring Boot 应用程序:
...
paketo-build_1 | [INFO] --- spring-boot-maven-plugin:2.4.1:build-image (default-cli) @ eureka-serviceregistry ---
paketo-build_1 | [INFO] Building image 'docker.io/library/eureka-serviceregistry:0.0.1-SNAPSHOT'
paketo-build_1 | [INFO]
paketo-build_1 | [INFO] > Pulling builder image 'docker.io/paketobuildpacks/builder:base' 100%
paketo-build_1 | [INFO] > Pulled builder image 'paketobuildpacks/builder@sha256:3cff90d13d353ffdb83acb42540dae4ce6c97d55c07fb01c39fe0922177915fa'
paketo-build_1 | [INFO] > Pulling run image 'docker.io/paketobuildpacks/run:base-cnb' 100%
paketo-build_1 | [INFO] > Pulled run image 'paketobuildpacks/run@sha256:f393fa2927a2619a10fc09bb109f822d20df909c10fed4ce3c36fad313ea18e3'
paketo-build_1 | [INFO] > Executing lifecycle version v0.10.1
paketo-build_1 | [INFO] > Using build cache volume 'pack-cache-9d8694845b92.build'
paketo-build_1 | [INFO]
paketo-build_1 | [INFO] > Running creator
paketo-build_1 | [INFO] [creator] ===> DETECTING
...
paketo-build_1 | [INFO] [creator]
paketo-build_1 | [INFO] [creator] Paketo Spring Boot Buildpack 3.5.0
paketo-build_1 | [INFO] [creator] https://github.com/paketo-buildpacks/spring-boot
paketo-build_1 | [INFO] [creator] Creating slices from layers index
...
paketo-build_1 | [INFO] [creator] Adding label 'io.buildpacks.project.metadata'
paketo-build_1 | [INFO] [creator] Adding label 'org.opencontainers.image.title'
paketo-build_1 | [INFO] [creator] Adding label 'org.opencontainers.image.version'
paketo-build_1 | [INFO] [creator] Adding label 'org.springframework.boot.spring-configuration-metadata.json'
paketo-build_1 | [INFO] [creator] Adding label 'org.springframework.boot.version'
paketo-build_1 | [INFO] [creator] Setting default process type 'web'
paketo-build_1 | [INFO] [creator] *** Images (7efae8be1167):
paketo-build_1 | [INFO] [creator] docker.io/library/eureka-serviceregistry:0.0.1-SNAPSHOT
paketo-build_1 | [INFO]
paketo-build_1 | [INFO] Successfully built image 'docker.io/library/eureka-serviceregistry:0.0.1-SNAPSHOT'
...
Run Code Online (Sandbox Code Playgroud)
但由于种种原因,这感觉不对。一是您需要以某种方式等待所有其他 Compose 服务的启动,直到该paketo-build
服务完成其工作并构建所有图像。但是正如 Docker 文档告诉我们的那样,我们需要反对在 Compose 中做出的设计决策才能实现这一目标!还没有,我觉得这个伟大的答案,其中Max解释说,这不是一个好的设计“污染”的“生产”docker-compose.yml
与仅仅是那里为构建容器。
之后,我将paketo-build
服务提取到它自己的 Compose 文件中 -build.yml
在示例项目中调用。有了这个,我们现在可以运行 Paketo 构建,而无需依赖主机安装 Maven - 并且仅使用 Docker-Compose:
docker-compose -f build.yml up && docker-compose up
Run Code Online (Sandbox Code Playgroud)
请记住不要与第一个容器分离,-d
因为在我们开始我们的docker-compose.yml
. 使用这种方法,我们也绝对不需要Dockerfile
. 但与此同时,我想到了完全消除对单独构建容器的需求,并在与 TLDR 中已经描述up
的&&
类似内容连接之前简单地使用 Maven(或 Gradle):
mvn clean spring-boot:build-image && docker-compose up
Run Code Online (Sandbox Code Playgroud)
希望这对你有帮助。很高兴听到您的反馈!这里还有一个完整的 GitHub 操作构建,展示了 Cloud CI 服务器上的所有“魔法”。
现在没有办法docker-compose up --build
使用 Paketo Buildpacks 来触发所有 Spring Boot 应用程序的新映像构建。
归档时间: |
|
查看次数: |
794 次 |
最近记录: |