search

Home  >  Q&A  >  body text

From inside a Docker container, how do I connect to the machine's localhost?

<p>I have an Nginx running inside a docker container. I have a MySql running on the host system. I want to connect to MySql from within my container. MySql only binds to the localhost device. </p> <p>Is there any way to connect to this MySql or any other program on localhost from within this docker container? </p> <p>This question is different from "How to get the IP address of the docker host from inside the docker container" because the IP address of the docker host may be a public IP or a private IP in the network, which may or may not be accessible from within the docker container (I means public IP if hosted on AWS or elsewhere). Even if you have the IP address of the docker host, it does not mean that you can connect to the docker host from within the container, because your Docker network may be an overlay network, a host network, a bridge network, a macvlan network, a none network, etc., which limits The container's reachability to this IP address. </p>
P粉787820396P粉787820396451 days ago582

reply all(2)I'll reply

  • P粉517090748

    P粉5170907482023-08-24 11:07:24

    Available on all platforms

    Docker v 20.10 and later (as of December 14, 2020)

    Use your internal IP address or connect to the special DNS name host.docker.internal, which will resolve to the internal IP address used by the host.

    This is for development purposes and is not intended for use in production environments outside of Docker Desktop.

    Linux Warning

    To enable this feature in Docker on Linux, add --add-host=host.docker.internal:host-gateway to your The docker command enables this feature.

    To enable this feature in Docker Compose on Linux, add the following line to the container definition:

    extra_hosts:
        - "host.docker.internal:host-gateway"
    

    According to some users, the special DNS names only work in Docker's default bridge network and not in custom networks.

    For older macOS and Windows versions of Docker

    Docker v 18.03 and later (as of March 21, 2018)

    Use your internal IP address or connect to the special DNS name host.docker.internal, which will resolve to the internal IP address used by the host.

    Linux support is pending https://github.com/docker/for-linux/issues /264

    For older macOS versions of Docker

    Docker for Mac v 17.12 to v 18.02

    Same as above, but using docker.for.mac.host.internal.

    Docker for Mac v 17.06 to v 17.11

    Same as above, but use docker.for.mac.localhost instead.

    Docker for Mac 17.05 and lower

    To access the host from a docker container, you must attach an IP alias to your network interface. You can bind any IP you want, just make sure you're not using it for anything else.

    sudo ifconfig lo0 alias 123.123.123.123/24

    Then make sure your server is listening on the above IP or 0.0.0.0. If it is listening on localhost 127.0.0.1, it will not accept connections.

    Then just point your docker container to this IP to access the host!

    To test, you can run something like curl -X GET 123.123.123.123:3000 inside the container.

    Aliases will be reset on every reboot, so create a startup script if necessary.

    Solution and more documentation here: https://docs.docker.com/desktop/networking/#use-cases-and-workarounds-for-all-platforms

    reply
    0
  • P粉019353247

    P粉0193532472023-08-24 09:26:22

    edit:

    If you are using Docker-for-mac or Docker-for-Windows 18.03, use host host.docker.internal (instead of 127.0.0.1< /code> in your connection string).

    If you are using Docker-for-Linux 20.10.0, you can also use host host.docker.internal ifYou use --add-host host.docker.internal:host-gateway option starts the Docker container, or the following code snippet is added to the docker-compose.yml file:

    extra_hosts:
        - "host.docker.internal:host-gateway"
    

    Otherwise, please read below


    TLDR

    Use --network="host" in the docker run command, then 127.0.0.1 in the docker container will point to your docker host .

    Note: This mode is only available for Linux versions of Docker, according to the documentation.


    Notes on docker container network mode

    Docker provides different network modes when running containers. Depending on the mode you choose, you will connect to the MySQL database running on the docker host differently.

    docker run --network="bridge" (default)

    Docker creates a bridge named docker0 by default. Both the docker host and the docker container have an IP address on the bridge.

    On the Docker host, enter sudo ip addr show docker0 You will get output like this:

    [vagrant@docker:~] $ sudo ip addr show docker0
    4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
        link/ether 56:84:7a:fe:97:99 brd ff:ff:ff:ff:ff:ff
        inet 172.17.42.1/16 scope global docker0
           valid_lft forever preferred_lft forever
        inet6 fe80::5484:7aff:fefe:9799/64 scope link
           valid_lft forever preferred_lft forever

    So, my docker host's IP address on the docker0 network interface is 172.17.42.1.

    Now start a new container and get a shell on it: docker run --rm -it ubuntu:trusty bash and type in the container ip addr show eth0 to know its master How to set up the network interface:

    root@e77f6a1b3740:/# ip addr show eth0
    863: eth0: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
        link/ether 66:32:13:f0:f1:e3 brd ff:ff:ff:ff:ff:ff
        inet 172.17.1.192/16 scope global eth0
           valid_lft forever preferred_lft forever
        inet6 fe80::6432:13ff:fef0:f1e3/64 scope link
           valid_lft forever preferred_lft forever

    The IP address of my container here is 172.17.1.192. Now view the routing table:

    root@e77f6a1b3740:/# route
    Kernel IP routing table
    Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
    default         172.17.42.1     0.0.0.0         UG    0      0        0 eth0
    172.17.0.0      *               255.255.0.0     U     0      0        0 eth0

    Therefore, the docker host's IP address 172.17.42.1 is set as the default route and is accessible from your container.

    root@e77f6a1b3740:/# ping 172.17.42.1
    PING 172.17.42.1 (172.17.42.1) 56(84) bytes of data.
    64 bytes from 172.17.42.1: icmp_seq=1 ttl=64 time=0.070 ms
    64 bytes from 172.17.42.1: icmp_seq=2 ttl=64 time=0.201 ms
    64 bytes from 172.17.42.1: icmp_seq=3 ttl=64 time=0.116 ms

    docker run --network="host"

    Alternatively, you can run a Docker container and set the network settings to host. Such a container will share the network stack with the docker host, and from the container's perspective, localhost (or 127.0.0.1) will refer to the docker host. p>

    Please note that any port opened in the docker container will be opened on the docker host. This does not require -p or <代码>-P docker runoption.

    IP configuration on my docker host:

    [vagrant@docker:~] $ 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 docker containers from host mode:

    [vagrant@docker:~] $ docker run --rm -it --network=host ubuntu:trusty 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

    As you can see, the docker host and the docker container share the exact same network interface and therefore have the same IP address.


    Connect to MySQL from container

    Bridge Mode

    To access MySQL running on a docker host from a container in bridge mode, you need to ensure that the MySQL service is listening for connections on the 172.17.42.1 IP address.

    To do this, make sure you have bind-address = 172.17.42.1 or bind-address = 0.0.0.0) in your MySQL configuration file (my.cnf).

    If you need to set environment variables using the IP address of the gateway, you can run the following code in the container:

    export DOCKER_HOST_IP=$(route -n | awk '/UG[ \t]/{print }')

    Then in your application, use the DOCKER_HOST_IP environment variable to open a connection to MySQL.

    NOTE: If you use bind-address = 0.0.0.0, your MySQL server will listen for connections on all network interfaces. This means your MySQL server is accessible from the Internet; make sure to set firewall rules accordingly.

    Note 2: If you use bind-address = 172.17.42.1, your MySQL server will not listen to the one established with 127.0.0.1 Connect>. Processes running on the docker host that want to connect to MySQL must use the 172.17.42.1 IP address.

    Host Mode

    To access MySQL running on a docker host from a container in host mode, you can leave bind-address = 127.0.0.1 in the MySQL configuration and connect to 127.0.0.1 From your container:

    [vagrant@docker:~] $ docker run --rm -it --network=host mysql mysql -h 127.0.0.1 -uroot -p
    Enter password:
    Welcome to the MySQL monitor.  Commands end with ; or \g.
    Your MySQL connection id is 36
    Server version: 5.5.41-0ubuntu0.14.04.1 (Ubuntu)
    
    Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
    
    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>

    Note: Please use mysql -h 127.0.0.1 instead of mysql -h localhost; otherwise the MySQL client will try to use the unix socket Make a connection.

    reply
    0
  • Cancelreply