Compose v2 changed the container names your scripts parsed

v1 joined the project, service and index with underscores and v2 uses hyphens, which breaks every script that constructed a container name by hand.

# v1
blog_php_1

# v2
blog-php-1

# so this stops finding anything:
docker exec blog_php_1 php artisan migrate

# and this keeps working on both
docker compose exec -T php php artisan migrate

# or, if a raw container id is genuinely needed:
docker compose ps -q php

The compatibility flag --compatibility restores the underscores and is a way to defer the problem rather than fix it. The real lesson is that a container name is an implementation detail and any script constructing one had a latent coupling — docker compose exec and ps -q have always been the supported way to reach a service, and they survive the rename, a project directory being renamed, and scaling to more than one replica.