Access host database from a docker container

Docker

Docker Problem Overview


If I have a mysql database running on some host machine, and that host is also running a docker container: How would I access the mysql database from within the docker container that is running on the host?.

For instance, is there a way to publish a hosts port to the container (the inverse of what docker run -p does)?

Docker Solutions


Solution 1 - Docker

From the 18.03 docs:

> I want to connect from a container to a service on the host > > The host has a changing IP address (or none if you have no network access). From 18.03 onwards our recommendation is to connect to the special DNS name host.docker.internal, which resolves to the internal IP address used by the host. > > The gateway is also reachable as gateway.docker.internal.

EXAMPLE: Here's what I use for my MySQL connection string inside my container to access the MySQL instance on my host:

mysql://host.docker.internal:3306/my_awesome_database

Solution 2 - Docker

There are several long standing discussions about how to do this in a consistent, well understood and portable way. No complete resolution but I'll link you to the discussions below.

In any event you many want to try using the --add-host option to docker run to add the ip address of the host into the container's /etc/host file. From there it's trivial to connect to the host on any required port:

> Adding entries to a container hosts file > > You can add other hosts into a container's /etc/hosts file by using > one or more --add-host flags. This example adds a static address for a > host named docker: > >
> > $ docker run --add-host=docker:10.180.0.1 --rm -it debian > $$ ping docker > PING docker (10.180.0.1): 48 data bytes > 56 bytes from 10.180.0.1: icmp_seq=0 ttl=254 time=7.600 ms > 56 bytes from 10.180.0.1: icmp_seq=1 ttl=254 time=30.705 ms > ^C--- docker ping statistics --- > 2 packets transmitted, 2 packets received, 0% packet loss > round-trip min/avg/max/stddev = 7.600/19.152/30.705/11.553 ms > > Note: Sometimes you need to connect to the Docker host, which means > getting the IP address of the host. You can use the following shell > commands to simplify this process: > > $ alias hostip="ip route show 0.0.0.0/0 | grep -Eo 'via \S+' | awk '{ print $2 }'" > $ docker run --add-host=docker:$(hostip) --rm -it debian

Documentation:

https://docs.docker.com/engine/reference/commandline/run/

Discussions on accessing host from container:

https://github.com/docker/docker/issues/1143

https://github.com/docker/docker/issues/10023

Solution 3 - Docker

From Docker 17.06 onwards, a special Mac-only DNS name is available in docker containers that resolves to the IP address of the host. It is:

docker.for.mac.localhost

The documentation is here: https://docs.docker.com/docker-for-mac/networking/#httphttps-proxy-support

Solution 4 - Docker

Use host.docker.internal from Docker 18.03 onwards.

Solution 5 - Docker

Other answers did not work well for me. My container could not resolve host ip using host.docker.internal. There are two ways

  1. Sharing host network --net=host:

     docker run -it --net=host  myimage
    
  2. Using docker's ip address, which is usually 172.17.0.1. You can check it by calling ifconfig command and grabbing inet addr of docker interface

     user@ubuntu:~$ ifconfig
     docker0   Link encap:Ethernet  HWaddr 02:42:a4:a2:b2:f1  
       inet addr:172.17.0.1  Bcast:0.0.0.0  Mask:255.255.0.0
       inet6 addr: fe80::42:a4ff:fea2:b2f1/64 Scope:Link
    

Once you have this ip address, you can pass it as an argument to docker run and then to application or as I do it, map the location of jdbc.properties via volume to the directory on host machine, so you can manage the file externally.

  docker run -it -v /host_dir/docker_jdbc_config:${jetty_base}/var/config myimage

NOTE: Your database might not allow external connections. In case of postgresql, you need to edit 2 files, as described here and here:

  1. Edit postgresql.conf to listen on all addresses. By default it will point to localhost.

     listen_addresses = '*'
    
  2. Edit pg_hba.conf to allow connections from all addresses. Add on the last line:

     host     all             all             0.0.0.0/0               md5
    

IMPORTANT: Last step updating database access is not recommended for production use unless you are really sure what you are doing.

Solution 6 - Docker

For Linux Only
Case 1:-Mysqldb running on localhost not on docker
You can fix the host Ip to connect and connect to that ip instead of localhost.
For linux dockerhost is fixed which is 172.17.0.1.So connect to 172.17.0.1 instead of localhost.
Case2:- If the mysqldb is also running on docker then the best practice is to connect with the docker container name instead of IP address.
So docker-compose file should look like this

version: '3.8'
services:
  mysqldb:
    image: mysql:5.7
    restart: unless-stopped
    env_file: ./.env
    environment:
      - MYSQL_ROOT_PASSWORD=$MYSQLDB_ROOT_PASSWORD
      - MYSQL_DATABASE=$MYSQLDB_DATABASE
    ports:
      - $MYSQLDB_LOCAL_PORT:$MYSQLDB_DOCKER_PORT
    volumes:
      - db:/var/lib/mysql
producer:
     build: .
     ports:
      - '$LOCAL_PORT:$DOCKER_PORT' 
     depends_on:
         - mysqlsb
     volumes:
         - ./:/usr/src/app

Now instead of an ip or localhost connect to mysqlsb

var mysql = require('mysql');

var con = mysql.createConnection({
  host: mysqldb,
  user: "yourusername",
  password: "yourpassword"
});

con.connect(function(err) {
  if (err) throw err;
  console.log("Connected!");
});

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRyan AndersonView Question on Stackoverflow
Solution 1 - DockerKevin ChenView Answer on Stackoverflow
Solution 2 - DockerJohn PetroneView Answer on Stackoverflow
Solution 3 - DockerBazmatiqView Answer on Stackoverflow
Solution 4 - DockerIgor De Oliveira SáView Answer on Stackoverflow
Solution 5 - DockergmodeView Answer on Stackoverflow
Solution 6 - DockerDivyanshu SenView Answer on Stackoverflow