288

I find myself in the situation, that I want to disable a service temporarily in a docker-compose file.

Of course I could comment it out, but is there any option to just say "enabled: false" ?

6
  • 11
    The answer is: "it depends" ... on what you are trying to accomplish. If you run docker-compose up it will start all the services by default. However, if you run docker-compose up myservice it will start myservice and things that depend on it. By setting up the dependencies you can make it so the bad service doesn't start with this command. You can also do docker-compose run to get just the services you want. The right choice may also be to break this into multiple compose files to allow you the flexibility you need. Commented May 16, 2016 at 14:58
  • 1
    In order to handle a similar need I had, I play with depends_on and the service argument in docker-compose up, or the option --no-deps in case you don't want to start the dependencies. I know is not what you are looking for, but is the other way around. Commented Feb 28, 2020 at 6:02
  • 5
    Another option is create as many docker-compose files as you need, and pick which of them you want to include in your calls docker-compose -f docker-compose.yml -f another-docker-compose.yml up -d. You can check the resultant docker compose merge with the config command: docker-compose -f docker-compose.yml -f another-docker-compose.yml config Commented Feb 28, 2020 at 6:15
  • Does this answer your question? Can you define optional docker-compose services? Commented Apr 10, 2020 at 19:18
  • @EshaanBansal I don't know of such a feature. Commented Apr 13, 2020 at 15:40

10 Answers 10

309

As of January 2021, there is a way to elegantly disable a service within the docker-compose.yml or to selectively run some services and not others. Docker Compose 1.28.0 introduced support for a profiles key. Now we can do something like:

version: "3.9"
services:
  base_image:
    ...
    profiles:
      - donotstart

Examples in the documentation describe how to use this key to create groups of containers that run together based on a --profile option on the command line. Check out the page here: https://docs.docker.com/compose/profiles/

Update

Support for profiles is working correctly in Compose V2 beta 5 (docker compose). Compose V2 beta 6 has been included in Docker Desktop 3.5.2 released 2021-07-08.

Sign up to request clarification or add additional context in comments.

5 Comments

Is there a way to tell docker to always use some profile? like the profile could be "production" vs "development?"
There is an environment variable that you could set with the name of your default profile. Something like COMPOSE_PROFILES=production.
Note that docker compose version 3.x only works with docker swarm. You cannot use it as standalone on a single machine, like 2.x
Found it, there's no such thing as "default" profiles. Simply you are tricking the mechanism by providing a named profile which you won't call later. Right?
@PatrizioBertoni, that's right. The default is to run containers that have no profile at all. If a container has a profile, it will only be run when you call for that profile. The name I used in my example--"donotstart"--is completely arbitrary. If you want to set a profile to run every time, you can use the COMPOSE_PROFILES environment variable. I probably confused things by referring to this earlier as a "default profile."
125

You can do it in a docker-compose.override.yaml file.

This file is automatically read by docker-compose and merged into the main docker-compose.yaml.

If you have it excluded from Git, each developer can tweak the configuration (with a few limitations) without changing the original docker-compose.yaml.

So, service foo can be disabled ad-hoc by redefining its entrypoint in docker-compose.override.yaml:

version: "3"

services:
  foo:
    entrypoint: ["echo", "Service foo disabled"]

7 Comments

If you have a "restart: unless-stopped" etc comment out that, or it will continuously restart
The idea is to change the entrypoint in the override file. If you have restart policies, change it to an infinite sleep loop
To clarify, you can do this in docker-compose.yml as in VonC's answer. That would be appropriate if you want to check it in and share it with other developers. Also, compose file format v1 accepts service names (foo in the example above) as top-level keys, rather than subkeys of "services".
This solution works nicely if looking to disable/enable a service for a particular environment (eg. development/staging/production) where you have a specified a different override file for each environment with the -f option.
with docker-compose v3 we can using env for disable service, ie: export XXX_ENTRYPOINT=/bin/true then ` entrypoint: [ "${XXX_ENTRYPOINT:-docker-entrypoint.sh}"]`
|
68

assign service to profile(s)

services:
  dev_service:
    ...
    profiles: ["dev"] # only runs with dev profile

enable the profile using

docker compose --profile dev up

ref: https://docs.docker.com/compose/profiles/

Comments

59

You could simply redefine the entrypoint or command in order to replace said command with something which does nothing (/bin/true)

That would make the container exit immediately, doing nothing.


shadi adds the following tips in the comments:

If you don't want the service to get built at all, redefine the build key to point to a Dockerfile that only has:

FROM tianon/true 
ENTRYPOINT ["/true"]

5andr0 points out in the comments the top-level section x-disabled: (an extension field-like)

Far more convenient: moving disabled services to the top-level section x-disabled: instead of services:

Sections with the x- prefix will be parsed, but ignored if not used in the intended way as an extension field.

7 Comments

I would also add/change restart: "no" to avoid infinite restarts
This does not help in the case that the reason what you want to disable this service is because the service can not even start. In my case, I postgres does not start because there is another instance of postgres running, and the ports command causes conflicts. I could start changing the definition, but at that point commenting the whole thing out is easier.
What about disabling building and loading of images?
@Alies The x- section is github.com/compose-spec/compose-spec/blob/master/…, but it is possible indeed that x-disabled is no longer valid.
Best answer imo since you can actually just remove the x-disabled: line to enable the service, since that makes it in line with the top level services: (assuming you add this section directly after the services section.)
|
20

I would scale the service to 0 replicas with:

deploy:
      replicas: 0

Unfortunately as the documentation states this only works with Docker Swarm.

2 Comments

"scale: 0" works just fine for me to disable services with a "version: 3.8" docker-compose file and Docker Desktop 3.2.2
@alv note that "scale" is deprecated
10

I add the following extra line to the service I want to temporarily disable:

command: echo "{put your service name here} disabled"

It starts anyway, but does nothing.

1 Comment

Re-defining the command does not have an effect on the entry point. In your example you rely that the entrypoint is bash I guess. To make this resilient ((independent of the built-in entrypoint) I think you need to redefine the entry point, not the command.
7

From Docker Compose version 2.24.4 and later you can use !reset and !override YAML tags like this: docker-compose.yml:

services:
  db:
    ...
  service2:
    ...
  service3:
    depends_on: 
      - db
      - service2

docker-compose.override.yml:

services:
  db: !reset
  service3:
    depends_on: !override
      - service2

https://docs.docker.com/compose/compose-file/13-merge/#reset-value

Comments

6

I finally found a solution to mimic conditionally run ALL by default except XXX, while avoiding manipulating profiles and breaking basic usage.

Let's say you have your own docker-compose.yaml, create an override docker-compose.override.yaml that will be automatically taken into account like:

services:
  prestashop:
    profiles:
      - ${DISABLE_PRESTASHOP:-}
  postgres:
    profiles:
      - ${DISABLE_APP:-}
  mariadb:
    profiles:
      - ${DISABLE_PRESTASHOP:-}
  mailcatcher:
    profiles:
      - ${DISABLE_PRESTASHOP:-}
  • If you run DISABLE_PRESTASHOP=true docker-compose up only the postgres service will start
  • Or if DISABLE_APP=true docker-compose up, prestashop / mariadb / mailcatcher will run
  • Or if docker-compose up, since Docker does not assign an empty string value, it will run all services

Notes:

  • You could have set DISABLE_APP=whatever it would act as DISABLE_APP=true since it's the profile name we set as required to be launched
  • As expected, using docker-compose down will shutdown all launched services due to no profile set

Comments

3

There is no way to disable a service defined in Docker compose yaml file. VonC's suggestion is a good workaround Please see below the docker compose documentation for available options https://docs.docker.com/compose/compose-file/

Comments

1

I got it:

docker-compose up $(yq -r '.services | keys | join(" ")' docker-compose.yml | sed 's/service-name//')

1 Comment

Update for yq version 4: yq eval '.services | keys | .[] | select(. != "backup")' docker-compose.yml

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.