I’m trying to connect to host OS MySQL
via host.docker.internal, I’m able to connect if i directly mention my internal IP in Laravel application hosted inside docker container.
OS / ENVIRONMENT:
Host operating system and version: MacOS Monterey 12.5.1
Docker desktop version: 4.12.0 (85629)
Docker desktop engine: Engine: 20.10.17
Docker desktop compose version: v2.10.2
Problem:
These are the steps i took to connect my Laravel application inside docker to my host OS MySQL. I successfully managed to connect my application via internal IP address of my Host OS, but the internal IP keep changing and its kind of getting dificult to keep changing the DB_HOST inside laravel .env each time the IP change. so i want to use host.docker.internal
but i won’t work.
Steps:
1: docker-compose down
(Delete all the containers)
2: I removed the devilbox .env port
HOST_PORT_MYSQL=
3: I changed the port of my host OS MySQL to 3306
and using sequel ace i successfully connected to mysql with these credentials
Host: 127.0.0.1
user: root
database: hanger
port: 3306
4: In order to connect from docker to my Host OS MySQL i had to edit my my.cnf
file OR in this case created a new one for MySQL here the my.cnf
[mysqld]
bind_address = 0.0.0.0 # default is 127.0.0.1 Change to 0.0.0.0 to allow remote connections
5: Restarted the MySQL server and confirmed that MySQL can now listen to all IP’s and NOT just localhost
6: used this command
netstat -anp tcp | grep 3306 OR netstat -ap tcp | grep -i "listen"
tcp4 0 0 127.0.0.1.3306 127.0.0.1.52469 ESTABLISHED
tcp4 0 0 127.0.0.1.52469 127.0.0.1.3306 ESTABLISHED
tcp4 0 0 127.0.0.1.3306 127.0.0.1.52468 ESTABLISHED
tcp4 0 0 127.0.0.1.52468 127.0.0.1.3306 ESTABLISHED
tcp4 0 0 127.0.0.1.3306 127.0.0.1.52464 ESTABLISHED
tcp4 0 0 127.0.0.1.52464 127.0.0.1.3306 ESTABLISHED
tcp4 0 0 *.3306 . LISTEN
tcp46 0 0 *.33060 . LISTEN
tcp4 0 0 192.168.18.190.3306 192.168.18.190.52566 TIME_WAIT
tcp4 0 0 192.168.18.190.3306 192.168.18.190.52567 TIME_WAIT
tcp4 0 0 192.168.18.190.3306 192.168.18.190.52568 TIME_WAIT
7: Once its confirmed that 3306
is listeing need to create a MySQL user which would be connected from other than localhost
8: In mysql shell i executed these queries, since I’m using MySQL 8.0.27 the creating user and granting previliges must be in seperate queries.
CREATE USER 'root'@'%' IDENTIFIED BY 'root'; // remember this root password we will use it in Laravel .env
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;
9: To make sure the root@%
user is created type
SELECT User, Host FROM mysql.user;
there are two root users
one with host set to localhost
and second one is %
10: Now its time to Edit Laravel .env
MySQL section
DB_CONNECTION=mysql
DB_HOST=192.168.18.190
// my host machine internal ip (host.docker.internal not working)
DB_PORT=3306
DB_DATABASE=hanger
DB_USERNAME=root
DB_PASSWORD=root
Note: my DB_HOST
did not work with 127.0.0.1
OR host.docker.internal
so i thought it may work with my local IP, which it did.
11: To find out my local IP on MAC go to system preferences > network > My wifi connection > advanced > TCP/IP > under IPv4 192.168.43.182
The thing I’m concerned about is that my local IP keep changing, and as per the documentation The following sections will give you the IP address and/or the CNAME where the host os can be reached from within a container.
https://devilbox.readthedocs.io/en/latest/advanced/connect-to-host-os.html#docker-18-03-0-ce-and-docker-compose-1-20-1 The docker should be able to connect through host.docker.internal to my Host machine, which it does not and i don’t know why. Can you please anyone please point me in the direction what should i do to figure out this issue ?
2
Answers
Don’t know the exact reasoning why does it work on some mac machines and doesn’t on some, but you can force docker to map host.docker.internal by adding
"host.docker.internal:host-gateway"
under extra_hosts in your docker-compose. You should be able to use it post this.Same problem here, the "host.docker.internal" is for development purpose and does not work in a production environment outside of Docker Desktop.
https://docs.docker.com/desktop/networking/#use-cases-and-workarounds-for-all-platforms
Suggested solution:
If you use ufw, the command is the following:
Access to the file can be found in general: /etc/my.cnf
In your case you have already do this.
To check the bridge network details run following command:
Result will be a JSON where you will find the IP of bridge gateway:
If everything is set up correctly, you can access the database on the host machine from the docker container.