243

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)?

1
  • 2
    If the MySQL server is listening on a port, couldn't the container just connect to the host on that port like any other internet connection? Commented Jan 20, 2015 at 22:51

8 Answers 8

207

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
Sign up to request clarification or add additional context in comments.

7 Comments

Just as hint: this does only work for Mac and Win so far
Upvote. Not just because of the answer, but because you should HOW to use it with an example.
Still no linux support as @flp wrote, for those curious. Here is the github issue.
This is my connection string in .NET , it cannot find database from docker "server=gateway.docker.internal;user=root;database=mydb;port=3306;password=" tried also with "host.docker.internal"
Still no doesn't work with Linux host machines!
|
100

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

1 Comment

Will it be also working behind a NGINX reverse proxy??
53

Use host.docker.internal from Docker 18.03 onwards.

6 Comments

how ? can you give an example of how to use it ?
Why don't you run a dockerized mysql?
does not work for me at Docker version 18.03.0-ce, build 0520e24
docker.for.mac.localhost works for me on 18.03.1-ce-mac65
replace localhost with host.docker.internal
|
45

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

2 Comments

docker.for.mac.host.internal from Docker 17.12.0 ce onwards. docs.docker.com/docker-for-mac/release-notes/…
docker.for.mac.localhost works on 18.03.1-ce-mac65
36

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.

1 Comment

--net=host worked for me on a CI environment, thanks a lot!
9

There is presumably a preferred way of doing this, working regardless of the host O/S.

When using docker run

docker run --add-host host.docker.internal:host-gateway

When using docker compose

services:
  myservices:
    extra_hosts:
      - host.docker.internal:host-gateway

    environments:
      - DBHOST=host.docker.internal:5432

This will create an entry host.docker.internal in /etc/hosts

1 Comment

Worked for me, and as you said is the preferred way of doing it; should be the top answer
5

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!");
});

3 Comments

Using Ubuntu 20.04. Changing the host to 172.17.0.1 does fix my problem. The container can connect to database from the host IP.
For me and my Docker Compose File - Specifying the Service that I wanted to use as my DB Host worked
Thanks so much, the solution with the docker IP 172.17.0.1 instead of localhost in your described case 1 solved my issue!
0

I am using:

  • Mac M2 Ventura 13.6.2
  • Engine: 24.0.6
  • Compose: v2.23.0-desktop.1

Ran the container either way by

docker run --detach --name some-mariadb --env MARIADB_ROOT_PASSWORD=123456  -p 3306:3306  mariadb:latest

OR used docker-compose.yml

version: "1.0"
name: "some_mariadb"
services:
  db:
    image: mariadb:10.5
    command: '--default-authentication-plugin=mysql_native_password'
    volumes:
      - ./tmp:/var/lib/mysql
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=123456
    ports:
      - "3306:3306"
    expose:
      - 3306

And successfully connected to the container simply by

mysql -h 127.0.0.1 -u root -p123456

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.