Here's a typical docker-compose.yml
configuration for MySQL that many developers use:
version: '3.8'
services:
mysql:
image: mysql:8.0
container_name: mysql_db
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: rootpassword
MYSQL_DATABASE: app_db
MYSQL_USER: app_user
MYSQL_PASSWORD: userpassword
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
timeout: 20s
retries: 10
volumes:
mysql_data:
When you try connecting using the container IP (172.21.0.2 in your case), MySQL rejects the connection because by default, MySQL Docker containers only allow connections from localhost. The error message indicates the requesting host (172.21.0.1) isn't authorized.
1. Connect Through Localhost Port Forwarding
Since port 3306 is exposed, you can connect directly:
mysql -h 127.0.0.1 -P 3306 -u root -prootpassword
2. Modify MySQL User Permissions
Access the container and update permissions:
docker exec -it mysql_db mysql -uroot -prootpassword
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'rootpassword';
FLUSH PRIVILEGES;
EXIT;
3. Use Docker Network Aliases
Modify your compose file:
services:
mysql:
networks:
default:
aliases:
- db.local
Then connect using the alias:
mysql -h db.local -P 3306 -u root -prootpassword
For production environments, always:
- Create specific database users with limited privileges
- Use strong passwords
- Consider adding SSL configuration
If connections still fail:
# Check if port is listening
docker exec mysql_db netstat -tuln | grep 3306
# Test connectivity between containers
docker run --rm -it --network your_network_name busybox ping mysql_db
When working with MySQL in Docker, one common frustration occurs when your connection attempts get rejected with:
ERROR 1130 (HY000): Host '172.21.0.1' is not allowed to connect to this MySQL server
Docker creates its own network bridge (docker0 by default) with private IP ranges. Your MySQL container gets an IP like 172.21.0.2, while the host machine's docker interface gets 172.21.0.1. MySQL by default doesn't allow remote root access.
Here's an improved docker-compose.yml that solves multiple issues:
version: '3.8'
services:
mysql:
image: mysql:8.0
container_name: mysql_db
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: test_db
MYSQL_USER: test
MYSQL_PASSWORD: test_pass
MYSQL_ROOT_HOST: '%'
command: --default-authentication-plugin=mysql_native_password
restart: unless-stopped
volumes:
mysql_data:
- Added
MYSQL_ROOT_HOST: '%'
to allow root access from any host - Used named volume instead of host path for better portability
- Specified exact MySQL version (8.0) for consistency
- Added container restart policy
Instead of using the container IP, you can:
- Connect via localhost:
mysql -h 127.0.0.1 -P 3306 -u root -p
- Use the service name from another container:
mysql -h mysql -P 3306 -u test -p
If problems continue, try these diagnostic commands:
# Check if container is running
docker ps
# View container logs
docker logs mysql_db
# Test basic connectivity
nc -zv 127.0.0.1 3306