Publishing ports using -p does not open any ports

So, as an utter novice, I’m attempting to Dockerize a Java webserver application, and I’ve gotten stuck on what must be something completely stupid. But even searching the forum archives, the only posts I’ve found that have symptoms similar to mine… have zero answers. :sob:

What I need to accomplish is to have this small Java webserver respond to HTTP queries from the host (and, later, from external systems networked to the host). The reason for the ProxyPass in my dockerfile (below) is that, in the final production installation, the host will be running multiple Docker containers that will be available over the LAN by http://HostIP:HostPort/ApplicationName/. My container has to slot into a pre-built server alongside many others, so I have no option to change the overall structure to make this easier – I have to play the cards I’ve been dealt. This seems like it should be an entirely straightforward process, but I’m obviously missing something basic somewhere.

I started with a Java application that functions perfectly inside of STS/Eclipse’s test&debug environment. I exported it as a .WAR file, then built it as a Docker image using the following dockerfile:

FROM tomcat:8.0-jre8
RUN apt-get update && apt-get install -y
supervisor
apache2
&& :
RUN :
&& touch /etc/apache2/mods-enabled/reverse.conf
&& echo “ProxyPass /firstapp/ ajp://localhost:8009/firstapp/” >> /etc/apache2/mods-enabled/reverse.conf
&& a2enmod proxy proxy_ajp proxy_http
&& service apache2 restart
&& :
MAINTAINER test@fanuc.co.jp
COPY ./supervisord/supervisord.conf /etc/supervisor/conf.d/
COPY ./war /usr/local/tomcat/webapps/
CMD [“/usr/bin/supervisord”]

And this supervisord.conf:

[supervisord]
nodaemon=true
logfile=/var/log/supervisor/supervisord.log
pidfile=/var/run/supervisord.pid
[program:tomcat]
command=catalina.sh run
autorestart=true
[program:apache]
command=/bin/bash -c “source /etc/apache2/envvars && exec /usr/sbin/apache2 -D FOREGROUND”
autorestart=true

The build yielded no error messages. Neither does the run, which I’ve performed under multiple -p combinations (more on that below).
I can’t yet find a way to see any of my Java app’s SLF4J logging output (that’s a different problem), but opening a Bash shell inside the container lets me see that ports 80, 8080, 8009, and 8005 are all listening (8080, and maybe 80, are the ones I should get responses from). A ‘ps’ shows me Apache, Tomcat, and Java all running. A curl localhost:8080/firstapp/ returns the web page I expect to see from my Java app. So I can confidently say that everything inside the container is working as expected.

However… on my Windows 7 host, netstat and nmap show none of http ports open, and attempting to point a browser to localhost gives me nothing but “refused connection.”

Now, I’ve tried using docker run -p with 80:80, 8888:80, 8080:8080, 80:8080, 8080:80 (plus more random combinations than I care to admit). For each combination, I try the host-side browser to localhost:port/firstapp/, but always get “connection refused.” I also try netstat and an nmap scan, and never see the host-side port open, regardless of what port number I’ve tried to use.

My full docker run syntax, for one particular port pair:

$ docker run -d -p 888:8080 --name firstapp firstapp:0.0.1

I’ve also tried using the container’s IP address (as shown by docker inspect), with the various port combinations, but that also fails the same as using localhost.

Regardless of my -p option, I never seem to get any port fowarding between the host and container. So my questions are:

  1. What am I doing wrong?
  2. With -p, should I see the Host port open and listening when I use netstat or nmap on the host? Or am I misunderstanding how this works?
  3. Should I be using the expose option in, instead? For what I’m doing, it doesn’t seem necessary, from what I’ve read of the Docker docs – the container already has ports 80 and 8080 open and listening, so exposing them would be redundant, wouldn’t it?

You need EXPOSE 8080 in your dockerfile

“The EXPOSE instruction informs Docker that the container listens on the specified network ports at runtime…”

1 Like

That doesn’t seem to agree with the documentation of the EXPOSE instruction, to wit:

The EXPOSE instruction does not actually publish the port. It functions as a type of documentation between the person who builds the image and the person who runs the container, about which ports are intended to be published

Also, in the meantime, I tried (for lack of any better ideas) to export the Image to a Linux machine I have around, without making any changes whatsoever… and when I spun up the container on the Linux host, everything worked exactly as intended.

So, either there’s some critical difference between running under a Windows host vs a Linux host that I’ve yet to grasp, or there’s something wrong with my Windows host that isn’t obvious.

EDIT: forgot to mention, a colleague suggested that my Docker Quickstart terminal on Windows might lack sufficient privileges to open any listening ports, and this might be causing a silent failure. But when I try to start the terminal under windows with Administrator privileges (which I have the authority to do, it’s just my user account lacks them organically), it fails with a set of VirtualBox error messages (which I can’t copy out, drat it)

1 Like

There are some limitations on using docker Windows containers for localhost. The solution would be pointing your Windows based browser not to localhost:port, but to ip_address:host, on which your docker container is running. You may find IP address of your running docker container by using “docker inspect …”

I tried that too, though. And ended up getting a response from my corporate firewall, even though the Container’s IP was not even on the same subnet as the coorporate LAN. I suspect that this is probably due to how the company DHCP and DNS servers set up my routing tables, but I simply didn’t have time to dig into it in any depth. The IT dept’s response when I asked was “Hm, that’s odd…” :roll_eyes:

I had a similar problem, and I solved it by forwarding the port in the VirtualBox settings for the docker virtual machine (in my case it is called “default”). Example:
Step 1). Use the --publish option to forward port 8080 of the docker container to port 8081 of the docker virtual machine:
docker container run --publish 8081:8080 …
Step 2). In the VirtualBox network settings for the docker virtual machine (NAT mode), configure port forwarding from port 8081 of the docker virtual machine (guest port) to port 8082 of the Windows host machine (host port).