How to access service in localhost exposed on a given port from a nginx container - docker

I currently have a nginx container which points to other dockers, that run a java app, through ip and port, working as expected. For simplicity porpouse, I'm running these java apps outside a docker container, thus having them exposed on localhost:xxxx
When trying to communicate to localhost:xxxx from nginx container, it obviously pointer to the container itself and not my java apps.
Is there a workaround to this problem?

Localhost is scoped to the container itself. Therefore to be able to connect to it, you would have to be inside the container.
To fix this, you need to get your application to talking/listen to 0.0.0.0 instead.

Related

How to make a Docker container's service accessible via the container's IP address?

I'm a bit confused. Trying to run both a HTTP server listening on port 8080 and a SSH server listening on port 22 inside a Docker container I managed to accomplish the latter but strangely not the former.
Here is what I want to achieve and how I tried it:
I want to access services running inside a Docker container using the IP address assigned to the container:
ssh user#172.17.0.2
curl http://172.17.0.2:8080
Note: I know this is not how you would configure a real web server but I want the container to mimic an embedded device which runs both services and which I don't have available all the time. (So it's really just a local non-production thing with no security requirements).
I didn't expect integrating the SSH server to be easy, but to my surprise I just installed and started it and had to do nothing else to be able to connect to the machine via ssh (no EXPOSE 22 or --publish).
Now I wanted to access the container via HTTP on port 8080 and fiddled with --publish and EXPOSE but only managed to make the HTTP server available through localhost/127.0.0.1 on the host. So now I can access it via
curl http://127.0.0.1:8080/
but I want to access both services via the same IP address which is NOT localhost (e.g. the address the container got randomly assigned is totally OK for me).
Unfortunately
curl http://172.17.0.2:8080/
waits until it times out every time I tied it.
I tried docker run together with -p 8080, -p 127.0.0.1:8080:8080, -p 172.17.0.2:8080:8080 and much more combinations, together or without EXPOSE 8080 in the Dockerfile but without success.
Why can I access the container via port 22 without having exposed anything?
And how do I make it accessible via the container's IP address?
Update: looks like I'm experiencing exactly what's described here.

How to send a request from inside a docker container to the outside hostname/port of this container?

I have a web application running inside a php:7.1.8-apache docker container. The application has port 80 inside the container and port 8080 outside of it.
One part of the application sends requests to itself, but uses the outside hostname/port (for example to http://outsidehostname.local:8080).
This doesn't work because the port and the hostname does not exist inside the container.
I already tried the --hostname flag, but this doesn't solve the problem with the different port inside and outside of my container. So I am looking for a different solution.
The hostname (outsidehostname.local) comes from the host os (in my case macos). I am using dnsmasq to resolve all *.local hostnames to 127.0.0.1.
Is there any way to configure docker so that this request works without changing the behavior of the application?
In docker you have various options to set hostnames that can be resolved from container to container: When to use --hostname in docker?
This doesn't work because the port and the hostname does not exist inside the container.
Why not? Where does this outside hostname come from?
Hostnames that cannot be resolved by docker could be resolved by other DNS servers configured on OS or network level. In general how a hostname will be resolved is not a trivial question and you first need to understand how / where your outside hostname is defined and resolved.
UPDATE:
The hostname (outsidehostname.local) comes from the host os (in my case macos). I am using dnsmasq to resolve all *.local hostnames to 127.0.0.1.
This explains your problem: log in to your running container (assuming it's Linux based) using docker exec -it <containerId> /bin/sh then inside the container if you try to look up outsidehostname.local you should see that outsidehostname.local cannot be resolved because there is no such DNS info inside the container OS. If it could be resolved to 127.0.0.1, your next problem would indeed be the wrong port.
Basically running the webserver inside the container defeats the purpose of running your own OSX DNS resolver outside the container. I don't know enough about your use case to really suggest a good solution, but for Linux based images you can always edit /etc/hosts or /etc/resolv.conf.

Map a port inside a docker container

In one of my test setups, I have code which is sometimes runs inside a docker container that wants to connect to a port on the host machine.
It is configured to try to connect to localhost:12345. That works when it is running outside the container, but obviously fails when it runs inside the container.
Is there a way to map a port on the local host into the container? This is the reverse of the normal port mapping, where you expose a port in the container to the host.
I can see potential security issues with this, and also that it breaks the paradigm of "the container is the world", so I would not be surprised if it is not supported.

How can I inverse EXPOSE a port to a container?

I am new to Docker and I may not be looking into the right place in the documentation because I couldn't find a way to do what I call "inverse EXPOSE".
So for example, I have one web application that EXPOSE 80. That same application is using a postgresql database. When I am locally developing it works fine because I connect to localhost:5432 but when I containerize the app, it says something like "connection refused". I think the Docker philosophy is to containerize as much as possible and make those containers communicate between each other through a docker network. But I am curious if it actually is possible to say that localhost:5432 in my container actually refers to the port 5432 on the actual machine that hosts my container.
Localhost inside a container is not your docker host, it's a namespaced network inside the container. So if you try to communicate with localhost or 127.0.0.1 inside a container, it's only going to communicate with other apps running inside that container.
Instead, you should use the routeable IP of the host, so that requests can come out of the container and back into the docker host interface to reach applications running outside of a container.
When the app is running in the container you should use the IP:5432 e.g. 192.168.99.100:5432 of the host and not localhost.
When using localhost in the container it refers to localhost (127.0.0.1) of the container and not the one of the host.

Can't connect to ASP.Net site in Docker for Windows

I am having difficulty connecting from the host to an ASP.Net website running in a Windows container on Docker. I can connect to a website running in a Linux container without any problem.
I have tried connecting to both localhost and to the IP port assigned to the container but in both cases I just get a timeout error.
I have tried several ASP.Net examples which are already pre-built along with trying to build my own custom image. In every case I get the same timeout error. I have also tried uninstalling and re-installing docker but that didn't change anything.
I am running Windows 10 Pro and Docker Community Edition Version 17.03.1-ce-win12 (12058)
Ultimately I was able to completely reset my container network using a customized older version of the Microsoft Vitualization cleanup scripts. https://github.com/Microsoft/Virtualization-Documentation/tree/live/windows-server-container-tools/CleanupContainerHostNetworking This reset my container network and everything is now working as expected.
SUMMARY:
When the published port/s for a container are defined using the EXPOSE directive in the container's Dockerfile, the -P argument must be used with the docker run command in order to "activate" those exposed port/s.
It is not possible for a Windows container host to access containers that it is running using localhost, 127.0.0.1 or its external host IP address. Access containers running on a given host, A, by using the IP address of A from a second host, B. Alternatively, you can use the IP address of a container directly.
FULL EXPLANATION:
So there are a few nuances with ensuring that the proper firewall rules are created, and your containers are actually accessible on their published port/s.
For instance, I'll assume that your ASP.Net containerized application is defined by a container image, which was defined by a Dockerfile. If so, you probably defined the published port for the image/app using the Dockerfile EXPOSE directive. In this case, when you actually run the container you need to "activate" that published port using the "-P" argument to the docker run command.
For example, if your container image is web_app, and the Dockerfile for that image included the line, EXPOSE 80, then when you go ahead and run that image you need to do something like:
C:\> docker run -P web_app
Once the container is running, it should be available on container port 80. You can then go ahead and view the app via browser. To do that you have two options:
You can access the app from your container host, using the container IP and port
Find the container IP using docker network inspect nat, then looking for the endpoint/IP address that corresponds with your container.
You can also fund the container IP by running docker exec <CONTAINER ID> ipconfig, where <CONTAINER ID> is the ID of your container.
You can get the ID of your container and the exposed port for your container by running docker ps on the container host.
You can access the app from another host machine, using the container host IP and host port
You can find the IP address of your host using ipconfig.
You can identify the host port upon which your app is exposed, by running docker ps from the host. Then, under PORTS you'll see a mapping of the form 0.0.0.0:<HOST PORT>-><CONTAINER PORT>/TCP. In this mapping <HOST PORT>, is the port upon which your app is available on the host.
Once you have the IP address of your container host, and the port upon which your app is available on the host, you can use that information to access your app from a browser on a separate host.
NOTE: Today you cannot access a container in this way from its own host--currently a Windows container host cannot access the containers it is running, despite whether localhost, 127.0.0.1 or the host IP address is used.

Resources