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

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.

Related

Docker cannot access exposed port inside container

I have a container for which I expose my port to access a service running within the container. I am not exposing my ports outside the container i.e. to the host (using host network on mac). On getting inside the container using exec -t and running a curl for a post request, I get the error:
curl command: curl http://localhost:19999
Failed connect to localhost:19999; Connection refused.
I have the expose command in my dockerfile and do not want to expose ports to my host. My service is also up and running inside the container. I also have the property within config set as
"ExposedPorts": {"19999/tcp": {}}
(obtained through `docker inspect <container id/name>\ Any idea on why this is not working? Using docker for Mac
I'd post my docker-compose file too but this is being built through maven. I can ensure that I am exposing my port using 19999:19999. Another weird issue is that on disabling my proxies it would run a very light weight command for my custom service and wouldn't run it again returning the same error as above. The issue only occurs on my machine and not others
Hints:
The app must be listening on port 19999 which is probably not.
The EXPOSE that you're using inside the Dockerfile does nothing.
Usually there is no need to change the default port on which an application is listening, hence each container has its own IP and you shouldn't run in a port conflict.
Answer:
Instead of curling 19999 try to use the default port on which your app would normally be listening to(it's hard to guess what you are trying to run).
If you don't publish a port (with the docker run -p option or the Docker Compose ports: option), you cannot directly reach the container on Docker for Mac. See the Known limitations, use cases, and workarounds in the Docker Desktop for Mac documentation: the "per-container IP addressing is not possible" item ism what you're trying to attempt.
The docker inspect IP address is basically useless, except in one very specific Docker configuration (on a native-Linux host, calling from outside of Docker, on the same host); I wouldn't bother looking it up.
The Dockerfile EXPOSE directive and similar runtime options do very little and mostly serve as documentation. Even if you have that configured you still need to separately publish the port when you start the container to reach it from outside of Docker space.

How do I make Eureka client to use host machine's IP instead of Docker container's IP?

I'm trying to dockerize my SpringBoot application. When the application is deployed in the docker container, it gets registered with Eureka using the docker container's IP.
I want it to get registered with the host machine's IP.
I've set eureka.instance.preferIpAddress to true. I tried ignoring the network interfaces like it is mentioned in documentation, but had no luck with it.
Is there any way to tell Eureka client to use host machine's IP?
If you start you container with --network=host, your container will have host's ip address and you wont need any additional configuration. Like docker run -it --network=host you-container ...
But consider drawbacks of this mode like lack of isolation of container, because your container will have access to host's networking.

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

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.

Docker container DNS - Resolve URL

I have a docker container that needs to access an network server on the LAN. This server is visible from the docker host machine and I can access it from within the container when I reference the IP address directly.
However I need to be able to specify a url and port (e.g http://myserver:8080) rather than an IP address, which the docker container cannot resolve.
How can I configure the container to resolve this? ideally using the docker hosts dns. I have looked at many of the docs, but not being a DNS expert, it doesn't seem straightforward.
UPDATE:
I have tried this, which seems to work, but does this have any downsides or unintended consequences?
--network host
Thanks,
The rigth way to do this is to configure the docker daemon dns as specified under daemon-dns-options.
Using the host network is not recommended as it has some downsides https://docs.docker.com/network/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