Containerized Node server inaccessible with server.listen(port, '127.0.0.1')
Your ports are being exposed correctly but your server is listening to connections on 127.0.0.1
inside your container:
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n'+new Date);
}).listen(1337, '127.0.0.1');
You need to run your server like this:
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n'+new Date);
}).listen(1337, '0.0.0.0');
Note the 0.0.0.0 instead of 127.0.0.1.
Adding EXPOSE 1337 to the docker file
EXPOSE
is mandatory if you want to "expose" that port to other containers.
As BMitch comments:
Expose
isn't needed to publish a port or to connect container to container over a shared docker network.
It's metadata for publishing all ports with-P
and inspecting the image/container.
So:
Running with the
--expose 1337
flag
Not exactly: you need to docker run it with -p 1337:1337
You need either:
- build an image with the
EXPOSE
directive in it (used by-P
) - or run it with the port published on the host
-p 1337:1337
The test curl http://localhost:1337
was done from within the container (no EXPOSE
or publish needed).
If you want it to work from the Linux host, you need EXPOSE+-P
or you need -p 1337:1337
.
Either.
Declaring it expose alone is good for documenting the intent, but does not do anything alone.
For instance:
In that figure, 8080 is EXPOSE'd, published to the Linux host 8888.
And if that Linux host is not the actual host, that same port needs to be fastfowarded to the actual host. See "How to access tomcat running in docker container from browser?".
If localhost does not work from the Linux host, try its IP address:
CID=$(docker run -p 1337:1337 -d node_server)
CIP=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' ${CID})
curl http://${CIP}:1337
Or, as mentioned above, make your server listen from connections coming from any IP: 0.0.0.0
which is the broadcast address or zero network.