ScanSkill
Sign up for daily dose of tech articles at your inbox.
Loading

[Solved]: Issue Connecting Host From Inside Docker Container

[Solved]: Issue Connecting Host From Inside Docker Container
[Solved]: Issue Connecting Host From Inside Docker Container

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) or docker.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!

Sign up for daily dose of tech articles at your inbox.
Loading