In this, we’ll discuss solutions for the “issue connecting from inside docker container to docker host”. This issue arises when you’re using containerized microservices with non-containerized services. For e.g.,
Let’s say, you’re running your MySQL service on your host machine and you have to access it from the applications which are running in docker containers. Then, you have to follow the following steps to establish the connection between them. Otherwise, it will throw a permission denied error.
Prerequisites
- Basics of docker networking
- Basics of CLI
Solutions – Issue Connecting Host From Inside Docker Container
Solution-1: Using host.docker.internal
instead of localhost
1.1) In docker
If you’re facing this issue, then use of host as host.docker.internal
instead of localhost
or 127.0.0.1
resolves. But to enable this feature you need to use an extra parameter to Command Line:- --add-host=host.docker.internal:host-gateway
.
$ docker run -d -p 3000:3000 --add-host=host.docker.internal:host-gateway --name demoapp-container demoapp:latest;
And, now you can access localhost of the host machine using the special DNS name host.docker.internal
.
1.2) In docker-compose
To enable host.docker.internal
in docker-compose, add the following lines in the container definition section:
extra_hosts:
- "host.docker.internal:host-gateway"
Note: For mac:
docker.for.mac.host.internal
(for docker version 17.12 – 18.02) ordocker.for.mac.localhost
(for docker version ≤ 17.06)
Solution-2: Using --network="host"
in docker run
command (Linux)
Alternatively, if you’re using a Linux system, then you can run a docker container with parameter --network="host"
. This will share the network stack with the docker host. And this opens any ports opened in the docker container on the docker host also.
IP configuration of host:
$ ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 08:00:27:98:dc:aa brd ff:ff:ff:ff:ff:ff
inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::a00:27ff:fe98:dcaa/64 scope link
valid_lft forever preferred_lft forever
and IP configuration of docker container with host method:
$ docker run -it --network=host demoapp:latest ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 08:00:27:98:dc:aa brd ff:ff:ff:ff:ff:ff
inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::a00:27ff:fe98:dcaa/64 scope link
valid_lft forever preferred_lft forever
Connecting host from inside docker container
Bridge mode
When you run docker run
command with --network="bridge"
or without --network="bridge"
(as it is the default mode), then you’re using bridge mode.
In this, the connection between host MySQL and containerized apps can be established by changing bind-address
value in MySQL config file (my.cnf or mysqld.cnf).
Case-1: If you use bind-address = 0.0.0.0
, MySQL server will listen for connections on all network interfaces. i.e. your MySQL server will be reachable from the internet. You can use a firewall as an access rule to restrict or allow the connections accordingly.
Case-2: If you use bind-address = <SPECIFIC_IP>
, then the MySQL server will listen to connections from the specified IP address only.
$ sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
...
# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
bind-address = 0.0.0.0
...
Note: Location of cnf file might be different for your OS. For Red Hat based distributions such as CentOS,
/etc/mysql/my.cnf
or/etc/my.cnf
After the change of bind-address, restart MySQL service:
# For Ubuntu/Debian
$ sudo systemctl restart mysql
# For Red Hat based distributions(like CentOS)
$ sudo systemctl restart mysqld
Host mode
If you run docker run
command with --network="host"
parameter, the container will share the network stack with the docker host.
For this host mode, you need use bind-address = 127.0.0.1
so that MySQL will listen for connections to IP 127.0.0.1
.
Note: For host mode, you have to use
127.0.0.1
instead of[localhost](<http://localhost>)
; otherwise it will try to use the Unix socket to connect.
e.g.
$ mysql -h 127.0.0.1 -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \\g.
Your MySQL connection id is 267
Server version: 8.0.30-0ubuntu0.22.04.1 (Ubuntu)
Copyright (c) 2000, 2022, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\\h' for help. Type '\\c' to clear the current input statement.
mysql>
That’s all.
Conclusion
In this, we discussed how to solve “issue connecting host from inside docker container to docker host” with proper explanations.
Thank You!