我正在研究Docker部署服务的多个版本(此处为PROD-1)的多个实例(此处为PROD-21.0)。我们需要在运行时根据其实例名称配置每个实例,并希望将该实例名称作为环境变量烘焙到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构建这些图像:
<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>

问题是,我无法根据docker-test:1.0 Maven变量在Dockerfile.PROD-*中配置基本镜像名称${project.version},而是每次开发人员发布时,都要求开发人员手动更新每个实例的Dockerfile。

我通过编写一个Ruby脚本在命令行上工作来生成每个实例的Dockerfile作为Heredoc,并将其传递给stdin上的docker build。据我所知,docker-maven-plugin不允许我将Dockerfile嵌入到POM中。有人可以提出解决方案吗?

最佳答案

经过一番摸索后,我通过将依赖的Docker镜像的Dockerfiles移动到src/main/resources/docker来进行工作:

# src/main/resources/docker/Dockerfile.PROD-1
FROM docker-test:${project.version}
ENV DOCKER_INSTANCE PROD.1

然后,我使用Maven资源过滤将${project.version}更改为当前版本,并在${project.build.outputDirectory}/docker中引用了修改后的Dockerfile:
# 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相匹配,但是至少我们不必手动更新版本号。如果有人有一个更干净的解决方案(最好只将实例名称PROD-1PROD-2指定一次),我希望听到它!

10-06 11:28