Connecting to Docker host MySQL from Docker Container: Linux Ubuntu
Let’s face it. Connecting to the host machine from Docker containers in Linux is frustrating. After hours of googling + trial and errors + crying, I came up with this solution which I’m happy to share it with you.
Why bother?
Both windows and mac version of Docker offers a convenient method of resolving the Dockerhost IP by calling host.docker.internal. Unfortunately at the time of writing this article, host.docker.internal does not work for Linux users.
Prerequisite
- Familiarity with Docker network and basic docker commands.
- Basic knowledge on TCP/UDP ports
1. Add Dockerhost to your docker-compose file:
Add and install this awesome docker container to your project. This container will forward any traffic to your host machine.
# docker-compose.yml
dockerhost:
image: qoomon/docker-host
cap_add:
- NET_ADMIN
- NET_RAW
restart: on-failure
networks:
- backend
- frontend
2. Enable firewall rules to allow dockerhost to connect to your host machine
Set up UFW (Uncomplicated FireWall — Ubuntu built-in firewall manager)
Enable UFW if you haven’t done so already. You can install a GUI if you like. Then add the IP address of the docker host container.
# You can find out the IP of your Dockerhost container by running this command:
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' {your_dockerhost_container_name}
# whitelisting dockerhost container ip
# (my dockerhost container ip is 172.22.0.1)
sudo ufw allow from 172.22.0.1 to any port 3306
# you can also allow the entire subnet to access port 3306
sudo ufw allow from 172.22.0/24 to any port 3306
NOTE: I only need to allow MySQL, which is on port 3306 in my case.
3. Create new admin user in MySQL
Connect to your host machine’s MySQL and run the following queries.
create user 'docker'@'%' identified by 'password';
grant all privileges on {schema}.{table} to 'docker'@'%' with grant option;
Note: {schema} and {table} are placeholders. You can replace them by * as a wildcard.
For example:
# this will let the docker user to have admin access to all tables in the schema 'app'
grant all privileges on app.* to 'docker'@'%' with grant option;
4. Done
Now we only need to connect to the dockerhost container. Simply do this anywhere in your app:
dockerhost:{port}
An alternative method:
If the above doesn’t work, we can add a new network in our docker-compose.yml
file, that looks something like:
networks:
# ..
phptohost:
ipam:
driver: default
config:
- subnet: "172.28.1.0/24"
And remember to add phptohost
to your docker-compose.yml
container’s network list.
Eg:
php-fpm: # A container named 'php-fpm'
# ..
networks: # connecting 'php-fpm' to the network defined below
phptohost:
ipv4_address: 172.28.1.5 # specify a static IP when joining
Host IP can be found via docker inspect <container_id> | grep Gateway
.
And container ID can be found via docker container ls
.
Then in our MySQL connection settings, we can use:
DB_HOST=172.28.1.1
DB_PORT=3306 # your host mysql port
DB_DATABASE=db_name
Lastly, remember to repeat step 3: Create new admin user
in the first section so our MySQL server is able to accept connections from the docker container.