Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Docker Desktop for Windows: cannot access service on exposed port in windows container mode

I am using the following Dockerfiles to create a container running Jenkins in a windows container on Windows 10 desktop running Docker Desktop for Windows version 17.03

FROM microsoft/windowsservercore

RUN powershell -Command wget 'http://javadl.oracle.com/webapps/download/AutoDL?BundleId=210185' -Outfile 'C:\jreinstaller.exe' ; Start-Process -filepath C:\jreinstaller.exe -passthru -wait -argumentlist "/s,INSTALLDIR=c:\Java\jre1.8.0_91" ; del C:\jreinstaller.exe

ENV JAVA_HOME c:\\Java\\jre1.8.0_91  
RUN setx PATH %PATH%;%JAVA_HOME%\bin

CMD [ "java.exe" ]

I create the image from this docker file:

docker build -t windows-java:jre1.8.0_91 .

The second Dockerfile I am using to install Jenkins on top of this:

FROM windows-java:jre1.8.0_91

ENV HOME /jenkins  
ENV JENKINS_VERSION 2.58  
RUN mkdir \jenkins  
RUN powershell -Command "wget -Uri https://updates.jenkins-ci.org/latest/jenkins.war -UseBasicParsing -OutFile /jenkins/jenkins.war"

EXPOSE 8080  
EXPOSE 50000  

CMD java -jar C:\\jenkins\\jenkins.war


docker build -t jenkins-windows:2.0 .

Then I launch the container like this:

docker run --name jenkinsci -p 8080:8080 -p 50000:50000  jenkins-windows:2.0

I can see the container running fine and logs showing up all good

PS C:\Users\mandeep\ringba\ringba-jenkins-setup-windows\jenkins-master> docker ps
CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS              PORTS                                              NAMES
85ba2ef525a1        jenkins-windows:2.0   "cmd /S /C 'java -..."   8 hours ago         Up 8 hours          0.0.0.0:8080->8080/tcp, 0.0.0.0:50000->50000/tcp   jenkinsci

However, I cannot access the jenkins server running on http://localhost:8080 on the host machine's web browser.

Not sure if it helps but when I was running docker in Linux container mode on the same machine, I was able to access jenkins server on http://localhost:8080 using their official docker image.

like image 242
Mandeep Singh Avatar asked May 03 '17 20:05

Mandeep Singh


People also ask

How do I access exposed port Docker?

There are several ways to do this: you can expose a port via the --expose flag at runtime, or include an EXPOSE instruction in the Dockerfile. You can also publish ports by using the -p or -P flags in the Docker run string. There's also container linking via --link .

Can I run a Windows service in a Docker container?

Docker containers (for simplicity, containers) can run natively on Linux and Windows.

What does it mean to expose a port in Docker?

The EXPOSE instruction exposes a particular port with a specified protocol inside a Docker Container. In the simplest term, the EXPOSE instruction tells Docker to get all its information required during the runtime from a specified Port. These ports can be either TCP or UDP, but it's TCP by default.


2 Answers

This is a currently a known issue on Windows. It's not possible to access a container endpoint from its own host using localhost/127.0.0.1. It is possible using Linux containers today because Docker has included a special workaround that is unique to their Moby/Linux implementation for running Linux containers on Windows.

We're working on a fix for this, but today we recommend working around this by either:

  • Accessing container endpoints from a separate host, using the IP address of the host that is running the container, and the exposed port for the container on its host
  • OR by accessing the container on the same host, using the container's internal IP address and published port (you can use docker network inspect <network name> or docker exec <container ID> ipconfig> to get the IP address of the container endpoint itself)
like image 75
Kallie-Microsoft Avatar answered Sep 20 '22 09:09

Kallie-Microsoft


To complete @Kallie-Microsoft post:

docs.docker.com have been updated with a section Limitations of Windows containers for localhost and published ports


Docker for Windows provides the option to switch Windows and Linux containers. If you are using Windows containers, keep in mind that there are some limitations with regard to networking due to the current implementation of Windows NAT (WinNAT). These limitations may potentially resolve as the Windows containers project evolves.

One thing you may encounter rather immediately is that published ports on Windows containers do not do loopback to the local host. Instead, container endpoints are only reachable from the host using the container’s IP and port.

So, in a scenario where you use Docker to pull an image and run a webserver with a command like this:

docker run -d -p 80:80 --name webserver nginx

Using curl http://localhost, or pointing your web browser at http://localhost will not display the nginx web page (as it would do with Linux containers).

In order to reach a Windows container from the local host, you need to specify the IP address and port for the container that is running the service.

You can get the container IP address by using docker inspect with some --format options and the ID or name of the container. For the example above, the command would look like this, using the name we gave to the container (webserver) instead of the container ID:

$ docker inspect \
  --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' \
  webserver
like image 39
Alexandre Roux Avatar answered Sep 19 '22 09:09

Alexandre Roux