Docker port binding not working as expected - docker

Running a Jenkins image in my container which is bound to the host port 9090
sudo docker run -itd -p 9090:8080 -p 50000:50000 --name=myjenkins -t jenkins-custom /bin/bash
The output of running $docker port myjenkins
50000/tcp -> 0.0.0.0:50000
8080/tcp -> 0.0.0.0:9090
I can also see the binding from the host perspective ps -Af | grep proxy
root 15314 15194 0 17:52 ? 00:00:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 50000 -container-ip 172.17.0.2 -container-port 50000
root 15325 15194 0 17:52 ? 00:00:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 9090 -container-ip 172.17.0.2 -container-port 8080
After starting my jenkins server i try connect to the container using the host ip and the forwarded port (9090).
I'm new to Docker so may have missed something however would appreciate suggestions
Update: including dockerfile
From local-artifiactory/jenkinsci/jenkins:2.9
ENV java_opts="-Xmx8192m"

This is not an answer to this specific question. It is a possible answer to "port mapping doesn't work"
I've been caught by this twice.
The image name must come last when creating a container from the command line
This syntax:
docker run --name MyContainer MyImage -p 8080:80
will create container MyContainer from MyImage without issue
But the -p 8080:80 part will be silently ignored and your port mapping won't work
This syntax will work - you'll see exactly the same outcome except that port mapping will actually work.
docker run --name MyContainer -p 8080:80 MyImage
Same for this:
docker run MyImage --name MyContainer
This will create a container from MyImage but it won't give it the explicit name, it'll assign a random name
I hope this saves someone some time.

Port binding/publishing in docker is actually publishing container's port to docker-machine's, instead of to localhost's. For example, with
docker run -p 9090:8080 jenkins
you will be able to access the service by curl <your-docker-machine>:9090, NOT curl localhost:9090 or curl 127.0.0.1:9090
To get your docker-machine's IP, do: docker-machine ls and check the URL

The problem is that no service is running at those ports. The only process running is /bin/bash (as specified in the end of the line). You must start Jenkins inside the container.

Related

Port issue with Docker for Windows

I'm trying to follow the beginner tutorial at training.play-with-docker.com. At Task 2, step 6, I do the following and get the error as below:
PS C:\Users\david.zemens\Source\Repos\linux_tweet_app> docker container run --detach --publish 80:80 --name linux_tweet_app $DOCKERID/linux_tweet_app:1.0
d39667ed1deafc382890f312507ae535c3ab2804907d4ae495caaed1f9c2b2e1
C:\Program Files\Docker\Docker\Resources\bin\docker.exe: Error response from daemon: driver failed programming external connectivity on endpoint linux_tweet_app (a819223be5469f4e727daefaff3e82eb68eb0674e4a46ee1a32e703ce4bd384d): Error starting userland proxy: listen tcp 0.0.0.0:80: bind: An attempt was made to access a socket in a way forbidden by its access permissions.
I am using Docker Desktop on a Win10 machine locally. I've tried resetting Docker as suggested here. Error persists. Since something else must be using port 80, I should be able to avoid the error by using a different port, right?
PS C:\Users\david.zemens\Source\Repos\linux_tweet_app> docker container run --detach --publish 1337:1337 --name linux_tweet_app $DOCKERID/linux_tweet_app:1.0
Right! docker ps now confirms the container is running:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b700df12c2d1 dzemens/linux_tweet_app:1.0 "nginx -g 'daemon of…" About a minute ago Up About a minute 80/tcp, 443/tcp, 0.0.0.0:1337->1337/tcp linux_tweet_app
But when I try to view the webpage that the tutorial sends me to, I get an error in the browser.
I'm not sure how the link is dynamically generated but it looks something like this:
http://ip172-18-0-32-blsfgt2d7o0g00epuqi0-80.direct.labs.play-with-docker.com/
Browser error as below:
The proxy could not connect to the destination in time.
URL: http://ip172-18-0-32-blsfgt2d7o0g00epuqi0-80.direct.labs.play-with-docker.com/
Failure Description: :errno: 104 - 'Connection reset by peer' on socketfd -1:server state 7:state 9:Application response 502 cannotconnect
Another highly-upvoted answer suggests I need to "disable Windows 10 fast startup" -- I have not tried this yet, mainly because I'm not sure what the full repercussions are with that setting.
Is there something stupidly obvious that I'm overlooking here? Shouldn't I be able to run this on different ports? If not, why not? If I have to use 80:80, but System is already using that port, won't I have some further problems if I try to kill that pid?
PS C:\Users\david.zemens\Source\Repos\linux_tweet_app> netstat -a -n -o | findstr :80 | findstr LISTENING
TCP 0.0.0.0:80 0.0.0.0:0 LISTENING 4
TCP 0.0.0.0:8003 0.0.0.0:0 LISTENING 4
TCP 0.0.0.0:8080 0.0.0.0:0 LISTENING 1348
TCP 0.0.0.0:8081 0.0.0.0:0 LISTENING 4688
TCP 127.0.0.1:8080 0.0.0.0:0 LISTENING 2016
TCP 127.0.0.1:8082 0.0.0.0:0 LISTENING 28536
TCP [::]:80 [::]:0 LISTENING 4
TCP [::]:8003 [::]:0 LISTENING 4
TCP [::]:8080 [::]:0 LISTENING 1348
TCP [::]:8081 [::]:0 LISTENING 4688
I made a small change in the Dockerfile changing EXPOSE 80 443 to EXPOSE 1337 443 and I'm now able to view my app by navigating to localhost:1337 in my browser. I think that will get me through the next steps in the training module, but still curious if I'm doing something wrong.
This seems to work regardless of the change in Dockerfile (I've removed and republished after changing Dockerfile).
PS C:\Users\david.zemens\Source\Repos\linux_tweet_app> docker container run --detach --publish 1337:80 --name linux_tweet_app $DOCKERID/linux_tweet_app:1.0
Try this
> net stop winnat
> docker start ...
> net start winnat
A part of the problem is that you're using the wrong mapping. The application uses the port 80, but you're mapping the ports 1337 to 1337.
The correct command should be:
PS C:\Users\david.zemens\Source\Repos\linux_tweet_app> docker container run --detach --publish 1337:80 --name linux_tweet_app $DOCKERID/linux_tweet_app:1.0
It may be because your IIS or some other server is already running on port 80.
Try stop the IIS and it should work.
Reference: https://forums.docker.com/t/error-starting-userland-proxy-listen-tcp-0-0-0-0-bind-an-attempt-was-made-to-access-a-socket-in-a-way-forbidden-by-its-access-permissions/81299/7

docker-pr proc already listening on port 80? Installed docker with snappy on Ubuntu

I ran this:
docker run -ti -p 80:80 --name esproxy "$tag"
but I get this error:
docker: Error response from daemon: driver failed programming external
connectivity on endpoint esproxy
(ead1fa4f09b2326cd1ff6aa0e3b8f8bfa5c9d353eb6db4efef6d188b81ea9df7):
Error starting userland proxy: listen tcp 0.0.0.0:80: bind: address
already in use.
So I did:
root#ip-172-xx-29-110:/interos/repos/nginx# lsof -i:80
and I got:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
docker-pr 28213 root 4u IPv6 64253 0t0 TCP *:http (LISTEN)
and so this process looks like:
root 28213 0.0 0.0 116552 2620 ? Sl 04:34 0:00 /snap/docker/384/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 80 -container-ip 172.17.0.2 -container-port 80
does anybody know what that process is?
I had the same issue.
Stoppping all runing containers and restarting the docker service fixed it for me
service docker restart
and then start your container again
If after you restart the docker service, the docker-pr service allocates some container port, your container is starting automatically.
To check if you have some container running use:
docker ps
To stop this container, we can use:
docker stop container_name
If you have more than one container, we can use:
docker stop $(docker ps -a -q)
To stop a container from starting automatically, we need to remove it from the auto restart.
To do this use the following command:
docker update --restart=no container_name
After this, you will able to restart your docker service and you will not found any container starting automatically.

When to perform host-ip based port mapping like "-p host-ip:port:port"

Docker provides a way to map ports between the container and host.
As per the official documentation its also possible to mention host-ip while port mapping.
-p 192.168.1.100:8080:80 - Map TCP port 80 in the container to port 8080 on the Docker host for connections to host IP 192.168.1.100.
I tried this option to figure out what's the difference with/without the host-ip.
Using just -p 80:80
$ docker run -itd -p 80:80 nginx:alpine
$ curl localhost:80
$ curl 127.0.0.1:80
$ curl 0.0.0.0:80
$ curl 192.168.0.13:80
$ ps -ef | grep docker-proxy
16723 root 0:00 /usr/local/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 8080 -container-ip 172.17.0.1 -container-port 80
$
All the curl commands return the output.
Using host-ip like -p 192.168.0.13:80:80
$ docker run -itd -p 192.168.0.13:80:80 nginx:alpine
$ curl localhost:80
curl: (7) Failed to connect to localhost port 80: Connection refused
$ curl 127.0.0.1:80
curl: (7) Failed to connect to 127.0.0.1 port 80: Connection refused
$ curl 0.0.0.0:80
curl: (7) Failed to connect to 0.0.0.0 port 80: Connection refused
$ curl 192.168.0.13:80 # return output
$ ps -ef | grep docker-proxy
4914 root 0:00 /usr/local/bin/docker-proxy -proto tcp -host-ip 192.168.0.13 -host-port 80 -container-ip 172.17.0.2 -container-port 80
$
All the curl commands failed except 192.168.0.13:80.
Is there any there any other difference apart for the one I mentioned here.
Wondering when to use host-ip based port mapping. Any use cases?
A docker host may have multiple NICs. In the data center, this may be too segregate traffic, e.g. management, storage, and application/public. On your laptop, this may be for wireless and wired interfaces. There are also virtual NICs for things like loopback (127.0.0.1) and VPN tunnels.
When you do not specify an IP in the port publish command, by default docker will bind to all interfaces on the host. In IPv4, this is commonly notated as 0.0.0.0 which means listen on any interface (and this is why I don't connect to this address because there's no such thing as connecting to any IP). With the IP address specified, you manually specify which interface to use. Why would you want to specify this? Several reasons I can think of:
Listening on only 127.0.0.1 to prevent external access
Listening on 0.0.0.0 to explicitly bind to all IPv4 interfaces (it is possible to change docker's default behavior, so this could be necessary for some).
Listening on one physical NIC, allowing other NICs to be bound by other services on the same port.
Listening on only IPv4 interfaces if the app does not work for IPv6.
While there are lots of possible reasons, other than listening on loopback for security, these use cases are very rare and most users leave docker to listen on all interfaces.

Deallocate a port on mac for zookeeper

I know this might have asked before. But I have been struggling with this for last 2 hours.
I am following a tutorial on apache kafka and trying to run this command to run a docker container:
docker run --rm -p 2181:2181 -p 3030:3030 -p 8081-8083:8081-8083 -p 9581-9585:9581-9585 -p 9092:9092 -e ADV_HOST=192.168.99.100 landoop/fast-data-dev:latest
however I am getting this error:
ocker: Error response from daemon: driver failed programming external connectivity on endpoint friendly_austin
(7fe43e4a4081d4ac072a8fbb9582b9456eb71e488fe9a21c358a916061709005): Error starting userland proxy: Bind for 0.0.0.0:2181 failed: port is already allocated.
I am aware this has to do with the allocated port 2181.
So i ran
lsof -i TCP:2181
I got the following pid:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
java 79831 omkar 27u IPv6 0xa390d90220637c69 0t0 TCP *:eforward (LISTEN)
However, I dont understand how can i free this port, or deallocate it? DO i even need to do it?
Help will be much appreciated.
This is a docker error - you cannot map port 2181 of your container as your host already use it
Simply modify this binding:
docker run --rm -p 2182:2181 -p 3030:3030 -p 8081-8083:8081-8083 -p 9581-9585:9581-9585 -p 9092:9092 -e ADV_HOST=192.168.99.100 landoop/fast-data-dev:latest
note the -p 2182:2181
I used 2182 here, you can use an other one
If you ever need to use zookeeper adress, this will be via :2182

Remote debugging JVM in docker on AWS EB

I have a docker image in which I start jstatd -p 1099 and then my Java app. I also expose port 1099 in the dockerfile.
I have deployed this docker image to AWS ElasticBeanstalk and I can see from the EB logs that the port is exposed.
/var/log/docker-ps.log
-------------------------------------
'docker ps' ran at Fri Jun 17 04:23:02 UTC 2016:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d3199a65e216 8b9c53bb10b6 "/app/run.sh" 5 minutes ago Up 5 minutes 1099/tcp, 8080/tcp jolly_carson
I would now like to profile the app using VisualVM. How can I find the correct ip to connect to? Attempts to telnet to the app's domain name on port 1099 time out.
The container's port is not bound to the instance's port, which is good because you don't want to expose your debugging interface publicly. The IP address of the container can be found with:
$ sudo docker ps
$ sudo docker inspect --format '{{ .NetworkSettings.IPAddress }}' <container_id>
Start an SSH tunnel that tunnels from port 5005 locally to that IP address and port 5005 on the box.
$ ssh ec2-user#ec2-54-204-111-222.compute-1.amazonaws.com -L 5005:<ip>:5005 -N
or you can configure port forwarding over iptables
$ sudo docker inspect --format '{{ .NetworkSettings.IPAddress }}' stupefied_swartz
172.17.0.2
$ sudo iptables -t nat -A PREROUTING -p tcp --dport 5005 -j REDIRECT --to-destination 172.17.0.2:5005

Resources