Vivek
Vivek

Reputation: 3613

Unable to connect to mysql 8 using mysql cmd client while running with docker-compose

I'm running a mysql 8 server on a custom port using docker and try to connect to it with command line client using the below command

`mysql -uroot -p -P 3305 --protocol=TCP -h localhost`

Error Response

ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (61)

Docker Compose File

version: '3'
  
services:
  mysqldb:
    image: mysql:8
    ports:
      - 3305:3306
    environment:
      - MYSQL_ROOT_PASSWORD=MyRootPass
      - MYSQL_USER=myuser
      - MYSQL_PASSWORD=myuserpass
      - MYSQL_DATABASE=mydb
    volumes:
      - ../lcdatastore/mysql/data:/var/lib/mysql

But i'm able to connect to the mysql if the mysql is run using docker run command

docker run -e MYSQL_ROOT_PASSWORD=MyRootPass -e MYSQL_USER=myuser -e MYSQL_PASSWORD=myuserpass -e MYSQL_DATABASE=mydb -p 3305:3306  mysql:8

Thanks for any hint

Update

Upvotes: 0

Views: 870

Answers (1)

acran
acran

Reputation: 9018

I see two possible issues here. The first one is not the case for you in particular, I'm just leaving this here for anyone landing here in the future with that problem:


From the mysql docs:

  • If the host is not specified or is localhost, a connection to the local host occurs:

    • On Unix, MySQL programs treat the host name localhost specially, in a way that is likely different from what you expect compared to other network-based programs: the client connects using a Unix socket file. The --socket option or the MYSQL_UNIX_PORT environment variable may be used to specify the socket name.

I.e. when using localhost as the host mysql tries to connect via a unix socket and not via network. The former won't work on your macOS host since only the latter will pass the connection to the container. You can force the connection via network by using 127.0.0.1 as the host or by passing the --protocol=TCP parameter (which you did in your question):

mysql -uroot -p -P 3305 -h 127.0.0.1
mysql -uroot -p -P 3305 --protocol=TCP -h localhost

The second issue may be that the port is not correctly forwarded from the macOS host to the docker host:

Since docker uses Linux namespaces for its containers it does not actually work on macOS natively. What it does instead is to transparently start a Linux VM in the background - which is the actual docker host - and forwards all docker commands to that VM. So the containers are not actually running on macOS but inside a Linux VM.

So when a container exposes a port to the "host" this refers to Linux VM and not the macOS host. From the perspective of the mysql run on macOS localhostrefers to the macOS host and not the docker host (i.e. the Linux VM).

Normally docker will set up respective port forwardings from the macOS host to the Linux VM automatically to make this work as you expect it. But this seems to be broken in your case. To further debug this, first try to connect to mysql on the Linux VM directly:

# start a new container attached to the host network (i.e. the network of the Linux VM)
# "127.0.0.1" will force a network connection
# and "3305" therfor refers to the localhost on the docker host
docker run --network=host -ti mysql:8 mysql -u root -p -P 3305 -h 127.0.0.1

If this succeeds the docker networking is basically working correctly (inside the Linux VM) and there is an issue with forwarding ports from macOS to the VM.

Now:

Upvotes: 1

Related Questions