1

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.

Lion
  • 16,606
  • 23
  • 86
  • 148

1 Answers1

0

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.

Lion
  • 16,606
  • 23
  • 86
  • 148