avatarSam Ngu

Summary

The article provides a step-by-step guide to connect a Docker container to a MySQL database on the host machine in a Linux Ubuntu environment.

Abstract

The author of the article shares a solution to the common challenge of connecting Docker containers to the host machine's MySQL database on Linux Ubuntu. The process involves adding a docker-host container to the docker-compose.yml file to forward traffic to the host, configuring firewall rules to allow the Docker container to communicate with the host, creating a new admin user in MySQL with the necessary privileges, and finally, connecting to the dockerhost container from the application. The article also presents an alternative method involving the creation of a custom network with a static IP for the Docker container.

Opinions

  • The author expresses frustration with the complexity of connecting Docker containers to the host machine in Linux, implying that it is a non-trivial task.
  • They endorse the use of the qoomon/docker-host container, suggesting it is an "awesome" solution to the problem.
  • The author notes the convenience of the host.docker.internal feature available for Windows and Mac Docker users, highlighting its absence in Linux as a point of inconvenience.
  • The author emphasizes the importance of understanding Docker networking and basic TCP/UDP ports as prerequisites for implementing the solution.
  • They recommend using UFW (Uncomplicated FireWall) to manage firewall rules, suggesting it as a user-friendly option for Ubuntu users.
  • The author advises creating a dedicated MySQL user for Docker connections, which indicates a preference for security best practices.
  • They provide a note on the flexibility of granting MySQL privileges, suggesting that users can tailor access to specific schemas and tables as needed.
  • The alternative method provided suggests that the author acknowledges potential variations in network configurations and offers a solution that involves setting a static IP for the Docker container.

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.

Photo by Oliver Hihn on Unsplash

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.

Docker
Linux
MySQL
Ubuntu
Recommended from ReadMedium