我如何使用Docker Maven插件创build相关的Docker镜像?
我正在调查Docker部署服务的多个版本(这里是1.0
)的多个实例(这里是PROD-1
和PROD-2
)。 我们需要根据实例名称在运行时configuration每个实例,并且希望将实例名称作为环境variables映射到Docker镜像中,以避免用户错误。 例如:
$ cat Dockerfile FROM ubuntu:14.04 ... $ cat Dockerfile.PROD-1 FROM docker-test:1.0 ENV DOCKER_INSTANCE PROD.1 $ cat Dockerfile.PROD-2 FROM docker-test:1.0 ENV DOCKER_INSTANCE PROD.2 $ docker build --tag=docker-test:1.0 --file=Dockerfile $ docker build --tag=docker-test:1.0-PROD-1 --file=Dockerfile.PROD-1 $ docker build --tag=docker-test:1.0-PROD-2 --file=Dockerfile.PROD-2
我现在试图通过docker-maven-plugin
来构build这些图像:
<plugin> <groupId>net.wouterdanes.docker</groupId> <artifactId>docker-maven-plugin</artifactId> <version>3.1.0</version> <executions> <execution> <id>build</id> <goals> <goal>build-images</goal> </goals> <configuration> <images> <image> <id>base</id> <dockerFile>${project.basedir}/Dockerfile</dockerFile> <nameAndTag>docker-test:${project.version}</nameAndTag> </image> <image> <id>instance1</id> <dockerFile>${project.basedir}/Dockerfile.PROD-1</dockerFile> <nameAndTag>docker-test:${project.version}-PROD-1</nameAndTag> </image> <image> <id>instance2</id> <dockerFile>${project.basedir}/Dockerfile.PROD-2</dockerFile> <nameAndTag>docker-test:${project.version}-PROD-2</nameAndTag> </image> </images> </configuration> </execution> </executions> </plugin>
问题是,我不能根据${project.version}
Mavenvariables在Dockerfile.PROD-*
configuration基本映像名称Dockerfile.PROD-*
docker-test:1.0
,而是要求开发人员手动更新每个实例的Dockerfile ,每次我们做一个释放。
通过编写一个Ruby脚本来为每个实例生成Dockerfile作为heredoc,并将其传递给stdin上的docker build,从而在命令行上得到了这个工作。 就我所见, docker-maven-plugin
不允许我在POM中embeddedDockerfile; 谁能提出一个解决scheme?
在玩了一段时间之后,我通过将依赖Docker镜像的Dockerfiles移动到src/main/resources/docker
docker来实现这个工作:
# src/main/resources/docker/Dockerfile.PROD-1 FROM docker-test:${project.version} ENV DOCKER_INSTANCE PROD.1
然后我使用Maven资源过滤将${project.version}
更改${project.version}
当前版本,并引用${project.build.outputDirectory}/docker
docker中的修改的Dockerfiles:
# pom.xml <build> ... <resources> <resource> <directory>src/main/resources/docker</directory> <targetPath>docker</targetPath> <filtering>true</filtering> </resource> </resources> ... <plugins> <plugin> <groupId>net.wouterdanes.docker</groupId> <artifactId>docker-maven-plugin</artifactId> <version>3.1.0</version> <executions> <execution> <id>build</id> <goals> <goal>build-images</goal> </goals> <configuration> <images> <image> <id>base</id> <dockerFile>${project.basedir}/Dockerfile</dockerFile> <nameAndTag>docker-test:${project.version}</nameAndTag> </image> <image> <id>instance1</id> <dockerFile>${project.build.outputDirectory}/docker/Dockerfile.PROD-1</dockerFile> <nameAndTag>docker-test:${project.version}-PROD-1</nameAndTag> </image> <image> <id>instance2</id> <dockerFile>${project.build.outputDirectory}/docker/Dockerfile.PROD-2</dockerFile> <nameAndTag>docker-test:${project.version}-PROD-2</nameAndTag> </image> </images> </configuration> </execution> </executions> </plugin> </plugins> ... </build>
这仍然不是理想的,因为我们必须确保POM文件匹配依赖的Dockerfiles,但至less我们不必手动更新版本号。 如果有人有一个更清洁的解决scheme(最好要求实例名称PROD-1
和PROD-2
只能指定一次),我很想听到它!
最新版本的插件让你使用构build参数,试试这个:
<plugin> <groupId>net.wouterdanes.docker</groupId> <artifactId>docker-maven-plugin</artifactId> <version>5.0.0</version> <executions> <execution> <id>build</id> <goals> <goal>build-images</goal> </goals> <configuration> <images> <image> <id>base</id> <dockerFile>${project.basedir}/Dockerfile</dockerFile> <nameAndTag>docker-test:${project.version}</nameAndTag> </image> <image> <id>instance1</id> <dockerFile>${project.basedir}/Dockerfile.PROD-1</dockerFile> <nameAndTag>docker-test:${project.version}-PROD-1</nameAndTag> <buildArguments> <version>${project.version}</version> </buildArguments> </image> <image> <id>instance2</id> <dockerFile>${project.basedir}/Dockerfile.PROD-2</dockerFile> <nameAndTag>docker-test:${project.version}-PROD-2</nameAndTag> <buildArguments> <version>${project.version}</version> </buildArguments> </image> </images> </configuration> </execution> </executions> </plugin>
然后你可以在你的docker文件中使用build参数来传递版本号,如下所示:
ARG version FROM docker-test:$version ENV DOCKER_INSTANCE PROD.1 ARG version FROM docker-test:$version ENV DOCKER_INSTANCE PROD.2