在构建docker-compose v2期间访问docker网络? [英] Access a docker network during build of docker-compose v2?
问题描述
摘要
具有 docker-compose.yml
文件,该文件可构建如下图像:
服务:
我的服务:
构建:
上下文:My.VS.AppFolder
网络:
-我的码头工人
网络:
我的码头工人:
外部:真实
定义的网络仅在 ENTRYPOINT
中可用。但不是在构建期间。在构建 Dockerfile
的过程中,如何访问同一网络 my-docker
上的另一个容器?</ p>
用例:从私人仓库中获取NuGet软件包
用例说明
我有一个ASP.NET Core MVC 2.1 Web应用程序。为了更好地分离关注点,我想在另一个分离的Web应用程序中实现某些功能(例如管理界面)。为了避免复制共享的内容,例如应用程序布局(Razor)或某些帮助程序实用程序类,我为这些内容创建了一个共享项目。
所以现在有三个项目:
- MyApp (原始应用程序)
- MyApp.Core (用于共享内容)
- MyApp.Admin
由于需要从其他项目中引用 MyApp.Core ,因此我安装了 BaGet作为适用于我的Docker构建环境的简单NuGet托管存储库。在 nuget.config
中以其DNS名称在内部引用此容器,该容器是在 MyApp
的解决方案级别创建的(与新容器相同) MyApp.Admin
,但为简单起见,我们重点关注 MyApp
)。
问题
在 Dockerfile
的 MyApp
我现在正在这样做:
RUN dotnet restore --configfile nuget.config
,并且需要访问名为 baget $的dns名称。
my-docker
网络上的c $ c>。 研究表明,只有在 docker-compose
,并且似乎仍未正式记录。但是 Docker在v3中从v2删除了几个选项,例如我正在使用的资源限制,例如 mem_limits
。从v3版本开始,只能使用群体功能,而不能再在单个节点上使用。
因此,我目前看不到任何解决方案,而只能迁移到v3和群集,这将导致额外的工作和复杂性,除了这个网络问题之外,没有其他好处。我的项目并不庞大,不需要很多。
我发现了解决此问题的两种方法:
使用 docker
cli工具而不是 docker-compose
构建我不是使用 docker-compose up -d --build
而是使用dockers CLI工具手动构建映像,因为它具有-network
允许在构建过程中指定网络的开关:
docker build --network my-docker -t my- service:latest --build-arg ASPNETCORE_ENVIRONMENT =开发My.VS.AppFolder
现在在此引用该图像 docker-compose.yml
而不是在此处构建:
服务:
我的服务:
图片:我的服务:最新
映像已生成,运行 docker-compose up -d
而不带-build
标志。因为您必须进行CLI调用,并且对于诸如 alpine-3.2.1
之类的实际标记,这会导致一些开销,因此需要使用env变量指定该标记并将其传递给两者docker / docker-compose。但这似乎是生产性使用的最佳方法。
兼容模式
有一个 --compatibility
在 docker-compose
自1.20.0起,允许使用新的v3文件版本,但将大量选项(如资源限制)映射到本地v2表单。换句话说:您可以在v3中使用指定的 ressources
,并且在使用此开关时,它们将应用于 docker-compose
。否则,它们将在 docker-compose
上被忽略,仅对 docker stack deploy
起作用。
因此,通过此切换,您可以从构建过程中定义网络的能力中受益,而不会失去资源限制。 但是文档警告说,这对于生产使用来说还不够稳定:
我们建议不要使用--compatibility生产模式。由于使用非Swarm模式属性生成的配置只是一个近似值,因此可能会产生意外的结果。
因此,我不不要将其视为真正的解决方案,而应在可能指定网络的情况下,使用通过docker CLI构建镜像的第一种方法。
Summary
Having a docker-compose.yml
file that builds an image like this:
services:
my-service:
build:
context: My.VS.AppFolder
networks:
- my-docker
networks:
my-docker:
external: true
the defined network is only avaliable in the ENTRYPOINT
. But not during build. How can I access another container on the same network my-docker
during build of the Dockerfile
?
Use case: Fetching NuGet packages from private repo
Description of the use case
I have an ASP.NET Core MVC 2.1 web application. For a better seperation of concerns, I want to implement certain features in another seperated web app (e.g admin interface). To avoid copying shared things like app layout (Razor) or some helper utility classes, I created a shared project for those things.
So there are three projects now:
- MyApp (The original application)
- MyApp.Core (For shared things)
- MyApp.Admin
Since MyApp.Core needs to be referenced from the other projects, I installed BaGet as simple NuGet hosting repo for my docker build environment. This container is internally referenced with it's DNS name in nuget.config
, created at solution level of MyApp
(same on new MyApp.Admin
but let's focus on MyApp
for simplicity).
The problems
In the Dockerfile
of MyApp
I'm doing now this:
RUN dotnet restore --configfile nuget.config
and need to access the dns name called baget
on the my-docker
network. Researchs show that this is only possible with at least version 3.4 of docker-compose
, and seems still not officially documentated. But Docker removed several options from v2 in v3, for example ressource limits like mem_limits
I'm using. From v3, they're only avaliable using swarm, not on single nodes any more.
So I currently don't see any solution than migrating to v3 and swarm, which would cause extra work and complexity without benefits other than this networking issue. My project isn't that big that swarm is required.
I found two ways of working around this problem:
Build with docker
cli tool instead of docker-compose
Instead of docker-compose up -d --build
, I manually build the image using dockers CLI tool because it has a --network
switch that allows specifying the network during build:
docker build --network my-docker -t my-service:latest --build-arg ASPNETCORE_ENVIRONMENT=Development My.VS.AppFolder
Now reference this image in docker-compose.yml
instead of building it there:
services:
my-service:
image: my-service:latest
After the image was build, run docker-compose up -d
without the --build
flag. This causes a bit of overhead since you have to CLI calls and for real tagging like alpine-3.2.1
, this tag need to be specified with an env variable and passed to both docker/docker-compose. But it seems the best working alternative for productive usage.
Compatibility mode
There is a --compatibility
switch in docker-compose
since 1.20.0 that allows using the new v3 file version, but map swarm options like ressource limits to the locally v2 form. In other words: You can use specifiy ressources
in v3 and they apply on docker-compose
when this switch is used. Otherwise, they would be ignored on docker-compose
and only have effect with docker stack deploy
.
So with this switch, you can profit from the ability of defining a network during build, without loosing ressource limits. But the documentation warns that this is not stable enough for productive usage:
We recommend against using --compatibility mode in production. Because the resulting configuration is only an approximate using non-Swarm mode properties, it may produce unexpected results.
For this reason, I don't consider it as a real solution and use the first approach of building the image using dockers CLI where specifiying a network is possible.
这篇关于在构建docker-compose v2期间访问docker网络?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!