MySQL "Connection refused" before "ready for connections" in CI
The MySQL container is starting but the server has not yet printed "ready for connections" and is not listening on 3306. Early connects are refused. A mysqladmin ping healthcheck gates steps until it is ready.
What this error means
The first connection fails with "Can't connect to MySQL server on '127.0.0.1' (111)" or a refused TCP connect, and the container log later shows "[Server] ... ready for connections".
ERROR 2003 (HY000): Can't connect to MySQL server on '127.0.0.1:3306' (111)Common causes
MySQL is still initializing the data directory
On first boot the image runs initialization (creating the system tables and any MYSQL_DATABASE). The port is not accepting connections until that finishes.
No healthcheck waits for "ready for connections"
Without a mysqladmin ping health command, steps run as soon as the container exists, before the server is up.
How to fix it
Gate steps with a mysqladmin ping healthcheck
GitHub Actions holds job steps until the service is healthy.
services:
mysql:
image: mysql:8.0
env:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: app_test
ports: ['3306:3306']
options: >-
--health-cmd "mysqladmin ping -h 127.0.0.1 -uroot -proot --silent"
--health-interval 5s
--health-timeout 5s
--health-retries 15Poll with mysqladmin ping in a loop
For docker-compose, wait until ping succeeds before running migrations.
until mysqladmin ping -h 127.0.0.1 -uroot -proot --silent; do
echo "waiting for mysql"; sleep 2
doneHow to prevent it
- Always add a
mysqladmin pinghealthcheck to the MySQL service. - Allow generous
--health-retries; MySQL first boot can take 10-20s. - Connect over TCP to
127.0.0.1:3306, not a socket, from steps.