如何通过 docker-compose 可靠地使用本地 Maven 镜像代理?

How to reliably use a local Maven mirroring proxy with docker-compose?

我正在努力将我们现有的 Java 项目的 Maven 构建过程迁移到 Docker。我是一名使用 Maven 的经验丰富的 Java 开发人员,但仍在学习 Docker.

我们的主要问题是默认情况下不会缓存工件,所以我们每五分钟下载一半的互联网,再加上我们在本地老旧的 Nexus 服务器上也有东西。由于这是用于自动化集成测试,我们不想在 docker.

之外构建工件

经过仔细考虑,我发现一个好的解决方案可能是为每个开发人员提供一个 Maven 镜像代理 运行,可以保留本地配置,然后 Docker 实例就可以引用它.手动 运行 一个 Nexus3 容器

docker run -p 8081:8081 --name nexus sonatype/nexus3

(加上一些手动配置来代理我们的内部存储库)到目前为止工作得很好,但不受 docker-compose 控制。

不幸的是,除了对机器的外部 IP 号码进行硬编码外,我看不到访客访问主机(端口 8081 可用)的方法,而且我看不到使 docker -compose 负责确保当我的 docker 构建需要它时,nexus 容器是 运行。

我目前将其用作 docker 中的 settings.xml 文件:

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                      https://maven.apache.org/xsd/settings-1.0.0.xsd">
    <mirrors>
        <mirror>
            <id>local-nexus</id>
            <name>Local Nexus</name>
            <!-- Host external IP number -->
            <url>http://1.2.3.4:8081/repository/sbforge_central/</url>
            <mirrorOf>central</mirrorOf>
        </mirror>
    </mirrors>
    <localRepository>/usr/share/maven/ref/repository</localRepository>
</settings>

我应该如何处理这个问题?我看到两种情况。

  1. 如何获得可靠的主机名称? Linux必填,其他平台就好

  2. 如何让 docker-compose 控制此容器,使其在 运行 docker-compose build 时启动,因此 docker 可以确保主机名Nexus 容器的解析?将成品容器上来时不需要。

或者有更聪明的方法吗?

不是答案,但评论不允许这样大小的评论:

也许我在这里误解了一件事:但是“我是一位经验丰富的 Maven 开发人员”是什么意思?您开发 Maven 插件等吗?或者您是 Java 使用 Maven 的开发人员? 此外,如果您通过 Maven 构建,为什么不缓存工件?是否删除每个构建的本地缓存?您以前使用过存储库管理器吗?为什么不喜欢在外部构建工件 Docker?你使用像 Jenkins 这样的 CI 服务器吗?为什么在 Docker 中使用存储库管理器但没有为存储库数据安装卷?与 Docker-Compose 的关系在哪里?除此之外docker-compose 不负责保持服务可用...

settings.xml 中的配置看起来像是在以某种方式共享本地缓存?我希望你不要这样做......这是行不通的......

更新:

正如我之前问的,为什么需要在 Docker 容器中构建?它比外面慢得多,最好是为此目的使用 CI 服务器....docker-compose 不能真正协调事情,因为它不确定服务是否启动并且 运行(那必须由你自己的服务来处理)

此外,您无法抽象化本地缓存,因为您需要它来构建您的 jar/war/ear...(顺便说一句:我现在与 Docker 一起工作了大约 2 年;使用 Maven 大约 10 年;我是 Apache Maven PMC 成员)...

重点是您必须将 Docker 容器的本地缓存映射到容器删除后未删除的卷上。所以每次启动 "Build Container" 时,您都有将卷提供给容器...否则在您停止容器后它会被删除(容器内的本地缓存)这对于您的 Nexus3 容器也是如此...您还必须将卷映射到 Nexus3 容器中否则代理想法被粉碎了....

关于 docker-compose 的一些想法。如果你定义像 depends_on nexus 这样的东西,这将在 Maven 执行之前启动 Nexus3 容器,但不会真正等到 Nexus3 真正可用..(这需要大约 2-3 分钟)......所以最后这种方法行不通(因为通常构建速度超过 2-3 分钟)...因此您必须在单独的区域(例如在 Mesos 类型的环境中)启动 Nexus3 容器 运行 总是导致支持 Maven 构建对您的基础架构至关重要...我还建议开始使用 CI 解决方案,如 jenkins 来处理所有构建...

希望我没听错,但我看到以下选项可以解决您的问题:

1. [更新] 在 settings.xml
中使用 env 参数 您能否在 docker-compose.yml 中使用环境变量并将其设置在 settings.xml 中:${env.EXTERNAL_NEXUS_HOST}?

2。 Nexus 依赖项

docker-compose build 不会让您为其他服务设置条件,但您可以使用 docker-compose run --rmdepends_on

version: '2'
services:
  # Whatever this might look like, it's just an example
  mvn:
    image: mvn
    depends_on:
      - nexus
    command: mvn deploy
  nexus:
    image: sonatype/nexus3

这能解决任何问题吗?还是我理解错了?

根据 https://whosebug.com/users/4527948/asger-askov-blekinge 离线建议,docker-compose 控制网络中主机的默认网络地址为 172.17.0.1。为 maven:3-jdk-9-slim 图像建议的 pom.xml 的修改版本(将本地存储库移动到图像中)然后看起来像:

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                      https://maven.apache.org/xsd/settings-1.0.0.xsd">
    <mirrors>
        <mirror>
            <id>local-nexus</id>
            <name>Local Nexus</name>
            <url>http://172.17.0.1:8081/repository/maven_central/</url>
            <mirrorOf>central</mirrorOf>
        </mirror>
    </mirrors>
    <localRepository>/usr/share/maven/ref/repository</localRepository>
</settings>

这对我们进行非部署构建时最有用,因为我们可以在 Nexus 中轻松地将我们的内部存储库与 Maven Central 合并,将复杂性转移到构建之外。