How to Fix “Host Not Allowed to Connect” Error When Accessing MySQL Docker Container


2 views

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:

  1. Connect via localhost: mysql -h 127.0.0.1 -P 3306 -u root -p
  2. 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