How to access Docker container's web server from host - docker

I'm running under boot2docker 1.3.1.
I have a Docker container running a web server via uwsgi --http :8080.
If I attach to the container I can browse the web site using lynx http://127.0.0.1:8080 so I know the server is working.
I ran my container with:
$ docker run -itP --expose 8080 uwsgi_app:0.2
It has the following details:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5248ad86596d uwsgi_app:0.2 "bash" 11 minutes ago Up 11 minutes 0.0.0.0:49159->8080/tcp cocky_hypatia
$ docker inspect --format '{{ .NetworkSettings.IPAddress }}' 5248ad86596d
172.17.0.107
I thought I could access that web site from my host by going to http://172.17.0.107:49159.
This does not work. I just see 'connecting...' in Chrome, getting nowhere.
What am I doing wrong?

Extending Anentropic's answer: boot2docker is the old app for Mac and Windows, docker-machine is the new one.
Firstly, list your machines:
$ docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM
default * virtualbox Running tcp://192.168.99.100:2376
Then select one of the machines (the default one is called default) and:
$ docker-machine ip default
192.168.99.100

Ok, stupid me, I found the answer in the docs for boot2docker
https://docs.docker.com/installation/mac/#container-port-redirection
I needed to use the ip address of the boot2docker vm, rather than the ip of the container, i.e.
$ boot2docker ip
192.168.59.103
and I am able to browse my site from the host at http://192.168.59.103:49159/
I did not need to add any route on the host

To find the IP address of your container, you should need NO additional installs:
docker inspect <container>
This provides a wealth of info. grep it for the IPAddress.

You could use boot2docker port mapping option -L, as described here.
So, in your case it would be
boot2docker ssh -L 0.0.0.0:8080:localhost:8080
and then
docker run -it -p 8080:8080 uwsgi_app:0.2
That way, you do not have to use boot2docker's IP address: you can use localhost or your own IP address (and your docker container can be accessed from outside).

Boot2docker is outdated, but you may still have this problem on Docker for Windows or Mac, even though the same container works on Linux. One symptom is that trying to access a page on the server inside the container gives the error "didn't send any data" as opposed to "could not connect."
If so, it may be because on Win/Mac the container host has its own IP, it's not localhost as it is on linux. Try running Django on IP 0.0.0.0, meaning accept connections from all IPs, like this:
python manage.py runserver 0.0.0.0:8000
Alternatively, if you need to make sure the server only responds to local requests (such as from your local proxy like nginx, apache, or gunicorn) you can use the host IP returned by hostname -i.
And make sure you are using the -p port forwarding option correctly in the docker run command.
Assuming all is well, you should be able to access your server at http://localhost in a browser running on the host machine.

docker build -t {imagename} .
docker build -t api-rest-test .
docker run -dp {localport}:{exposeport} image:name
docker run -dp 8080:8080 api-rest-test:latest
make sure you are using the same port for yourlocalport and exposeport
then you can access your rest service in your local machine http://localhost:8080

[EDIT: original version was ignoring the -P in question]
If you want to get to the containers without having to 'publish' the port (which changes its number)
there is a good run-through here.
The key is this line:
sudo route -n add 172.17.0.0/16 172.16.0.11
which tells the Mac how to route to the private network inside the VirtualBox VM that the Docker containers are on.

Had the same issue and in my case i was using AWS EC2 instance. I was trying with the container IP which did not work. Then I used the actual public IP of the AWS host as the IP, which worked.

How to troubleshoot the issue on hosting application on local host browser
For this launch the container with below command, in my case it was:
[root#centoslab3 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1b81d8a0e3e1 centos:baseweb "/bin/bash" 8 minutes ago Exited (0) 24 seconds ago webtest
[root#centoslab3 ~]# docker run --name=atul -v /root/dockertest:/var/www/html -i -t -p 5000:8000 centos:baseweb /bin/bash
In the httpd configuration:
[root#adb28b08c9ed /]# cd /etc/httpd/conf
[root#adb28b08c9ed conf]# ll
total 52
-rw-r--r--. 1 root root 34419 Sep 19 15:16 httpd.conf
edit the file with the port 8000 in listner and update the container ip and port under Servername.
Restart the httpd service and you are done.
Hope this helps

Related

Docker desktop for windows: Can't access my container via the browser

I'm trying to run httpd container
The ip address is 172.17.0.2 (I'm sure of it cause I've ran docker container inspect <container_name>) and I the port is 4400 and when I run the container can't access it via the browser on this address http://172.17.0.2:4400 !
I've tried to disable the firewall but still the same problem.
This is how I started it:
docker container run -d -p 4400:8080 httpd
This is what docker container ls give me
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e9f92cfceb76 httpd "httpd-foreground" 24 minutes ago Up 13 minutes 80/tcp, 0.0.0.0:4400->8080/tcp interesting_wright
What am I missing ?
The problem was with wamp
when I disabled it I was able to access the container via http://localhost:4400
docker run -dit --name my-apache-app -p 4400:80 -v "$PWD":/usr/local/apache2/htdocs/ httpd:2.4
And then user your localhost + that port, and/or the LAN IP + that port.
Reference: https://hub.docker.com/_/httpd
I also was facing the same problem in windows with XAMPP installed
I resolved it by modifying the hosts file
/c/Windows/System32/drivers/etc
Just comment on the xampp IP and in this file you can also see the docker internal IP use it to access the application inside the container

Map container to hostname other than localhost in Docker for Mac

I am creating an Nginx container that I would like to access locally at http://api. Using Docker Machine, I assumed running docker-machine create default and docker-machine ip default to receive the IP and editing my hosts file to something like this:
# docker-machine ip default --> 192.168.99.100
192.168.99.100 api
should map requests to api\ to the Docker Machine IP and serve my content.
Two things are confusing me:
I launch Docker through the Mac App and can create Nginx containers and access content at http://localhost. However, running docker-machine ls returns no machines. This is confusing because I thought Docker had to run on a VM.
Starting from scratch and starting Docker Machine, then spinning up containers seems to have no effect. In other words, I still can access content at http://localhost but not http://api
Instead of accessing my container at http://localhost I want to access it at http://api. How do I do this?
I'm using Docker for Mac 17.12 and Docker Machine 0.14.
On the base of your this question:
Instead of accessing my container at http://localhost I want to access
it at http://api. How do I do this?
Your docker run command:
docker run -it --rm --name test --add-host api:192.168.43.8 -p 80:80 apachehttpd
1st Thing: The --add-host flag add value to /etc/hosts in your container /etc/hosts so http://api will also response inside the container if ping inside that container.
This is how will ping response inside container
2nd Thing: Edit your host etc/hosts file and add
api 192.168.43.8 [your ip]
This is how you can see in Browser.

How to identify the docker host ip to use when running a jenkins container

I have docker machine installed on windows OS and have pulled in Jenkins image from docker hub. I then run the below commands:
docker volume created myjenkins-data
docker run -p 8080:8080 -p 50000:50000 -v myjenkins-data:/var/jenkins_home jenkins
I received the admin key for Jenkins in the logs. I've confirmed that my container is still running status:
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2854c7d83879 jenkins "/bin/tini -- /usr..." About a minute ago Up About a minute 0.0.0.0:8080->8080/tcp, 0.0.0.0:50000->50000/tcp quizzical_cray
Now, I need to log into 8080 port to view the Jenkins web app. But I do not know which host ip to use. I identified the docker host ip with the command "docker-machine ip" and got the ip address: 192.168.99.100. But using 192.168.99.100:8080 did not bring up Jenkins app. I also tried using docker inspect to get the container's ip, but port 8080 didn't work on those ips as well. Which ip address do i use to see the Jenkins app that is running in the container?
First, double-check if http://localhost:8080 is not enough.
Hyper-V (through vpnkit, if you are using Docker for Windows) should have done the port-forwarding for you.
If you are using the legacy docker toolbox (VirtualBox), then you need port-forwarding (issue 4115).

Can't access service running in docker

I'm unable to access a nodejs based service via http://localhost:8000 running in a docker image. I'm using Docker for Mac (https://docs.docker.com/docker-for-mac/)
I'm following the tutorial here https://nodejs.org/en/docs/guides/nodejs-docker-webapp/.
The server runs on port 8000. I start the docker image with the following:
$ docker run -p 8000:8000 -d geuis/node-server:latest
If I run docker ps I see:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9fa2e446918b geuis/node-server:latest "npm start" 6 seconds ago Up 5 seconds 0.0.0.0:8000->8000/tcp unruffled_lewin
If I docker exec -it 9fa2e446918b /bin/bash I can access the docker vm and I can curl http://localhost:8000 and access the server from inside the container.
However, I try the same curl http://localhost:8000 from my system terminal and its not accessible.
Not sure what I need to do next.
Try the following listen statement:
app.listen(PORT, '0.0.0.0');
From reading the tutorial you mention it looks like express is listening on localhost. This is fine if you're running locally but inside of a container, localhost is not the same localhost that's outside of the container.
0.0.0.0 is the unspecified IPv4 address and so Express will bind on any IP it can find, which will be the IP that your requests are coming in from outside the container.

Obtaining the ip address of a docker container

I have a ubuntu machine which is a VM where I have installed docker in it. I am using this machine from my local windows machine and doing ssh , opening the terminal to the ubuntu machine.
Now , I am going to take a docker image which contains all the necessary softwares for eg: apache installed in it. Later I am going to deploy a sample appication(which is a web applicationP on to it and save it .
Now , I am in a confused mode as in how to check the deployed application if its running properly. i.e., what would be the address of the container which containds the deployed application.
for eg:- If I type http://127.x.x.x which is the address of the ubuntu machine , I am just getting time out .
Can anyone tell me how to verify the deployed application . Also, the printing the output of the program on the console works seemlessly fine , as the output gets printed , only thing I have some doubts is regarding the web application.
There are some possibilities to check whether your app is running.
Remote API
As JimiDini said, one possibility is the Docker remote API. You can use it to see all running containers (which would be your use case, right?), inspect a certain container or start and stop containers. The API is a REST-API with several binding for programming languages (at https://docs.docker.io/reference/api/remote_api_client_libraries/). Some of them are very outdated. To use the Docker remote API from another machine, I needed to open it explicitly:
docker -H tcp://0.0.0.0:4243 -H unix:///var/run/docker.sock -d &
Note that the API is open to the world now! In a real scenario you would need to secure it in some way (e.g. see the example at http://java.dzone.com/articles/securing-docker%E2%80%99s-remote-api).
Docker PS
To see all running containers run docker ps on your host. This will list all running containers. If you do not see your app, it is not running. It also shows you the ports your app is exposing. You can also do this via the remote API.
Logs
You can also check the logs. You can run docker attach <container id> to attach to a certain container an see its stdout. You can run also run docker logs <container id> to receive the Docker logs. What I prefer is to write the logs to a certain directory, e.g. all logs to /var/log and mount this folder to my host machine. Then all your logs will end up in /home/ubuntu/docker-logs on your host.
docker run -p 80:8080 -v /home/ubuntu/docker-logs:/var/log:rw my/application
One word to ports and IP
Every container will get its own IP address. You can check this IP address via the remote API or via Docker on the host machine directly. You can also specify a certain host name for the container (by passing the --hostname="test42" to the run command). However, you mostly did not need that.
To access the application in the container, you need to open the port in the container and bind to a port on the host.
In your Dockerfile you need to EXPOSE the port your app runs on:
FROM ubuntu
...
EXPOSE 8080
CMD run-my-app.sh
When you start your container, you need to bind this port to a port of the host:
docker run -p 80:8080 my/application
Now you can access your app on http://localhost:80 or http://127.0.0.1:80.
If you app does not response, check if the container is running by typing docker ps or the remote API. If it is not running, check the logs for the reason.
(Note: If you run your Ubuntu VM in something like VirtualBox and you try to access it from your Windows machine, make sure you opened the ports in VirtualBox too!).
Docker container has a separate IP address. By default it is private (accessible only from the host-machine).
Docker provides all metadata (including IP address) via its API:
https://docs.docker.io/reference/api/docker_remote_api_v1.10/#inspect-a-container
https://docs.docker.io/reference/api/docker_remote_api_v1.10/#monitor-docker-s-events
You can also take a look at a little tool called docker-gen for inspiration. It monitors docker-events and created configuration-files on host machine using templates.
To obtain the ip address of a docker container, if you know its id (a long hex string) or if you named it:
docker inspect --format '{{ .NetworkSettings.IPAddress }}' <container-id-or-name>
Docker is running its own network and to get information about it you can run the following commands:
docker network ls
docker network inspect <network name>
docker inspect <container id>
In the output, you should be able to find the IP.
But there is also a couple of things you need to be aware of, regarding Dockerfile and docker run command:
when you EXPOSE a port in Dockerfile, the service in the container is not accessible from outside Docker, but from inside other Docker containers
and when you EXPOSE and use docker run -p ... flag, the service in the container is accessible from anywhere, even outside Docker
So for example, if your apache is running on port 8080 you should expose it in Dockerfile and then you can run it as:
docker run -d -p 8080:8080 <image name> and you should be able to access it from your host on HTTP://localhost:8080.
It is an old question/answer but it might help somebody else ;)
working as of 2020
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container_name_or_id

Resources