31

I want to remove a container defined in docker-compose.yml file when we run in composition/override with another file docker-compose.prod.yml, by example:

# docker-compose.yml
version: 2
services: 

  www:
    image: php56

  db_for_development:
    image: mariadb

override with:

# docker-compose.prod.yml
version: 2
services: 

  www:
    image: php70

  db_for_development:
    [control: override-and-remove] # hypothesis

Then, when running:

docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
docker-compose -f docker-compose.yml -f docker-compose.prod.yml ps

Actually, i have www and db_for_development together.

I want only www container, not others.

Francesco Bianco
  • 519
  • 1
  • 5
  • 12

5 Answers5

28

You may have to switch to version: 3 to do this, I believe on version: 2 you can use the "scale" parameter but I'm not 100% sure.

Anyways, you can override the "replicas" parameter like this:

# docker-compose.prod.yml
version: "3"
services: 

  db_for_development:
    deploy:
      replicas: 0
Matt Blaha
  • 921
  • 6
  • 9
  • 1
    `deploy` key used to be only for swarm. (See here, for example: https://github.com/docker/compose/issues/4672) Does Compose support it now? I could not find it in docs, but in my experiments, looks like it does... Still better to have some doc to refer. – C-F Mar 07 '23 at 21:10
  • You answered your own question . . . note that six year old issue is . . . closed. Follow it through and you can find the release where it became supported? – Matt Blaha Mar 09 '23 at 00:56
13

You're going about this backwards

docker-compose.yml -> specify all services that will be always running

docker-compose.override.yml -> gets picked up automatically, usually used for development

docker-compose.*.yml -> special cases

So, in your case:

You don't remove a container defined in docker-compose.yml, you add it by override with another file or customize it with docker-compose.prod.yml, by example:

docker-compose.yml -> this is the base

version: 2
services: 
  www:
    image: php56

docker-compose.override.yml -> this is dev

version: 2
services: 
  db_for_development:
    image: mariadb

docker-compose.production.yml -> this is prod

version: 2
services: 
  www:
    environment:
      - APP_ENV=production
    env_file:
      - /home/ubuntu/production-app

docker-compose.admin.yml -> this is for the dba

version: 2
services: 
  adminer:
  image: adminer
  restart: always
  ports:
    - 8080:8080

instructions:

For development, docker-compose.yml and docker-compose.override.yml will be used just by running

$ docker-compose up

Production, manually specify both files

$ docker-compose -f docker-compose.yml -f docker-compose.production.yml up --remove-orphans

If you want to bring also bring adminer up (not recommended for production, but sometimes needed anyways)

$  docker-compose -f docker-compose.yml -f docker-compose.production.yml -f docker-compose.admin.yml up

Lastly, when you're done with adminer, just run the production command again this will leave adminer running as an orphan, and you do not want that. That's why the flag --remove-orphans is for

Magus
  • 2,905
  • 28
  • 36
  • 4
    Thanks @Magus, this is a good practices tip but not is a response on my exact request! I'm not looking for the right way to do composition of prod/dev env. The idea is found the best way to remove container throug override – Francesco Bianco Dec 09 '21 at 09:50
  • no problem. the dev/prod is a common scenario that I used to show how the overriding works, you can't remove services through overriding. – Magus Dec 09 '21 at 15:39
3

Let's say you want to remove (disable) a service that's defined in your compose file

Contents of docker-compose.yml

version: "3.4"

services:
  app:
    restart: always
    image: "rasa/rasa-x-demo:${RASA_X_DEMO_VERSION}"
    expose:
      - "5055"
    depends_on:
      - rasa-production

Contents of docker-compose.override.yml

version: "3.4"

services:
  app:
    image: alpine:latest
    command: "true"
    entrypoint: "true"

Done. Now your container will still launch but it's disabled using an empty image

Pian0_M4n
  • 2,505
  • 31
  • 35
  • 4
    That would still consume resources by booting up an alpine linux. Not the ideal solution. – Amir Apr 09 '20 at 20:06
  • Of course, it will. ~35MB RAM. Ideally, you wouldn't have null services in your compose file. – Pian0_M4n Jul 17 '20 at 13:41
  • FYI the `rasa-production` depends_on would still be in play, which is probably not what anyone expects. – Emerson Farrugia Jul 21 '21 at 11:02
  • this will not disable the service, just make the service unusable. – Theo Sep 20 '21 at 08:40
  • 1
    Work for me. I'd add a `restart: "no"` in case it has the restart policy specified in one of the overridden yml files. – cosmin Jul 14 '22 at 07:29
  • @Amir, if you don't want the size of an alpine image then [`tianon/true:latest`](https://hub.docker.com/r/tianon/true/tags) would save some bytes. – jpnp Mar 24 '23 at 16:51
0

This is not possible. Your only real option would be to specify the services (selectively) when running docker-compose up.

yomateo
  • 2,078
  • 12
  • 17
0

Another workaround is possible by using the profile feature added in docker compose version '3.9'

The idea is that in your docker-compose.prod.yml, set a dummy profile for the service to be removed, and call docker compose up without specifying that profile. So in your case:

# docker-compose.prod.yml
version: '3.9' # make sure the version is at least 3.9
services: 
  db_for_development:
    profiles:
      - dummy-profile

Running docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d will not bring up the db_for_development at all.

More examples of how profile works can be found in the official documentation

Charles Chen
  • 21
  • 1
  • 3