Search code examples
dockerdocker-composecontainers

How to run service with deploy.replica=0 in docker-compose.yml?


I have services in my docker-compose.yml configuration that I would occasionally use, such as for end-to-end testing, linting, or some one-off service.

Something along the lines of this:

  app:
    ...

  e2e-or-linter-or-one-off:
    ...
    deploy:
      replicas: 0

With replicas set to 0, docker-compose up would not spin up the e2e-or-linter-or-one-off service when I just want to run my regular app container(s).

And when I would need that e2e-or-linter-or-one-off service, I want to do something like this:

docker-compose run e2e-or-linter-or-one-off bash

Is there a way to define a service that doesn't spin up on docker-compose up but is still able to be used with docker-compose run?

docker-compose up has a --scale flag that I can use if I wanted to spin everything up, such as:

docker-compose up --scale "e2e-or-linter-or-one-off"=1 e2e-or-linter-or-one-off

But docker-compose run doesn't have a similar flag that can be used and I need docker-compose run so I can run the container interactively. Without it this:

docker-compose run e2e bash

won't work and Docker returns: no containers to start

Thank you for your help 🙏


Solution

  • This article shows a way to use an environment variable for the replica count, allowing you to change the value at invocation-time:

      app:
        ...
    
      e2e-or-linter-or-one-off:
        ...
        deploy:
          replicas: ${E2E_REPLICAS:-0}
    

    I modified the example a bit so you don't need to have the env var set 100% of the time. The :- in the variable expansion is an operator that says "use the default value to the right if the name to the left is unset or empty".

    Now running docker-compose up should run every service with 1+ replicas defined, but invoking E2E_REPLICAS=1 docker-compose run --rm e2e-or-linter-or-one-off bash will set the env variable, overriding the default value of 0, create the container & service, and run bash. When you're done with your shell session, the --rm tag will tear down the container so the environment returns to its normal operational state.