compose: 1.7.1 doesn't set network aliases when using `run` command

I noticed what appears to be a regression upon upgrading from 1.7.0 to 1.7.1, where the network “aliases” are not defined when running docker-compose run.

This is the simplest docker-compose.yml configuration I could create to illustrate the difference:

version: '2'

services:
  test:
    image: busybox
    networks:
      default:
        aliases:
          - busy
    command: sh

When running docker-compose run test on 1.7.1 the “Aliases” key is empty:

> docker-compose -v
docker-compose version 1.7.1, build 0a9ab35
> docker-compose run test
> docker inspect --format '{{.NetworkSettings.Networks.composetest_default.Aliases}}' $(docker-compose ps -q)
[]

On 1.7.0 I see the defined alias:

> docker-compose -v
docker-compose version 1.7.0, build 0d7bf73
> docker-compose run test
> docker inspect --format '{{.NetworkSettings.Networks.composetest_default.Aliases}}' $(docker-compose ps -q)
[busy]

I also tried using a defined network, but Aliases weren’t created there either under 1.7.1. Aliases are assigned as expected using docker-compose up -d test.

Is the 1.7.1 behavior expected, or a bug? In my case the new behavior is breaking a selenium test suite that I have created, which has two services which need bidirectional communication. My solution (under 1.7.0) was to link my “app” service to the “selenium” service, and define an alias for the app service (on the default network). Then I docker-compose run the “app” service in order to run a series of tests (I can attach the docker-compose.yml file for the actual service if necessary but it uses some proprietary images). Under 1.7.0 the containers can resolve each other using the defined aliases, but under 1.7.1 only “app” can see “selenium”, but not the other way around.

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 1
  • Comments: 27

Commits related to this issue

Most upvoted comments

OK. Both of these sound like use cases outside of what docker-compose run is designed for, but they could also be potentially addressed by adding a flag to run for including the aliases defined on the service. Perhaps --service-aliases.

It definitely shouldn’t be the default behaviour of run to add the aliases, because then you’d get situations where one-off containers are accessible via the same hostname as long-running containers for the same service, and part of the load-balancing group - which is almost never what you want.

I’ve since figured out a workaround for this, by using a named container (which populates using ‘run’ properly). This assumes a ‘tests’ container (which runs tests), which has a link to selenium:

docker-compose stop tests; docker-compose rm -f tests docker-compose run --rm --name tests tests

The ‘stop/rm’ parts are there to ensure no old containers stick around, as container names must be unique.

I’ve been googling myself gray-haired trying to figure this out. I must say that I find this to be pretty awful. You would expect to be able to run a container so that it is identical to up - but that is obviously not the case.

I run a stack comprised of a lot of microservices all running on docker, and I like to step into the containers when I am developing, to save me the trouble of having to generate appropriate payloads and shooting them at the container manually with curl or something - I had implemented my own DNS for doing this previously, but docker-compose was supposed to do away with my need of it. Or so I thought until I foolishly expected this to just work.

It sort of breaks the networking contract made by the docker-compose.yml file, that is, services should be available by name as long as they share a network.

For reference, I am on ubuntu 14.04, running docker-compose version 1.9.0, build 2585387

@aanand I tried to explain in the original description, but basically: I have an app that uses the selenium/standalone-chrome image to run tests against a custom e2e service (it happens to both run the app with the tests and run the tests themselves, using webdriverio for orchestration).

The hostname of the e2e service needs to be resolvable by the selenium service (so it can navigate to the app), and the hostname of the selenium service needs to be resolvable by the e2e service (so webdriverio knows which selenium server to use).

It used to be that I could start the e2e service using docker-compose run e2e which would spin up the e2e service, the selenium service (which is a linked dependency), and run the test suite, allowing the selenium service to drive the browser against the e2e hostname (using the network alias):

e2e:
  links:
    - selenium
  networks:
    default:
      aliases:
        - e2e

Now I have to do the docker-compose up workaround, which is fine, but not ideal because it makes what used to be one line of shell code using docker-compose run into several lines of code with up/run/down, not to mention that the Docker images are not backwards compatible because the Dockerfile CMD command needs to be modified to make the up command work.

I would also like to express frustration with this feature going away as well. We use docker-compose to be able to stand up, test and teardown test environments in CI. We exclusively use docker-compose run (along with some docker-compose magic such as --name and -p to avoid clashing when running the same test on the CI host) to do this and rely on the alias being set correctly within its network. Now we have to build workarounds for this. Glad I found this issue; otherwise, I would have gone crazy trying to figure out why this isn’t working anymore.

Managed to discover a workaround for this problem!

You can manually set a static IP address to your test container and add an extra_hosts entry pointing to that static IP. Settings like these will work:

version: '2'

services:
  service:
    networks:
      - test
    extra_hosts:
      - "test:172.16.0.42"
	  
  test:
    depends_on:
      - service
    networks:
      test:
        ipv4_address: 172.16.0.42

networks:
  test:
    driver: bridge
    ipam:
      driver: default
      config:
      - subnet: 172.16.0.0/24
        gateway: 172.16.0.1

With a configuration similar to that docker-compose.yml, I am able to run docker-compose run --rm test and my service container can connect to the shortname test.

I am experiencing the same issue on 1.8.1. @aanand I do not agree with your opinion about “run” not being designed for these use cases. In my opinion one off commands should be able to access related services in the same way as “up” otherwise it would make no sense to take depends_on and links into account when executing “run” either.