在构建docker-compose v2期间访问docker网络?

时间:2019-09-22 07:57:47

标签: c# docker asp.net-core docker-compose nuget

摘要

具有一个docker-compose.yml文件,该文件生成的图像如下:

services:
  my-service:
    build: 
      context: My.VS.AppFolder
    networks:
      - my-docker

networks:
  my-docker:
    external: true

已定义的网络仅在ENTRYPOINT中可用。但不是在构建期间。 my-docker构建期间如何访问同一网络Dockerfile上的另一个容器?<​​/ p>

用例:从私有存储库中获取NuGet软件包

用例说明

我有一个ASP.NET Core MVC 2.1 Web应用程序。为了更好地分离关注点,我想在另一个分离的Web应用程序中实现某些功能(例如管理界面)。为了避免复制共享的内容,例如应用程序布局(Razor)或一些帮助程序实用程序类,我为这些内容创建了一个共享项目。

所以现在有三个项目:

  • MyApp (原始应用程序)
  • MyApp.Core (用于共享的东西)
  • MyApp.Admin

由于需要从其他项目中引用 MyApp.Core ,因此我为docker构建环境安装了BaGet as simple NuGet hosting repo。在nuget.config中以其DNS名称在内部引用此容器,该容器是在解决方案级别MyApp上创建的(与新MyApp.Admin相同,为简单起见,我们将重点放在MyApp上)。

问题

Dockerfile的{​​{1}}中,我正在这样做:

MyApp

,并且需要访问RUN dotnet restore --configfile nuget.config 网络上名为baget的dns名称。 Researchs show that this is only possible with at least version 3.4 of docker-compose,并且似乎尚未正式记录。但是Docker removed several options from v2 in v3,例如我正在使用的资源限制,例如my-docker。从v3开始,仅可使用swarm来提供它们,而不再可以在单个节点上使用。

因此,除了迁移到v3和群集外,我目前没有其他解决方案,这将导致额外的工作和复杂性,而除了此网络问题之外,没有其他好处。我的项目并不庞大,不需要大量的资源。

1 个答案:

答案 0 :(得分:0)

我发现了解决此问题的两种方法:

使用mem_limits cli工具而不是docker

构建

我使用dockers CLI工具而不是docker-compose来手动构建映像,因为它具有一个docker-compose up -d --build开关,可以在构建期间指定网络:

--network

现在在docker build --network my-docker -t my-service:latest --build-arg ASPNETCORE_ENVIRONMENT=Development My.VS.AppFolder 中引用此图像,而不是在此处构建它:

docker-compose.yml

在生成映像之后,运行没有services: my-service: image: my-service:latest 标志的docker-compose up -d。由于您必须进行CLI调用,并且需要进行--build之类的实际标记,因此会产生一些开销,需要使用env变量指定该标记并将其传递给docker / docker-compose。但这似乎是生产性使用的最佳方法。

兼容模式

有一个--compatibility switch in docker-compose since 1.20.0允许使用新的v3文件版本,但是将诸如资源限制之类的大量选项映射到本地v2表单。换句话说:您可以在v3中使用指定的alpine-3.2.1,并且在使用此开关时它们将应用于ressources。否则,它们将在docker-compose上被忽略,仅对docker-compose有效。

因此,通过此开关,您可以从构建过程中定义网络的能力中受益,而不会失去资源限制。 但是文档警告说,这对于生产使用来说还不够稳定:

  

我们建议不要在生产中使用--compatibility模式。由于使用非Swarm模式属性生成的配置仅是近似值,因此可能会产生意外的结果。

由于这个原因,我不认为这是一个真正的解决方案,而是使用第一种使用docker CLI构建映像的方法(可能指定网络)。