compose: profile-deactivated dependencies do not cause a failure

Description

According to the documentation, docker compose will fail if a dependency is deactivated through an inactive profile:

# this will fail because profile "dev" is disabled
$ docker compose up phpmyadmin

However in practice, docker compose will successfully start and not even print an error or warning (it “fails to fail”).

Steps to reproduce the issue:

  1. Create the following docker-compose.yml
services:
  foo:
    image: hello-world
    profiles: ["foo"]
  bar:
    image: hello-world
    depends_on:
      foo:
        condition: service_completed_successfully
  1. docker compose up

Describe the results you received:

docker compose will just silently execute service “bar”:

$ docker compose up               
[+] Running 1/0
 ⠿ Container test-bar-1  Created                                                                                                                         0.1s
Attaching to test-bar-1
test-bar-1  | 
test-bar-1  | Hello from Docker!
test-bar-1  | This message shows that your installation appears to be working correctly.
test-bar-1  | 
test-bar-1  | To generate this message, Docker took the following steps:
test-bar-1  |  1. The Docker client contacted the Docker daemon.
test-bar-1  |  2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
test-bar-1  |     (amd64)
test-bar-1  |  3. The Docker daemon created a new container from that image which runs the
test-bar-1  |     executable that produces the output you are currently reading.
test-bar-1  |  4. The Docker daemon streamed that output to the Docker client, which sent it
test-bar-1  |     to your terminal.
test-bar-1  | 
test-bar-1  | To try something more ambitious, you can run an Ubuntu container with:
test-bar-1  |  $ docker run -it ubuntu bash
test-bar-1  | 
test-bar-1  | Share images, automate workflows, and more with a free Docker ID:
test-bar-1  |  https://hub.docker.com/
test-bar-1  | 
test-bar-1  | For more examples and ideas, visit:
test-bar-1  |  https://docs.docker.com/get-started/
test-bar-1  | 
test-bar-1 exited with code 0

Describe the results you expected:

According to the docs, I expected a failure, which I interpret as preferably docker compose not starting at all but instead exiting with an error message, or at least if it does start it should print an error message. Alternatively it could automatically start foo but that seems to be not intended according to the docs.

Output of docker compose version:

Docker Compose version 2.10.2

Output of docker info:

Client:
 Context:    default
 Debug Mode: false
 Plugins:
  buildx: Docker Buildx (Docker Inc., v0.8.2-docker)
  compose: Docker Compose (Docker Inc., 2.10.2)

Server:
 Containers: 175
  Running: 0
  Paused: 0
  Stopped: 175
 Images: 249
 Server Version: 20.10.17
 Storage Driver: overlay2
  Backing Filesystem: extfs
  Supports d_type: true
  Native Overlay Diff: false
  userxattr: false
 Logging Driver: json-file
 Cgroup Driver: systemd
 Cgroup Version: 2
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: inactive
 Runtimes: io.containerd.runc.v2 io.containerd.runtime.v1.linux runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 9cd3357b7fd7218e4aec3eae239db1f68a5a6ec6.m
 runc version: 
 init version: de40ad0
 Security Options:
  seccomp
   Profile: default
  cgroupns
 Kernel Version: 5.19.2-arch1-1
 Operating System: Arch Linux
 OSType: linux
 Architecture: x86_64
 CPUs: 20
 Total Memory: 46.97GiB
 Name: konradsdesktop
 ID: 3NEP:3UOO:RVV3:RCWK:44GY:N4UB:ZIRE:2BN7:KSBI:CMZG:5KFU:YRPN
 Docker Root Dir: /home/konrad/docker
 Debug Mode: false
 Registry: https://index.docker.io/v1/
 Labels:
 Experimental: false
 Insecure Registries:
  127.0.0.0/8
 Live Restore Enabled: false

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 17 (5 by maintainers)

Most upvoted comments

Hi,

I would like to make a case for changing the specification to keep this behavior of it silently ignoring depends_on because this allows you to have a docker-compose.yml file that looks like this:

services:
  postgres:
    profiles: ["postgres"]
  redis:
    profiles: ["redis"]
  web:
    profiles: ["web"]
    depends_on: ["postgres", "redis"]
  worker:
    profiles: ["worker"]
    depends_on: ["postgres", "redis"]
  assets:
    profiles: ["assets"]

In development you can set this environment variable in an .env file to start everything:

export COMPOSE_PROFILES=postgres,redis,assets,web,worker

In production you can set this instead:

export COMPOSE_PROFILES=web,worker

This would let you not run a dev-only set of assets containers in production for various watchers and also take advantage of using your cloud provider’s managed Postgres and Redis services because the local containers for those services don’t need to run since the cloud provider’s managed service will fulfill that dependency.

If this bug were fixed then we’re back to profiles being in my opinion not very useful because the above wouldn’t be possible anymore. I actually made a blog post and video about this other day at https://nickjanetakis.com/blog/docker-tip-94-docker-compose-v2-and-profiles-are-the-best-thing-ever which goes into more details.

Personally if this were fixed and brought back to its previous form I would stop using Docker Compose profiles and go back to using an override file plus hacky sed replacements in prod which is way worse than the current unfixed but fully working approach.

Please consider not fixing this and officially change the spec to use the current behavior by default.

did this get changed? My compose file looks like this:

api:
    build: .
    restart: unless-stopped
    networks:
      - nginx-proxy
    profiles:
      - deploy
api_dev:
    build: .
    depends_on:
      - db
    ports:
      - "8000:80"
    networks:
      - internal
    profiles:
      - dev
worker:
    build: "./worker"
    user: nobody
    depends_on:
      - api_dev
      - api

but now this happens:

> docker-compose --profile dev up
no such service: api

I think this affects both development and production. It’s extremely common to use managed databases in production but not in development and you’d still want depends_on for development while depends_on is inactive / ignored in prod (as needed).

The current unfixed behavior handles this use case perfectly. Having this fixed without another type of workaround as an alternative solution is a big hit to the developer experience or for anyone who wants to use Docker Compose in both development and production.

IMO the unfixed behavior is the user friendly / intuitive behavior. I want depends_on when I activate profiles that use it, however if I have depends_on defined but didn’t activate the dependent profile then it’s expected the dependency is coming from somewhere else. If it doesn’t that’s out of Docker’s control to enforce a working system.