depends_on waits for the container to start, which is not the same as the process inside it being ready to answer.
services:
mysql:
image: mysql:8.0
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1"]
interval: 5s
timeout: 3s
retries: 10
start_period: 30s
php:
depends_on:
mysql:
condition: service_healthy
The long form with a condition is the whole point and the short list form does nothing useful for anything with a startup sequence. start_period is the field people miss: without it, failing health checks during a legitimate initialisation count towards the retry budget, and MySQL on a fresh volume takes long enough to exhaust it. This still does not guarantee readiness if the health check is weaker than the thing your application needs, which is the next note.