'docker-compose - Multiple containers with same service

I would like to create 2 containers with almost same settings except environment variables.

Tried severals things without success especially the .override.yml (passing multiple .yml to docker-compose overriding the previous one).

# docker-compose.yml
version: '3.7'
services:
  web:
    image: nginx
    container_name: test-web
    ports:
      - 80:80

Now the other one

# docker-compose.override.yml
version: '3.7'
services:
  web:
    container_name: dupe-web
    ports:
      - 8080:80

Doing :

$ docker-compose -f docker-compose.yml -f docker-compose.override.yml up -d
Recreating test-web ... done

Kills me the test-web container and starts the new one name dupe-web.

Is there a way to have both launched using same service?

In my case I would like to create two containers:

  • one for developers
  • one for staging (almost same settings except env as said)

Any help would be welcome.



Solution 1:[1]

If you name the service the same, you override it. So your file name docker-compose.override.yml is actually very fitting.

I think that's logical and desired. How else would you be able to override, and what would be the name of the service in the second file? Compose had to choose one for you in some way. After all, it wouldn't make sense, imo.

You can use YAML anchors/overrides for your needs, but they have to be in the same file for that to work.

name: example
services:
  web: &web
    image: nginx
    container_name: test-web
    ports:
      - 80:80
  web2:
    <<: *web
    container_name: dupe-web
    ports:
      - 8080:80

I would also recommend removing the container name.

name: example
services:
  test-web: &web
    image: nginx
    ports:
      - 80:80
  dupe-web:
    <<: *web
    ports:
      - 8080:80

If you run docker compose config you can see the normalized spec:

name: example
services:
  dupe-web:
    image: nginx
    networks:
      default: null
    ports:
    - mode: ingress
      target: 80
      published: "8080"
      protocol: tcp
  test-web:
    image: nginx
    networks:
      default: null
    ports:
    - mode: ingress
      target: 80
      published: "80"
      protocol: tcp
networks:
  default:
    name: example_default

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1