Direct command to compose up/down a profile without up/down default

There’s no proper way to compose down only a profile’s services without specifying specific service names or getting default services down along as well.

For e.g. if you do docker compose --profile=xyz down removes the default services along.
correct way is to docker compose down <profile_service_1> <profile_service_2> …

that’s inconvenient. there might be nesting command to get services names dynamically from config maybe. But hard to get around such complex command.

Is there some ideal way. Or can we introduce something for this?

It matches the behaviour in the docs:

The behaviour between --profile=x up and --profile=x down.are consistent. Right now there is no way around specifying the service names as used in the compose file (not profile_service_?) on docker compose down <service1> <service2>.. I understand it’s inconvenient and share your point of view..

You might want to add a feature request in the git repository and ask that a --profile-only argument is added to the down action, if --profile is used.

my first instinct was to create an issue in that repo, however to avoid spamming issues I just wanted to be double sure there’s no convenient way around other that manually naming services to down/stop/up/logs.

Just to share why I think it works like it does:

The profiles are for optional services not to use as filters like you would with labels in some cases. So when you define a profile for a service, it becomes optional and while the default services will always be included, services with profiles only when you allow that profile.

So when you want to use “down”, you still need to allow those profiles, but again, the defaults are included.

What you can do at the moment is define a “default” profile for all services that don’t have one. It is easy if you made the compose project, but if you don’t want to permanently add profiles to all services or it is an existing project, you can generate the default profile into a compose.override.yml with this command in a linux shell:

docker compose config --services \
  | awk 'BEGIN {printf "services:\n"} \
               {printf "  " $0 ":\n    profiles: [default]\n"}' \
  > compose.override.yml

Since the main command above is docker compsoe config --services and it has no profile option, services with profiles are not allowed here either and you get only profileless services. The awk command then generates the content of the override compose file which is read by docker compose commands automatically.

Here is my test compose file:

services:
  default:
    image: nginx
  default2:
    image: nginx
  a:
    image: nginx
    profiles:
      - a
    depends_on:
      - default
  b:
    image: nginx
    profiles:
      - b
  ab:
    image: nginx
    profiles:
      - a
      - b

And the generated override file:

services:
  default:
    profiles: [default]
  default2:
    profiles: [default]

In this example service “a” depends on “default”, so when you try to run

docker compose --profile a down

you will get:

service "a" depends on undefined service "default": invalid compose project

What's next:
    Debug this Compose error with Gordon → docker ai "help me fix this compose error"

The following command would work:

docker compose --profile default --profile a down

Output:

[+] down 4/4
 ✔ Container profiles-a-1        Removed                                                                                                                         0.1s
 ✔ Container profiles-default2-1 Removed                                                                                                                         0.2s
 ✔ Container profiles-default-1  Removed                                                                                                                         0.1s
 ✔ Network profiles_default      Removed

Since service “b” has no dependency, you can easily delete that

docker compose --profile b down

Output:

[+] down 3/3
 ✔ Container profiles-ab-1  Removed                                                                                                                              0.2s
 ✔ Container profiles-b-1   Removed                                                                                                                              0.1s
 ✔ Network profiles_default Removed

So generating the default profile for alls ervices without other profiles can be a workaround if you don’t mind that for services with dependencies you have to allow the default profile as well, otherwise the dependency will not be found.

And of course, since all your services wil have profiles, a simply docker compose down will not delete anything.

nice insights. workarounds are fine for individuals but not for teams. hence my goal/perspective is to have it without workarounds. I usually have a folder structure like

project
|- backend/
|  |- ...
|  |- compose.yml
|- frontend/
|  |- ...
|  |- compose.yml
|- some-services/
|  |- ...
|  |- compose.yml
|- .../
|- compose.yml (includes and overrides if required any/all compose from sub folders, contains db, logging & monitoring, utility like pgadmin or phpmyadmin etc. as different profiles as required by people.)
|- ...

and my team heavily relies on vscode-containers extension for compose commands. and people are often sharing services like db and promtail, grafana for log/metric while developing. and sometimes people only have access to limited repos(sub folder/submodules).
profiles are a nice way to manage, like default, infra, log, monitor, backend, frontend etc. but when doing compose down, I don’t want to shut infra and default profile being used by other devs but stop maybe extras profile. while they run their default or other specific profile(s) only. without having to know names of tons of services.