Docker port forwarding not working
Asked Answered
A

13

71

I have setup Docker container for access my machine docker container to another machine in local.

Create a container below command:

    docker run -it -d --name containerName -h www.myhost.net -v /var/www/html -p 7000:8000 --net mynetwork --ip 172.11.0.10 --privileged myimagename bash

After Create A Container Details:

        CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES

        1e1e5e9b74b4        myimgaename         "bash"              21 minutes ago      Up 6 minutes        0.0.0.0:7000->8000/tcp   containername

NetWork Details:

     "NetworkSettings": {
        "Bridge": "",
        "SandboxID": "fe357c54c816fff0f9d642037dc9a173be7f7e42a80776d006572f6a1395969e",
        "HairpinMode": false,
        "LinkLocalIPv6Address": "",
        "LinkLocalIPv6PrefixLen": 0,
        "Ports": {
            "8000/tcp": [
                {
                    "HostIp": "0.0.0.0",
                    "HostPort": "7000"
                }
            ]
        }

if I access docker ipaddr(172.11.0.10) or hostname(www.myhost.net) in mymachine(hostmachine) it working

But if I access with Port doesn't work: hostmachine ip: 192.168.1.1

  go to the browser  192.168.1.1:7000  hostmachine and locally connected anoter machine also.

But My 7000 port are listen in hostmachine:

        # ps aux | grep 7000
        root     10437  0.0  0.2 194792 24572 pts/0    Sl+  12:33   0:00 docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 7000 -container-ip 172.11.0.10 -container-port 8000
        root     10941  0.0  0.0 118492  2324 pts/3    R+   12:44   0:00 grep --color=auto 7000

update 1:

      $ docker version
        Client:
         Version:      1.11.2
         API version:  1.23
         Go version:   go1.5.4
         Git commit:   b9f10c9
         Built:        Wed Jun  1 21:39:21 2016
         OS/Arch:      linux/amd64

        Server:
         Version:      1.11.2
         API version:  1.23
         Go version:   go1.5.4
         Git commit:   b9f10c9
         Built:        Wed Jun  1 21:39:21 2016
         OS/Arch:      linux/amd64

Suggest me Why Cannot access my Container to another machine. How to Resolve this Problem

Aliber answered 16/9, 2016 at 7:19 Comment(2)
Are you using docker toolbox or native docker?Intarsia
@Intarsia I am using native docker, I install using command line(fed23) dnf install dockerAliber
M
190

A very common problem can be this:

Bind your app inside Docker to 0.0.0.0, not to 127.0.0.1 address to let Docker reach the app inside container.

UPD: Don't try to solve it with docker. There is no docker command to fix that. It strictly depends on the using app, web-framework, etc. Read the manual of the tool you use inside the container. Try to google "how to bind [using framework] to the specific address and port". It could be an environment variable, cli parameter, code, etc.

Marchioness answered 9/8, 2019 at 10:5 Comment(17)
Thanks! 0.0.0.0 it the key. My example was simple php standalone server: d run --rm -p 8091:8091 -v (pwd):(pwd) -w (pwd) --name php php:7.3 php -S 0.0.0.0:8091Firedamp
What does this mean? Do not use only english. Post full docker commands.Neurosurgery
@mathtick It doesn't require any special docker command, but you should bind the socket of your app to 0.0.0.0 address. It depends on the app you use inside a container. For example if you have a nodejs app you should set host parameter in server.listen function call to 0.0.0.0: nodejs.org/api/…Marchioness
Oh I see, it is "tell the app to bind" and not "tell docker to bind the app" got it.Neurosurgery
what does that mean?Urbanize
Slightly simplified explanation: Your networking application have to be attached to IP address to let other apps/browsers/servers/users can discover it for connection. 0.0.0.0 IP address means your app will be attached to all IP addresses you have. 127.0.0.1 IP address is private and doesn't available outside. Since your app runs in a container than your host is the outside world for it and you have to attach the socket to the external address 0.0.0.0 of the container to let your host connect to it.Marchioness
Your programming language has API to set IP address for the server socket of your app. For example in Python: docs.python.org/3/library/socket.html#socket.socket.bindMarchioness
I'm using Rails and I need to use bin/rails server --binding 0.0.0.0 instead of bin/rails serverMekka
I'm using Ghost and I needed to set server__host="0.0.0.0" in my .env file (or the equivalent in the conffig gile)Valentino
for flask i added host='0.0.0.0' in app.run() then it started workingContact
This is a truly great answer! I was running a bunch of kubernetes services inside a docker and the default forward is to 127.0.0.1which of cause must be manually changed to something like kubectl port-forward svc/kiali --address=0.0.0.0 20001 -n istio-system Thank you for the critical hint (and for asking the question)Leucine
Finally, the solution to my problem!Harker
thanks very much! this is a bug confusing me for a whileSuds
can you clearly provided the solution as a command?Diesis
The command depend on what inside the container. I've added a little an explanation to the answer.Marchioness
For Django dev server, use python manage.py runserver 0.0.0.0:8000 instead of just python manage.py runserverSigler
for uvicorn running inside the container, need to change and add host parameter uvicorn src.main:app --port 8000 --host 0.0.0.0 --reload else by default it listens on 127.0.0.1 `Stomato
B
30

Port 7000 on the host is redirecting to port 8000 in the container, but is anything listening on that port in the container?

Your docker run command is a bit odd: -it is for running a container interactively with a terminal attached; -d is for running detached, in the background; bash at the end overrides whatever the image configures as the startup command, which is why I think there's nothing listening on port 8000.

Try running the simplest NGINX container with this:

docker run -d -p 8081:80 nginx:alpine

And then verify you can get to the homepage:

curl http://localhost:8081

If that's working then I'd look at how you're running your image.

Bolme answered 16/9, 2016 at 12:43 Comment(2)
In my case localhost:8081 does not working. I have to use docker-machine ip default instead (192.168.99.100). Any idea why localhost is not working ?Preview
When you use Docker "natively", containers are "bound" to the host computer, so you use localhost. When you use an alternative like Docker Toolbox, Docker runs inside a VM, so the containers are "bound" to the VM's localhost and you need to use its IP address (usually 192.168.99.100)Eby
M
3

This was happening for me w/ Docker for Mac. Clicking the Docker icon, then Restart did the trick.

Medarda answered 11/7, 2019 at 18:50 Comment(0)
B
3

For anyone running serverless-offline inside a docker container:

I was trying to map localhost:3000 on my mac to the default serverless-offline app port of 3000 (which was running inside docker), achieved the desired result as follows:

(1) Added --host:0.0.0.0 to the usual serverless offline command like so:

serverless offline --host 0.0.0.0

(2) Then ran the docker container with the usual port mapping:

docker run -p 3000:3000 <your-image-name>

NOTE: Needed to rebuild my image (before running it) to get everything working properly.

Boundless answered 10/9, 2021 at 3:32 Comment(0)
K
1

Hi I have encountered this problem as I'm using Dockerfile to build image. I realised I can't set address to specific IP address meaning after I change

    srv := &http.Server{
    Handler: s,
    Addr:    "127.0.0.1:5000",
}

to

    srv := &http.Server{
    Handler: s,
    Addr:    ":5000",
}

the command docker run -dp 5000:5000 --name myapiserver api_server:v1 is working properly. I can access the the container port 5000 without issue. So to conclude in container you can only set the server's port?

Update

127.0.0.1 is the IP address that your host will not send to outsite, the proper way to handler way is to send through all IP address which is 0:0:0:0 or in short just port only.

Knapsack answered 29/5, 2021 at 12:44 Comment(0)
A
0

I hit this problem with a Docker Wordpress container.

Troubleshooting:

curl -Is http://192.168.X.X executed on the Docker host itself would return a result as expected, but the same command executed on my laptop on a different subnet would just hang.

Same with telnet 192.168.X.X 80: this would connect as expected on port 80 from the Docker host itself, but not outside the Docker host; it too would just hang.

docker logs containerName provided no useful clues.

On the router's firewall I allowed everything between the Docker host and my laptop to ensure the router's firewall wasn't breaking connectivity on port 80.

Solution:

Struggling to clear the error, I decided to remove my custom networking from the docker run command to reduce complexity.

Like the OP, I had specified my own custom network and IP address in the docker run command. But when I removed --net and --ip from the docker run command, the container rose-up using the default bridge and a Docker DHCP assigned address.

Test Solution:

I found the IP of my Wordpress container using:

docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' wordpressContainerName

and tried loading Wordpress in a browser on my laptop. The container could now be contacted on the forwarded port 80 outside the Docker host on a different subnet.

Conclusion:

Removing --net and --ip from the docker run command fixed the issue in my case; YMMV of course.

Aerostatics answered 1/12, 2021 at 11:39 Comment(0)
C
0

You can use docker run -d -p 127.0.0.1:9000:4000 --name some-container some-image-name or you can use -it flag

Centring answered 4/12, 2021 at 22:54 Comment(0)
A
0

After thousand of hours digging this problem, i finally solve it by this silly way:

  1. Uninstalled docker:

sudo yum remove docker
docker-client
docker-client-latest
docker-common
docker-latest
docker-latest-logrotate
docker-logrotate
docker-engine docker-ce

  1. Update my centos system:

    yum -y update

  2. Reboot

  3. Re-install docker

  4. Re-install container/image

Now it work like a charm.

Aramaic answered 20/12, 2021 at 15:13 Comment(0)
J
0

In my case I logged in the docker container (postgresql) and saw that it's ip was 172.18.0.13 (by running ifconfig or ip a, install by e.g. apt-get install net-tools if you are running Debian derived containers).

I was able to connect to the container from the host machine fine (netcat, install by running apt-get install netcat-traditional) :

nc -vz 172.18.0.13 5432

but trying to connect from outside to the exposed port 5433 did not work.

Next I checked the iptables -settings:

iptables -nL -t nat --line-numbers |grep 5433

and saw output

7   DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:5433 to:172.18.0.2:5433

So the IP address of the port forwarding is pointing to docker_gwbridge (or wrong ip). I think there is some older container lingering around, or the port forward settings of it, or some malfunction in docker gwbridge. Restarting docker might help, and/or clearing/flushing all iptables -settings before starting docker. However, I had some production containers running there and I tried to avoid service break, so I fixed it manually by deleting the offending rule (line 7):

iptables -t nat -D DOCKER-INGRESS 7

Then I manually added forward to the right container (Note! please change the interface -i to your egress interface):

iptables -t nat -I DOCKER-INGRESS -p tcp -i eth0 --dport 5433 -j DNAT --to-destination 172.18.0.13:5432

Please note that this is a temporary hack, since docker keeps changing the rule back to a non-working version, so restart might be required sooner or later.

Jesselyn answered 18/1, 2023 at 20:57 Comment(0)
S
0

one possible issue is that your container is using IPV6 , after running your container , for example if you are running you container using something like this >

docker run -it -p 8080:80 --name mycontainer myimage

then run this in bash of your host machine >

sudo netstat -tulpn | grep :8080

if there was tcp6 in the output , it means that your container is using IPV6

Slouch answered 14/5, 2023 at 13:25 Comment(0)
R
0

it's very simple just check your ip of the docker by docker-machine ip

it usually dockerip

first create a docker conatiner abd run it by docker run -d -p 8081:80 nginx:alpine

then run http://dockerip:8081/ on your browser.

Reputation answered 15/5, 2023 at 12:36 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Backcourt
A
-1

Partial Answer:

Now I solved this problem partially, While i try without bash in create a container and change my port to 3000(-p 3000:80) it worked for me.

Before Command:

     docker run -it -d --name containerName -h www.myhost.net -v /var/www/html -p 3000:80 --net mynetwork --ip 172.11.0.10 --privileged myimagename  bash

After Command:

    docker run -it -d --name containerName -h www.myhost.net -v /var/www/html -p 3000:80 --net mynetwork --ip 172.11.0.10 --privileged myimagename

Then,

execute the container with bin/bash

  docker exec -it containerName bin/bash

Now , works locally Connected Another machine.

 hostmachineip:3000 


I don't know docker have any port restrictions.But This solution works for me.
Aliber answered 17/9, 2016 at 5:17 Comment(0)
T
-1

When i encountered this problem (with a docker-compose managed set of docker instances), I found that deleting the network that docker-compose fixed the problem:

docker-compose stop
# find the network related to my docker-compose setup
docker network ls
docker network rm NETWORKNAME
# let docker-compose recreate the network:
docker-compose up -d
Tops answered 8/11, 2017 at 18:1 Comment(2)
docker-compose down does all thatIndaba
it does, and more? I don't lose volumes, containers or images by doing the above (just the network)?Tops

© 2022 - 2024 — McMap. All rights reserved.