How to access host port from docker container

I have a docker container in which jenkins work. As part of the build process, I need to access a web server that runs locally on the host machine. Is there a way that a host's web server (which can be configured to work on a port) can be opened to a jenkins container?

EDIT: I run docker natively on a Linux machine.

UPDATE:

In addition to @larsks, answer below to get the host IP address from the host machine, I do the following:

ip addr show docker0 | grep -Po 'inet \K[\d.]+' 
+204
docker docker-container
Jul 09 '15 at 18:01
source share
10 answers

When starting Docker initially on Linux, you can access host services using the IP address of docker0 . From inside the container, this will be your default route.

For example, on my system:

 $ ip addr show docker0 7: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0 valid_lft forever preferred_lft forever inet6 fe80::f4d2:49ff:fedd:28a0/64 scope link valid_lft forever preferred_lft forever 

And inside the container:

 # ip route show default via 172.17.0.1 dev eth0 172.17.0.0/16 dev eth0 src 172.17.0.4 

It's pretty easy to extract this IP address with a simple shell script:

 #!/bin/sh hostip=$(ip route show | awk '/default/ {print $3}') echo $hostip 

You may need to change the iptables rules on your host to allow connections from Docker containers. Something like this will do the trick:

 # iptables -A INPUT -i docker0 -j ACCEPT 

This will allow access to any ports on the host from Docker containers. Note:

  • The iptables rules are ordered, and this rule may or may not do the right thing, depending on what other rules come before it.

  • you can only access host services that either (a) listen to INADDR_ANY (aka 0.0.0.0) or explicitly listen to the docker0 interface.

+157
Jul 09 '15 at 20:54
source share

For macOS and Windows

Docker v 18.03 and higher (since March 21, 2018)

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

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

MacOS with earlier versions of Docker

Docker for Mac v 17.12 to 18.02

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

Docker for Mac from 06/17 - 11/17

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

Docker for Mac 17.05 and below

To access the host machine from the dock container, you must attach an IP alias to your network interface. You can associate any IP address you want, just make sure you are not using it with anything else.

sudo ifconfig lo0 alias 123.123.123.123/24

Then, make sure your server is listening on the IP address mentioned above or 0.0.0.0 . If he listens for localhost 127.0.0.1 he will not accept the connection.

Then just point your dock container to this IP and you will have access to the host machine!

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

The alias will be reset each time you reboot, so create a startup script if necessary.

The solution and additional documentation is here: https://docs.docker.com/docker-for-mac/networking/#use-cases-and-workarounds

+223
Apr 21 '17 at 11:36 on
source share

Use --net="host" in your docker run --net="host" , then localhost in your Docker container will point to your Docker host.

+44
Feb 15 '18 at 12:08
source share

Solution with docker-compose: to access a host-based service, you can use the network_mode parameter https://docs.docker.com/compose/compose-file/#network_mode

 version: '3' services: jenkins: network_mode: host 
+15
Jun 14 '18 at 21:11
source share

Currently, the easiest way to do this on Mac and Windows is to use host host.docker.internal , which resolves the IP address of the host machine. Unfortunately, it does not work on Linux (as of April 2018).

+9
Apr 20 '18 at 19:47
source share

I created a Docker container to do just that https://github.com/qoomon/docker-host

Then you can simply use the dns container name to access the host system, for example curl http://dockerhost:9200

+6
Aug 6 '18 at 8:36
source share

We found that a simpler solution for all this network junk is to use a domain socket for the service. If you are still trying to connect to the host, just mount the socket as a volume and you are on the way. For postgresql, it was so simple:

 docker run -v /var/run/postgresql:/var/run/postgresql 

Then we just set up a connection to our database to use a socket instead of a network. Literally so simple.

+6
May 7 '19 at 17:19
source share

You can access the local web server that runs on your host computer in two ways.

  1. Approach 1 with public IP

    Use the public IP address of the host machine to access the web server in the Jenkins dock container.

  2. Host 2 Approach

    Use "--net host" to add the Jenkins dock container to the host network stack. Containers deployed on the host stack have full access to the host interface. You can access the local web server in the Docker container with the private IP address of the host machine.

 NETWORK ID NAME DRIVER SCOPE b3554ea51ca3 bridge bridge local 2f0d6d6fdd88 host host local b9c2a4bc23b2 none null local 

Run the container with the host network. Eg: docker run --net host -it ubuntu and run ifconfig to get a list of all available network IP addresses available from the dock container.

For example: I started the nginx server on my local host machine and was able to access the nginx website URLs from the Ubuntu dock container.

docker run --net host -it ubuntu

 $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a604f7af5e36 ubuntu "/bin/bash" 22 seconds ago Up 20 seconds ubuntu_server 

Access to the Nginx web server (running on the local host) from the Ubuntu dock container with the IP address of the private network.

 root@linuxkit-025000000001:/# curl 192.168.xx -I HTTP/1.1 200 OK Server: nginx/1.15.10 Date: Tue, 09 Apr 2019 05:12:12 GMT Content-Type: text/html Content-Length: 612 Last-Modified: Tue, 26 Mar 2019 14:04:38 GMT Connection: keep-alive ETag: "5c9a3176-264" Accept-Ranges: bytes 
+2
Apr 09 '19 at 5:47
source share

I studied various solutions and found this least hacky solution:

  1. Define a static IP address for the bridge gateway IP address.
  2. Add the IP address of the gateway as an extra entry to the extra_hosts directive.

The only drawback is that if you have several networks or projects, you must make sure that their range of IP addresses does not conflict.

Here is an example of a Docker Compose:

 version: '2.3' services: redis: image: "redis" extra_hosts: - "dockerhost:172.20.0.1" networks: default: ipam: driver: default config: - subnet: 172.20.0.0/16 gateway: 172.20.0.1 

You can then access the ports on the host from the container using the host name "dockerhost".

+1
Sep 06 '18 at 14:09
source share

When you have two docker images that are already created, and you want to link the two containers to each other.

To do this, you can conveniently launch each container with its own name and use the -link flag to ensure communication between them. You will not get this while building dockers.

When you are in a scenario like me and this is yours

 docker build -t "centos7/someApp" someApp/ 

It breaks when you try

 curl http://172.17.0.1:localPort/fileIWouldLikeToDownload.tar.gz > dump.tar.gz 

and you are stuck on "curl / wget" not returning "host route".

The reason is the security installed in place by the docker, which by default prohibits communication with the container in relation to the host or other containers running on your host. It was rather unexpected for me, I have to say, you expect that the echo systems of docker machines running on the local machine can simply perfectly access each other without any special obstacles.

An explanation of this is described in detail in the following documentation.

http://www.dedoimedo.com/computers/docker-networking.html

Two quick workarounds are provided to help you move around, reducing network security.

The easiest alternative is to simply disable the firewall - or allow it all. This means that you need to execute the necessary command, which can be stopped at the system stop firewalld, iptables -F or equivalent.

We hope this information helps you.

0
Nov 16 '16 at 21:47
source share



All Articles