Docker containers work on port 80 only - node.js

I tried this on multiple machines (Win10 and server 2016), same result
using this tutorial:
https://docs.docker.com/docker-for-windows/#set-up-tab-completion-in-powershell
This works
docker run -d -p 80:80 --name webserver nginx
Any other port, fails with
docker run -d -p 8099:8099 --name webserver nginx --> ERR_EMPTY_RESPONSE
Looks like Docker/nginx is listening failing on this port, but failing. Telneting to this port shows that the request goes through, but disconnects right away. This is different from when a port is not being listened to on at all.

There are two ports in that list. The first port is the one docker publishes on the host for you to connect to remotely. The second port is where to send that traffic in the container. Docker doesn't modify the application, so the application itself needs to be listening on that second port. By default, nginx listens on port 80. Therefore, you could run:
docker run -d -p 8099:80 --name webserver nginx
To publish on port 8099 and send that traffic to an app inside the container listening on port 80.

Related

What is port 49160 in docker-run?

I am following this tutorial to set up docker for my node.js rest api and there is this line in the tutorial:
docker run -p 49160:8080 -d <your username>/node-web-app
And this description:
The -p flag redirects a public port to a private port inside the
container. Run the image you previously built:
From the description, I know that port 49160 is a public port and 8080 is a private port. Since I am exposing port 5001 in my nodejs app, so I think I am running:
docker run -p 49160:5001 -d <your username>/node-web-app
But what exactly is a public port? Why is it "49160"?
It can be anything. Tutorial just used a random port. You can change it whatever you want. Then you can access your node-web-app running inside container at port 5001 at localhost:49160 from your host machine.
In your example port 8080 leads to some server (probably web server / Node) located inside of your Docker container. The outside (the host you're working on) port is 49160. The Docker setting named -p connects the inner port 8080 to the outer port 49160. If you now open the browser in your host system and hit the url http://localhost:49160 you will essentially access port 8080 inside the container.
Port 8080 is usually used for web servers. It is not obligatory though.
Port 49160 is just some port you or the auther of the tutorial decided to take as an example.
If you have a server inside the container listening on port 5001 it will not be accessible in your setup. If you want to make it accessible, you could adapt the following command:
docker run -p 49160:8080 -p 49159:5001 -d <your username>/node-web-app

My express https server works locally but not in a docker container

I currently have two docker containers running:
ab1ae510f069 471b8de074c4 "docker-entrypoint.s…" 8 minutes ago Up 8 minutes 0.0.0.0:3001->3001/tcp hopeful_bassi
2d4797b77fbf 5985005576a6 "nginx -g 'daemon of…" 25 minutes ago Up 25 minutes 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp wizardly_cori
One is my client and the other (port 3001) is my server.
The issue I'm facing is I've just added SSL to my site, but now I can't access the server. My theory is that the server needs both port 443 and port 3001 open, but I can't have port 443 open on both containers. I can run the server via HTTP locally, so I think that also points to this conclusion.
Is there anything I can do to have both using https? The client won't talk to the server if the server uses http (for obvious reasons).
Edit:
I'm now not sure if it is to do with port 443, as I killed my client and tried to just run the server, but it still gave me connection refused:
docker run -dit --restart unless-stopped -p 3001:3001 -p 443:443 471b8de074c4
If you open the port 443 for a docker container, it means that a docker-managed tool will be started. This (anyways, highly sup-optimal) tool will forward the TCP requrest to your host port 443 to the container.
If you want two containers to use the port 443, docker would want to start this portforwarder twice, on the same port. As your docker output shows, it could happen only once. Maybe digging (deeply) in the (nearly non-existent) docker logs, you can see also the relevant error message.
The problem you've found is not docker-dependant, it is the same problem what you would face also in a container-less environment - you simply can't start multiple service processes listening on the same TCP port.
Also the solution is coming from the world before the containers.
You need a central proxy service, this would listen on your port 443, and forward the requests - depending on the asked virtualhost - to the corresponding container.
Dig into the docker containers, it is nearly sure that such a https forward proxy exists. This third container will forward the requests where you want. Of course you will need to configure it.
From that moment, you don't even need to have https in your containers (although you can if you want), what helps a lot in productive, correctly certified ssl environments. Only your proxy will need the certificates. So:
/---> container A (tcp:80)
tcp:443 -- proxy
\---> container B (tcp:80)

Accessing database that is running inside a docker container?

I have a MariaDB up and running in a Docker container. I want to know how to connect to it from an app running locally (not) in the docker container. How can I open up access?
your MariaDB container must publish ports, and you will connect using those ports. See for example http://amattn.com/p/installing_maria_db_mysql_with_docker.html
the port 3306 in the container will be mapped to a port on the host, and you will connect to that port.
when you call docker run to start your container you can bind a specific port like this
docker run -p your_port:3306
this will make your container accessible on docker_host_ip:your_port and the docker service will take care of forwarding the connection to the right container at the port 3306

docker connection refused nodejs app

I launch docker container:
docker run --name node-arasaac -p 3000:3000 juanda/arasaac
And my node.js app works ok.
If I want to change host port:
docker run --name node-arasaac -p 8080:3000 juanda/arasaac
Web page is not loaded, logs from browser console:
Failed to load resource: net::ERR_CONNECTION_REFUSED
http://localhost:3000/app.318b21e9156114a4d93f.js Failed to load resource: net::ERR_CONNECTION_REFUSED
Do I need to have the same port both in host and container? It seems it knows how to resolve http://localhost:8080 so it loads my website, but internal links in the webpage go to port 3000 and it's not as good :-(
When you are running your node.js app in a docker container it will only expose the ports externally that you designate with your -p (lowercase) command. The first instance with, "-p 3000:3000", maps the host port 3000 to port 3000 being exposed from within your docker container. This provides a 1 to 1 mapping, so any client that is trying to connect to your node.js service can do so through the HOST port of 3000.
When you do "-p 8080:3000", docker maps the host port of 8080 to the node.js container port of 3000. This means any client making calls to your node.js app through the host (meaning not within the same container as your node.js app or not from a linked or networked docker container) will have to do so through the HOST port of 8080.
So if you have external services that expect to access your node.js at port 3000 they won't be able.

Debug a NodeJS application inside Docker

I'm moving my NodeJS application to docker, and the last problem that I have encountered is debugging the application.
My setup: OSx, boot2docker, docker (based on centos), WebStorm as IDE and debugger.
Here's what I have by now:
Forward 5858 from docker to boot2docker:
docker run -p 5858:5858 ...
Forward 5858 port from boot2docker to host:
VBoxManage controlvm boot2docker-vm natpf1 "boot2docker5858,tcp,127.0.0.1,5858,,5858"
This same setup works to foreword my application ports to host machine.
Port 5858 on the other hand, doesn't seem to react if accessed from outside the docker container.
Inside the docker container it works just fine.
Any idea what can be done to make this work?
Well, I have finally figured it out.
As it seems, node listens only on 127.0.0.1:5858.
To make it listen on all ports, I installed HAProxy on the docker, that forwards the requests from 0.0.0.0:5859 to 127.0.0.1:5858.
Here's the HAProxy configuration if anybody ever needs:
listen l1 0.0.0.0:5859
mode tcp
timeout client 180000
timeout server 180000
timeout connect 4000
server srv1 127.0.0.1:5858
And than add to your Dockerfile:
COPY haproxy.conf haproxy.conf
RUN haproxy -D -f /haproxy.conf

Resources