As the title says. I need to be able to retrieve the IP address the docker hosts and the portmaps from the host to the container, and doing that inside of the container.
问题:
回答1:
/sbin/ip route|awk \'/default/ { print $3 }\'
As @MichaelNeale noticed, there is no sense to use this method in Dockerfile
(except when we need this IP during build time only), because this IP will be hardcoded during build time.
回答2:
On Docker for Mac, as of version 18.03, you can use host.docker.internal
as the host\'s IP.
Note, as in the documentation, \"This is for development purpose[s] and will not work in a production environment outside of Docker for Mac.\" This is because, in Docker for Mac, \"you cannot see a docker0 interface on the host. This interface is actually within the virtual machine.\"
This is an update from docker.for.mac.localhost
, available since version 17.06, and docker.for.mac.host.internal
, available since version 17.12, which may also still work.
For example, I have environment variables set on my host:
MONGO_SERVER=host.docker.internal
In my docker-compose.yml
file, I have this:
version: \'3\'
services:
api:
build: ./api
volumes:
- ./api:/usr/src/app:ro
ports:
- \"8000\"
environment:
- MONGO_SERVER
command: /usr/local/bin/gunicorn -c /usr/src/app/gunicorn_config.py -w 1 -b :8000 wsgi
回答3:
Update: On Docker for Mac, as of version 18.03, you can use host.docker.internal as the host\'s IP. See allanberry\'s answer. For prior versions of Docker for Mac the following answer may still be useful:
On Docker for Mac the docker0
bridge does not exist, so other answers here may not work. All outgoing traffic however, is routed through your parent host, so as long as you try to connect to an IP it recognizes as itself (and the docker container doesn\'t think is itself) you should be able to connect. For example if you run this from the parent machine run:
ipconfig getifaddr en0
This should show you the IP of your Mac on its current network and your docker container should be able to connect to this address as well. This is of course a pain if this IP address ever changes, but you can add a custom loopback IP to your Mac that the container doesn\'t think is itself by doing something like this on the parent machine:
sudo ifconfig lo0 alias 192.168.46.49
You can then test the connection from within the docker container with telnet. In my case I wanted to connect to a remote xdebug server:
telnet 192.168.46.49 9000
Now when traffic comes into your Mac addressed for 192.168.46.49 (and all the traffic leaving your container does go through your Mac) your Mac will assume that IP is itself. When you are finish using this IP, you can remove the loopback alias like this:
sudo ifconfig lo0 -alias 192.168.46.49
One thing to be careful about is that the docker container won\'t send traffic to the parent host if it thinks the traffic\'s destination is itself. So check the loopback interface inside the container if you have trouble:
sudo ip addr show lo
In my case, this showed inet 127.0.0.1/8
which means I couldn\'t use any IPs in the 127.*
range. That\'s why I used 192.168.*
in the example above. Make sure the IP you use doesn\'t conflict with something on your own network.
回答4:
For those running Docker in AWS, the instance meta-data for the host is still available from inside the container.
curl http://169.254.169.254/latest/meta-data/local-ipv4
For example:
$ docker run alpine /bin/sh -c \"apk update ; apk add curl ; curl -s http://169.254.169.254/latest/meta-data/local-ipv4 ; echo\"
fetch http://dl-cdn.alpinelinux.org/alpine/v3.3/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.3/community/x86_64/APKINDEX.tar.gz
v3.3.1-119-gb247c0a [http://dl-cdn.alpinelinux.org/alpine/v3.3/main]
v3.3.1-59-g48b0368 [http://dl-cdn.alpinelinux.org/alpine/v3.3/community]
OK: 5855 distinct packages available
(1/4) Installing openssl (1.0.2g-r0)
(2/4) Installing ca-certificates (20160104-r2)
(3/4) Installing libssh2 (1.6.0-r1)
(4/4) Installing curl (7.47.0-r0)
Executing busybox-1.24.1-r7.trigger
Executing ca-certificates-20160104-r2.trigger
OK: 7 MiB in 15 packages
172.31.27.238
$ ifconfig eth0 | grep -oP \'inet addr:\\K\\S+\'
172.31.27.238
回答5:
The only way is passing the host information as environment when you create a container
run --env <key>=<value>
回答6:
The --add-host
could be a more cleaner solution (but without the port part, only the host can be handled with this solution). So, in your docker run
command, do something like:
docker run --add-host dockerhost:`/sbin/ip route|awk \'/default/ { print $3}\'` [my container]
(From https://stackoverflow.com/a/26864854/127400 )
回答7:
Docker for Mac 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. https://docs.docker.com/docker-for-mac/networking/#use-cases-and-workarounds
回答8:
If you enabled the docker remote API (via -H
tcp://0.0.0.0:4243
for instance) and know the host machine\'s hostname or IP address this can be done with a lot of bash.
Within my container\'s user\'s bashrc
:
export hostIP=$(ip r | awk \'/default/{print $3}\')
export containerID=$(awk -F/ \'/docker/{print $NF;exit;}\' /proc/self/cgroup)
export proxyPort=$(
curl -s http://$hostIP:4243/containers/$containerID/json |
node -pe \'JSON.parse(require(\"fs\").readFileSync(\"/dev/stdin\").toString()).NetworkSettings.Ports[\"DESIRED_PORT/tcp\"][0].HostPort\'
)
The second line grabs the container ID from your local /proc/self/cgroup
file.
Third line curls out to the host machine (assuming you\'re using 4243 as docker\'s port) then uses node to parse the returned JSON for the DESIRED_PORT
.
回答9:
Here is another option for those running Docker in AWS. This option avoids having using apk to add the curl package and saves the precious 7mb of space. Use the built-in wget (part of the monolithic BusyBox binary):
wget -q -O - http://169.254.169.254/latest/meta-data/local-ipv4
回答10:
In linux you can run
HOST_IP=`hostname -I | awk \'{print $1}\'`
In macOS your host machine is not the Docker host. Docker will install it\'s host OS in VirtualBox.
HOST_IP=`docker run busybox ping -c 1 docker.for.mac.localhost | awk \'FNR==2 {print $4}\' | sed s\'/.$//\'`
回答11:
If you want real IP
address (not a bridge IP
) on Windows
and you have docker 18.03
(or more recent) do the following:
Run bash on container from host where image name is nginx
(works on Alpine Linux distribution
):
docker run -it nginx /bin/ash
Then run inside container
/ # nslookup host.docker.internal
Name: host.docker.internal
Address 1: 192.168.65.2
192.168.65.2
is the host\'s IP - not the bridge IP like in spinus
accepted answer.
I am using here host.docker.internal:
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. This is for development purpose and will not work in a production environment outside of Docker for Windows.
回答12:
If you are running a Windows container on a Service Fabric cluster, the host\'s IP address is available via the environment variable Fabric_NodeIPOrFQDN
. Service Fabric environment variables
回答13:
Here is how I do it. In this case, it adds a hosts entry into /etc/hosts within the docker image pointing taurus-host to my local machine IP: :
TAURUS_HOST=`ipconfig getifaddr en0`
docker run -it --rm -e MY_ENVIRONMENT=\'local\' --add-host \"taurus-host:${TAURUS_HOST}\" ...
Then, from within Docker container, script can use host name taurus-host to get out to my local machine which hosts the docker container.
回答14:
Maybe the container I\'ve created is useful as well https://github.com/qoomon/docker-host
You can simply use container name dns to access host system e.g. curl http://dockerhost:9200, so no need to hassle with any IP address.
回答15:
With https://docs.docker.com/machine/install-machine/
a) $ docker-machine ip
b) Get the IP address of one or more machines.
$ docker-machine ip host_name
$ docker-machine ip host_name1 host_name2