Reputation: 3740
I have a daemon on my host running on some port (i.e. 8008) and my code normally interacts with the daemon by contacting localhost:8008 for instance.
I've now containerized my code but not yet the daemon. How can I forward the localhost:8008 on my container to localhost:8008 on the host running the container (and therefore the daemon as well).
The following is netstat -tlnp
on my host. I'd like the container to forward localhost:2009 to localhost:2009 on the host
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:2009 0.0.0.0:* LISTEN 22547/ssh
tcp6 0 0 :::22 :::* LISTEN -
tcp6 0 0 ::1:2009 :::* LISTEN 22547/ssh
Upvotes: 72
Views: 129211
Reputation: 75
If you still want to access your app locally try this:
First, find your docker ip, you can find it using ifconfig
command.
use docker0 ip address and add port ahead of it, example:
172.17.0.1:your-port
Done...
Upvotes: 0
Reputation: 468
If you're doing this on your local machine, you can simple specify the network type as host
when starting your container (--network host
), which will make your host machine share network with your docker container.
eg:
Start your container:
docker run -it --rm --network host <container>
On your host machine, Run:
python3 -m http.server 8822
Now from your container run:
curl 127.0.0.1:8822
If all went well you'll see traffic on your host terminal.
Serving HTTP on 0.0.0.0 port 8822 (http://0.0.0.0:8822/) ...
127.0.0.1 - - [24/Jan/2023 22:37:01] "GET / HTTP/1.1" 200 -
Upvotes: 3
Reputation: 361
TL;DR: You can use the special hostname host.docker.internal
instead of localhost
anywhere inside the container that you want to access localhost
on the host. Note that:
--add-host=host.docker.internal:host-gateway
to your Docker command to enable the feature.extra_hosts:
- "host.docker.internal:host-gateway"
Full answer: Is the host running MacOS or Windows? Buried in the documentation for Docker Desktop is the fact that there is no docker0 bridge on MacOS and there is no docker0 bridge on Windows. Apparently that's the cause of this. In both cases the workaround (given right after, in a subsection titled "Use cases and workarounds") is to use the special hostname host.docker.internal
in placed of localhost
anywhere inside the container that you want to access localhost
on the host.
If the host is Linux, there are some Linux-only techniques for achieving this. However, host.docker.internal
is also useable with a Linux host, but it has to be enabled first. See the Linux part of the TL;DR, above, for instructions.
By this method, in OP's case host.docker.internal:8008
should be used instead of localhost:8008
. Note that this is a code or configuration change of the application code running inside the container. There is no need to mention the port in the container configuration. Do not try to use -p
or --expose
in the docker run
commandline. Not only is it not necessary, but your container will fail to start if the host application you want the container to connect to is already listening on that port.
Upvotes: 21
Reputation: 722
After checked the answers and did some investigation, I believe there are 2 ways of doing that and these 2 only work in Linux environment.
The first is in this post How to access host port from docker container
The second should be set your --network=host
when you docker run
or docker container create
. In this case, your docker will use the same network interface you use in Mac.
However, both ways above cannot be used in Mac, so I think it is not possible to forward from the container to host in Mac environment. Correct me if I am wrong.
Upvotes: 5
Reputation: 37
I'm not sure if you can do that just with docker's settings. If my under standing is correct, expose port is not what you looking for. Instead, establish ssh port forwarding from container to host mightbe the answer.
Upvotes: -2
Reputation: 12635
So the way you need to think about this is that Docker containers have their own network stack (unless you explicitly tell it to share the host's stack with --net=host
). This means ports need to be exposed both inside the docker container and also on the outside (documentation), when linked with host ports. The ports exposed on the container need to be bound to the host ports explicitly (with -p xxxx:yyyy
in your docker run
command) or implicitly (using EXPOSE
in your Dockerfile and using -P
on the command line), like it says here. If your Dockerfile does not contain EXPOSE 8008
, or you do not specify --expose 8008
in your docker run
command, your container can't talk to the outside world, even if you then use -p 8008:8008
in your docker run
command!
So to get tcp/8008 on the host linked with tcp/8008 on the container, you need EXPOSE 8008
inside your Dockerfile (and then docker build
your container) OR --expose 8008
in your docker run command
. In addition, you need to either use -P
to implicitly or -p 8008:8008
to explicitly link that exposed container port to the host port. An example docker run
command to do this might look like:
docker run -it --expose 8008 -p 8008:8008 myContainer
It's handy to remember that in the -p 8008:8008
command line option, the order for this operation is -p HOST_PORT:CONTAINER_PORT
. Also, don't forget that you won't be able to SSH into your container from another machine on the internet unless you also have this port unblocked in iptables on the host. I always end up forgetting about that and waste half an hour before I remember I forgot to iptables -A INPUT ...
for that specific tcp port on the host machine. But you should be able to SSH from your host into the container without the iptables rule, since it uses loopback for local connections. Good luck!
Upvotes: 56
Reputation: 165
docker run -d --name <NAME OF YOUR CONTAINER> -p 8008:8008 <YOUR IMAGE>
That will publish port 8008
in your container to 8008
on your host.
Upvotes: -6