I am using Docker for Mac. I am running a nodejs based microservice in a Docker container. I want to test node microservice through the browser. How to get IP address of running docker container?
If you don't want to map ports from your host to the container you can access directly to the docker range ip for the container. This range is by default only accessed from your host. You can check your container network data doing:
docker inspect <containerNameOrId>
Probably is better to filter:
docker inspect <containerNameOrId> | grep '"IPAddress"' | head -n 1
Usually, the default docker ip range is 172.17.0.0/16. Your host should be 172.17.0.1 and your first container should be 172.17.0.2 if everything is normal and you didn't specify any special network options.
EDIT
Another more elegant way using docker features instead of "bash tricking":
docker inspect -f "{{ .NetworkSettings.IPAddress }}" <containerNameOrId>
EDIT2
For modern docker engines, now it is this way (thanks to the commenters!):
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <containerNameOrId>
Use --format option to get only the IP address instead whole container info:
sudo docker inspect --format '{{ .NetworkSettings.IPAddress }}' <CONTAINER ID>
For modern docker engines use this command :
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container_name_or_id
and for older engines use :
docker inspect --format '{{ .NetworkSettings.IPAddress }}' container_name_or_id
if you want to obtain it right within the container, you can try
ip a | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" | grep 172.17
You can start your container with the flag -P. This "assigns" a random port to the exposed port of your image.
With docker port <container id> you can see the randomly choosen port. Access is then possible via localhost:port.
For my case, below worked on Mac:
I could not access container IPs directly on Mac. I need to use localhost with port forwarding, e.g. if the port is 8000, then http://localhost:8000
See https://docs.docker.com/docker-for-mac/networking/#known-limitations-use-cases-and-workarounds
The original answer was from: https://github.com/docker/for-mac/issues/2670#issuecomment-371249949
If you want to view the IP address from within the running container, /etc/hosts file is a great place to look at. Now, to uniquely identify the entry within the hosts file, it is a good practise to run the container with the -h option. Sample commands are given below:
Run the container with -h set:
docker run -td -h guju <image name>
Log in to the running container and view the /etc/hosts file. It will show an entry like this:
172.17.0.5 guju
this will list all containers' IP addresses
while read ctr;do
sudo docker inspect --format "$ctr "'{{.Name}}{{ .NetworkSettings.IPAddress }}' $ctr
done < <(docker ps -a --filter status=running --format '{{.ID}}')
You can not access the docker's IP from outside of that host machine.
If your browser is on another machine better to map the host port to container port by passing -p 8080:8080 to run command.
Passing -p you can map host port to container port and a proxy is set to forward all traffix for said host port to designated container port.
Related
On my windows laptop I have created a Play application which runs fine if I execute its scripts directly. On the local machine, I access the application using localhost:9000 URL.
I have now created a Docker image of the application and have exposed port 9000
#this docker file copies prod specific files to container, eg logback_prod.xml and application_prod.conf
FROM openjdk:8
#ENV APP_NAME myapp
#ENV APP_VERSION 1.0-SNAPSHOT
...
#entrypoint is deploy/....
EXPOSE 9000
ENTRYPOINT ...
But I can't access the application on localhost:9000. I suspect that the image might be running on some other IP created by docker itself.
Am I correct? How can I access my application through the container? I don't need Kubernetes Services etc. as I already have that setup on another machine. My specific question is how to access the docker container directly.
UPDATE
I also tried running the docker image using --network="host" but that doesn't work either
UPDATE 2
Based on the suggestions below, I executed the following commands but still can't access the application.
docker run -p 9000:9000 --env-file env.txt imagename
I see the trace
[debug] a.i.TcpListener - Successfully bound to /0.0.0.0:9000
[info] p.c.s.AkkaHttpServer - Listening for HTTP on /0.0.0.0:9000
docker ps -a shows application is up with port binding 0.0.0.0:9000->9000/tcp
docker inspect shows IP - "IPAddress": "172.17.0.2"
but http://172.17.0.2:9000/ on Chrome doesn't work This site can’t be reached172.17.0.2
netstat -ab on cmd shows TCP 0.0.0.0:9000 LAPTOP-788I0GL1:0 LISTENING [com.docker.backend.exe]
Identify container's IP Address
Try these options with a running container.
<docker> refers to container's name or id
docker inspect --format '{{ .NetworkSettings.IPAddress }}' <docker>
//WINDOWS ONLY
docker inspect --format "{{ .NetworkSettings.IPAddress }}" <docker>
docker inspect <docker> | grep "IPAddress"
Grep not avaliable on Windows*
docker network inspect bridge
This last one would output all running containers' info that are allocated in the bridge network (default). Once identified, check the container's IPv4Address field.
Expose ports
In order to be able to connect to the a container's port, you could expose it. Note that the previous step is not needed in this case:
docker run -p 9000:9000 --env-file env.txt manuchadha25/mydockerimage
By default the docker will bind/listen to all interfaces on the host. The -p 9000:9000 option exposes the port, and as a result you get: 0.0.0.0:9000->9000/tcp
Now localhost:9000 succesfully connects to your docker process.
You can try the command docker inspect:
docker inspect <containerid>
for list the containers ids you can run the command:
docker ps
In order to get the ipAddress information you should look to node:
"IPAddress": "172.23.0.2"
In the json output produced.
Here is the documentation for docker inspect command.
I have a collection of IPv4 traffic recorded by tcpdump, and I am interested in mapping a given outgoing connection to its origin Docker container on the same machine. I can view the TCP source port, but it is unclear to me how to ask Docker which container is using this port. How can this be done?
Thanks
You can filter containers which publish or expose a given port:
docker ps --filter=expose=3306
or use the format switch to get a list of container IDs with the used ports:
docker ps --format "{{.ID}}: {{.Ports}}"
I had this exact problem where I wanted to know which container was the client for a particular Postgresql database query. These are the steps I took to find the container that was the source of the TCP connection I was interested in.
In postgres query pg_stat_activity to determine the client_addr and client_port of the query you care about:
SELECT * FROM pg_stat_activity;
Now you know the source ip (client_addr) you can ssh to this box and determine the network interface used by docker:
ip addr
In my case it was docker0. Now we can use the source port of the database connection (client_port) to find the container ip address:
tcpdump -i docker0 src port 52282
02:41:16.257106 IP 172.17.0.15.52282 > 192.168.2.119.postgres: Flags [P.] ...
Now we need to work out which container this source ip (172.17.0.15) belongs to, to do this we can use the docker inspect command with a filter:
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container
We run this command in a loop for each of the running containers and grep for the ip we are looking for:
for name in $( docker ps --format '{{.Names}}' ); do echo -n "$name => " && docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $name; done | grep 172.17.0.15
my-container => 172.17.0.15
Now we know that the container my-container is the source of the traffic we are interested in.
Is there a way to have docker automatically give it’s containers a local IP address that you can reach with it’s ports exposed?
For example, LXC has ways to do this.
lxc-create -t ubuntu -n myname
lxc-start -n myname -d
Which will then assign a local IP which you can see via lxc-ls if you have a bridge configured:
lxc-ls -f
This is super convenient for throwing up a bunch of containers for testing out deployment/configuration management like ansible.
Is it possible to do something similar in docker without much headache? I come from using LXC and I’m not familiar with the networking modes.
LXC and Docker are very similar. When LXC is installed, a random subnet is picked for configuring the IP addresses of bridge and the containers attached to it. With Docker, the default subnet is 172.17.0.0/16, which can be customized if needed. Every container stared (unless using host network or network of another container) using docker run command are assigned an IP address from the above subnet.
docker ps lists all the containers running but unfortunately it doesn't show the IP addresses.
Looks like a small trick can show the IP addresses: (based on this post)
docker ps -q | xargs docker inspect --format '{{ .Id }} - {{ .Name }} - {{ .NetworkSettings.IPAddress }}'
Also you can expose the ports using the -p option of docker run command.
Example:
docker run -itd -p 8080:80 nginx
This starts the container on the docker bridge and also exposes the nginx on the host network via port 8080.
from_host_running_container# curl http://172.17.x.y
from_not_the_host_running_container # curl http://${HOST_IP}:8080
Is there a way to know the IP address of a CentOS host machine inside the docker container inside which the container is running? Like say if I have a linux machine 10.10.10.10 IP that has docker container1 and container2 running, I would want to query the IP from my java code. The Java code is inside the docker container. I am actually running these services as a docker swarm.
Docker is about isolating the container from the host.
So, in theory, the container should not be aware fo this IP address, unless the host "gives" it to the container
Some ideas
In an environment variable at run time
either
docker run -e "host_IP=10.10.10.10"...
or in a file my_env containing
host_IP 10.10.10.10 and use it in
docker run --env-file my_env
see the doc
https://docs.docker.com/engine/reference/commandline/run/#set-environment-variables--e---env---env-file
in an environment variable at build time
have in your Dockerfile a line
ENV host_IP 10.10.10.10
the doc
https://docs.docker.com/engine/reference/builder/#env
you can share /etc/hosts between the host and the container with
docker run -v /etc/hosts:/etc/hosts ...
You can use the following netstat command to find the host ip from inside a container:
netstat -nr | grep '^0.0.0.0' | awk '{print $2}'
I have three docker containers,
java container (JC): for my java application (spring boot)
elasticsearch container (EC): for ElasticSearch
test container (TC): testing container to troubleshoot with ping test
Currently, the JC cannot see the EC by "name". And when I say "see" I mean if I do a ping on the JC to EC, I get a ping: unknown host. Interestingly, if I do a ping on the TC to EC, I do get a response.
Here is how I start the containers.
docker run -dit --name JC myapp-image
docker run -d --name EC elasticsearch:1.5.2 elasticsearch -Des.cluster.name=es
docker run --rm --name TC -it busybox:latest
Then, to ping EC from JC, I issue the following commands.
docker exec JC ping -c 2 EC
I get a ping: unknown host
With the TC, since I am already at the shell, I can just do a ping -c 2 EC and I get 2 replies.
I thought maybe this had something to do with my Java application, but I doubt it because I modified my Dockerfile to just stand up the container. The Dockerfile looks like the following.
FROM java:8
VOLUME /tmp
Note that you can create the above docker image by docker build -no-cache -t myapp-image ..
Also note that I have Docker Weave Net installed, and this does not seem to help getting the JC to see the EC by name. On the other hand, I tried to find the IP address of each container as follows.
docker inspect -f '{{ .NetworkSettings.IPAddress }}' JC --> 172.17.0.4
docker inspect -f '{{ .NetworkSettings.IPAddress }}' EC --> 172.17.0.2
docker inspect -f '{{ .NetworkSettings.IPAddress }}' TC --> 172.17.0.3
I can certainly ping EC from JC by IP address: docker exec JC ping -c 2 172.17.0.2. But getting the containers to see each other by IP address does not help as my Java application needs a hostname reference as a part of its configuration.
Any ideas on what's going on? Is it the container images themselves? Why would the busybox container image be able to ping the ElasticSearch container by name but the java container not?
Some more information.
VirtualBox 5.0.10
Docker 1.9.1
Weave 1.4.0
CentOS 7.1.1503
I am running docker inside a CentOS VM on a Windows 10 desktop as a staging environment before deployment to AWS
Any help is appreciated.
Within the same docker daemon, use the old --link option in order to update the /etc/hosts of each component and make sure one can ping the other:
docker run -d --name EC elasticsearch:1.5.2 elasticsearch -Des.cluster.name=es
docker run -dit --name JC --link ED myapp-image
docker run --rm --name TC -it busybox:latest
Then, a docker exec JC ping -c 2 EC should work.
If it does not, check if this isn't because of the base image and a security issue: see "Addressing Problems with Ping in Containers on Atomic Hosts".
JC is based on docker/_java:8, itself based on jessie-curl, jessie.
Containers in this default network are able to communicate with each other using IP addresses. Docker does not support automatic service discovery on the default bridge network. If you want to communicate with container names in this default bridge network, you must connect the containers via the legacy docker run --link option. docs.docker.org.
It should also work using the new networking.
docker network create -d bridge non-default
docker run --net non-default ...
There isn't a specific option which applies this behavior to the default network (AFAICT from looking at docker network inspect). I guess it's just triggered by the option "com.docker.network.bridge.default_bridge".
In the first part of another question, it's suggested this was changed in Docker 1.9. Note that Docker 1.9 was when they turned on the new networking system in the stable release. The section of the userguide that I quoted from above, did not exist in version 1.8. Docker 1.9.0 "bridge" versus a custom bridge network results in difference in hosts file and SSH_CLIENT env variable