How to access webserver running on localhost from a docker container on a network? - macos

I have the following system configuration:
Docker container running on user defined network
docker-machine (with VirtualBox on OS:X forwarding port 9000 to 9000)
Local webserver running on http://localhost:9000
I do not know how to make a basic http request against this webserver, from within my docker container.
To test this I am using:
docker exec testcontainer curl --data "foobaz=foo" http://{hostname}:9000/
where I have tried, for hostnames:
'localhost'
'127.0.0.1'
'192.168.99.100' (docker-machine IP)
Each time I receive errors or timeouts. When I run the curl command locally (not in docker and on my host OS:X machine) I am able to successfully post the http request.
I cannot disconnect the docker container from my user-defined network. I also cannot add my webserver to that network, as it is not running in a container. Also, I know it is trivial to connect the other way (curl to a webserver running in a docker container) but this is not my use case.
How can I successfully route that http request from the docker container which is part of a user defined network to my localhost webserver?

You can do this with the actual IP address of your local computer.
So for example, if your en0 IP is 10.100.20.32 on your host OS, you can run:
docker exec testcontainer curl --data "foobaz=foo" http://10.100.20.32:9000/
which will successfully allow you to make the http requests.
Note that if you are doing this from a container on the host docker network, this is trivial, as you can directly access localhost or 0.0.0.0 without having to use the actual machine IP.

You might want to check what the IP address of the container is - you can find this out by running docker inspect.
However, if you want to access the server process running in your container using the docker machine IP, then you should "expose" port 9000 that your contained app is listening on (using Dockerfile) - in this way, you will still need to figure out which port the 9000 container port is mapped to (this shows when you list your containers via $ docker ps. You can also specify port binding option in command line when starting your container like this: $ docker run -p 9000:9000 <your-container>.

Related

Localhost vs 0.0.0.0 with Docker on Mac OS

I am reading the docs here and I find myself a bit confused, since running
docker run --name some-mysql -p 3306:3306 -d mysql
or
docker run --name some-mysql -p 127.0.0.1:3306:3306 -d mysql
then mysql --host localhost --port 3306 -u root gives me the following error :
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2).
But running mysql -u root -p --host 0.0.0.0 works.
Does someone have an explanation ?
With docker port forwarding, there are two network namespaces you need to keep track of. The first is inside your container. If you listen on localhost inside the container, nothing outside the container can connect to your application. That includes blocking port forwarding from the docker host and container-to-container networking. So unless your container is talking to itself, you always listen on 0.0.0.0 with the application you are running inside the container.
The second network namespace is on your docker host. When you forward a port with docker run -p 127.0.0.1:1234:5678 ... that configures a listener on the docker host interface 127.0.0.1 port 1234, and forwards it to the container namespace port 5678 (that container must be listening on 0.0.0.0). If you leave off the ip, docker will publish the port on all interfaces on the host.
So when you configure mysql to listen on 127.0.0.1, there's no way to reach it from outside of the container's networking namespace. If you need to prevent others outside of your docker host from reaching the port, configure that restriction when publishing the port on the docker run cli.
As described in the mysql documentation (https://dev.mysql.com/doc/refman/5.7/en/connecting.html), when you connect to 127.0.0.1 with the client, it'll try to use the unix sockets to perform this operation. Normally this would work fine since it's on the same host. In Docker the socket file is not available.

Map port of Elasticsearch in Docker

I want to start an Elasticsearch container in Docker. By default I see nearly everywhere something like:
docker run -d -p 9200:9200 docker.elastic.co/elasticsearch/elasticsearch:5.5.1
Now is my question: Why are we mapping the port on our host network? I understand port mapping but I don't see the big advantage of it.
In my opinion I would always do something like this:
$ docker network create logging
20aa4c7bf2d8289d8cbd485c3e384f9371eed87204625998687c61e4bad27f14
$ docker run -d --name es --net logging docker.elastic.co/elasticsearch/elasticsearch:5.5.1
And connect to the ES by using it's name (es in this case) and deploying containers in the same network. I would think my ES is more secure in its private docker network.
I see there is an advantage for port mapping when your containers which need to connect to elasticsearch aren't in the same network. But are there other advantages or why is this always shown with port mapping?
So host access is more about accessibility. If you are running docker on local machine and you want to access the app only on that machine, then host mapping is not need.
Now if you need to access this app on a external computer other than your docker host then you need to do that port mapping.
docker run -d -p 9200:9200 docker.elastic.co/elasticsearch/elasticsearch:5.5.1
This maps the host port 9200 (left side) to 9200 inside the docker (right side). The listening interface is 0.0.0.0 which means all interfaces. And hence it is accessible to to anyone how has access to this machine.
If you want to make it more secure then you do it like below
docker run -d -p 127.0.0.1:9200:9200 docker.elastic.co/elasticsearch/elasticsearch:5.5.1
This would listen on local host only. So only you can access it on the machine. But if you need to access it from some place else then you would use a SSH tunnel
ssh -L 9200:127.0.0.1:9200 <user>#<HOSTIP>
And on that machine you can access it on 127.0.0.1:9200
Next level of security is added when you use a firewall like ufw, firewalld etc.
What you did with network command
docker network create logging
Basically creates new network and isolates other docker containers from accessing it on the host. But as long as external accessibility is concerned, you still need to map it to the host port
Hope this answers your question

From a container running on Docker for Windows, how can I access a port on the host?

I'm running a CentOS-based container on Docker for Windows and trying to connect to an http service running on port 8545 of my host environment.
I've tried this, attempting a variety of suspected host names and IP addresses:
curl http://localhost:8545
But the error message I get is "curl: (7) Failed connect to localhost:8545; Connection refused"
How should I figure out what IP Address to use? Is there anything I need to configure as far as allowing the port number to be accessed from inside the container?
Localhost is not working yet I think with Docker for Windows.
There is few things you can try. First you can add EXPOSE 'portnumber' in the dockerfile so the container will listen on this port. You can also use docker run with -p 8545:8545, it will map the port of the container and the host.
To get the Ip address of the container you can use:
docker inspect -f "{{ .NetworkSettings.Networks.nat.IPAddress }}" containername
You can access the host using its ip but localhost/127.0.0.1 won't work (they will resolve to the Linux VM that is part of docker for windows). If you use the default network settings, your host should be reachable on 10.0.75.1 from your container

how to handle redirection url in port forwarding - docker container

I build magento application in docker container, I am trying to access that container from remote machine using docker port forwarding.
System A
create container : docker run -it -d -p 8000:80 -h tm.gworks.mobi -v /var/www/public --privileged --name testmachineone magedev
container ip : 172.17.0.2
System A ip : 192.168.1.6
I can able to access webserver using both ip in system A http://172.17.0.2 && http://192.168.1.6:8000
note: if I access http://192.168.1.6:8000 it will get automatically redirect to http://172.17.0.2 that is default behavior of magento.
System B
if I access http://192.168.1.6:8000 it will get automatically redirect to http://172.17.0.2 but system B can't able to access http://172.17.0.2 so it throws 404 error.
as per my search we can't access docker container ip from remote host, only way is port forwarding. But I stuck with URL redirection in port forwarding.
how to sort out this issues?

How to access web page served by nginx web server running in docker container

We are trying to use docker to run nginx but for some reason I'm unable to access the nginx web server running inside the docker container.
We have booted a Docker Container using the following Dockerfile: https://github.com/dwyl/learn-docker/blob/53cca71042482ca70e03033c66d969b475c61ac2/Dockerfile
(Its a basic hello world using nginx running on port 8888)
To run the container we used:
docker run -it ubuntu bash
we determined the Container's IP address using the docker inspect command:
docker inspect --format '{{ .NetworkSettings.IPAddress }}' a9404c168b21
which is: 172.17.0.11
when I try to visit the container's IP address and the nginx port in a browser http://172.17.0.11:8888/ we get ERR_CONNECTION_TIMED_OUT
or using curl:
curl 172.17.0.11:8888
curl: (7) Failed to connect to 172.17.0.11 port 8888: Connection refused
To attempt to solve this we googled extensively but suspect we might be asking the "wrong" questions...
You shouldn't be trying to hit the IP address of the container, you should be using the IP address of the host machine.
What you are missing is the mapping of the port of the host machine to the port of the container running the nginx server.
Assuming that you want to use port 8888 on the host machine, you need a parameter such as this to map the ports:
docker run ... -p 8888:8888 ...
Then you should be able to access you server at http://<HOST_MACHINE_IP>:8888
EDIT: There is another gotcha if you are running on a Mac. To use Docker on a Mac it's common to use boot2docker but boot2docker adds in another layer. You need determine the IP address of the boot2docker container and use that instead of localhost to access nginx.
$ boot2docker ip
The VM's Host only interface IP address is: <X.X.X.X>
$ wget http://<X.X.X.X>:8888
...
Connecting to <X.X.X.X>:8888... connected.
HTTP request sent, awaiting response... 200 OK
Reference: https://viget.com/extend/how-to-use-docker-on-os-x-the-missing-guide
EDIT: ... or with docker-machine the equivalent command would be docker-machine ip <machine-name> where <machine-name> is likely to be "default".
You may need to check if your container is running:
docker ps ( you should have an active container)
If no container is active:
docker run -p 80:80 -it /bin/bash
you will then be on your image terminal
start nginx - sudo service nginx start
ctrl p + ctrl q to quit docker without exiting the container
if you are on mac and using boot2docker you cannot use localhost to check your running nginx
so use boot2docker ip
browse using the boot2docker ip

Resources