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.
Related
Context, I'm currently dockerizing an application in windows containers, the application
will connect to a Sql Server database from outside the container, normally working with linux containers I could use host driver, but since that is not available in windows containers. How could I connect to that database outside my windows container?
So, the answers provided before are all valid. I'd just add that while Host network is not available on Windows, you can still use the same concept - albeit a bit different.
The native network driver on Windows is Network Address Translation. With that driver, the container will get a private IP address and the ports from the container host can be mapped to the ports on the container, by use of the docker run -p 8080:80, for example.
That way, if you want to continue to use the option to call the localhost between the app container and the database container you can. You just need to specify the port: localhost:8080. Note that if the host is not using that port, you can even map it directly, such as: docker run -p 80:80. The caveat here is: The container host cannot be using the port already, and you can't map the same port to another container. So, if you need another instance, you can map to something like: docker run -p 81:80.
I blogged about this here: https://cda.ms/4nB
So I see host mentioned a few times in the docs. There's also networking_mode=host you can add in the yml file.
So what I assume the host is, is the machine the VM (Docker) is run on?
So if I set networking mode to host, the port mapping etc will be handled on my local machine. Where in the yml i could do 3001:3000 that'll map port 3001 to the container port of 3000. With networking mode host that mapping will be handled on my local machine.
Now, when we're hosting containers on rancher. And we set the networking_mode=host. What's host in that context? Is it the VM or ec2 or whatever that is running my rancher? Or the VM/ec2 that's running my host stack?
I can't grasp it from the docs.
A container runs on a single server, a.k.a host, running Docker.
Host can be either be a bare metal server, Virtual machine running on your laptop or an EC2 instance.
Rancher itself is a container running on a host. Now when you build a cluster, you can add the host that's running the Rancher container or you can choose to keep things isolated and start adding totally different hosts.
If you choose networking_mode=host, the container is using the host networking stack and if you don't the container gets it's own networking stack. When running in host networking mode, the application running inside the container binds directly to the host network interfaces, so there is no port mapping happening.
In case you are interested in more details, I have discussed a lot about networking in the first half of this talk: https://www.youtube.com/watch?v=GXq3FS8M_kw. Let me know if you have more questions.
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.
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.
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.