A stack assembled from three override files and a set of environment variables is not readable by looking at any of them.
$ docker compose
-f docker-compose.yml
-f docker-compose.override.yml
-f docker-compose.ci.yml config
# prints the merged, interpolated, fully resolved file:
# every variable substituted
# every extends flattened
# every relative path made absolute
$ docker compose config --services
$ docker compose config --quiet && echo valid
Running it with --quiet as a CI step catches an undefined variable before a deploy does, which is the failure that otherwise appears as a container started with an empty environment. It is also the fastest way to answer “which port is actually published” on a project where three files each have an opinion.