Docker ports are not exposed

I set up a simple node server in Docker.

Dockerfile

  • docker push to private registry: how not to specify a port
  • Delivering software updates with Docker
  • Docker - SpringConfig - Connection refused to ConfigServer
  • How to bind a shared directory from container to host in Docker
  • Kubernetes - ReplicationController and Persistent Disks
  • Jenkins in Docker: Unable to resolve VCS host
  • FROM node:latest
    RUN apt-get -y update
    ADD example.js .
    EXPOSE 1337   
    CMD node example.js
    

    example.js

    var http = require('http');
    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');
    console.log('Server running at http://127.0.0.1:1337/');
    

    Now build the image

    $ docker build -t node_server .

    Now run in container

    $ docker run -p 1337:1337 -d node_server
    $ 5909e87302ab7520884060437e19ef543ffafc568419c04630abffe6ff731f70

    Verify the container is running and ports are mapped:

    $ docker ps

    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
    5909e87302ab        node_server         "/bin/sh -c 'node exa"   7 seconds ago       Up 6 seconds        0.0.0.0:1337->1337/tcp   grave_goldberg
    

    Now let’s attach to the container and verify the server is running inside:

    $ docker exec -it 5909e87302ab7520884060437e19ef543ffafc568419c04630abffe6ff731f70 /bin/bash

    And in the container command line type:

    root@5909e87302ab:/# curl http://localhost:1337
    Hello World
    Mon Feb 15 2016 16:28:38 GMT+0000 (UTC)
    

    Looks good right?

    The problem

    When I execute the same curl command on the host (or navigate with my browser to http://localhost:1337) I see nothing.

    Any idea why the port mapping between container and host doesn’t work?

    Things I already tried:

    • Running with the --expose 1337 flag

  • Docker when deployed on marathon is failing continously
  • docker cp permissions are wrong when you mount the directory back into container
  • Docker without any https/SSL validation?
  • How to avoid race condition during docker overlay network creation?
  • cannot mount windows directory
  • Deploying Docker image to Kubernetes
  • 2 Solutions collect form web for “Docker ports are not exposed”

    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 publish that port

    Running with the –expose 1337 flag

    Not exactly: you need to docker run it with -p 1337:1337

    You need both:

    • build an image with the EXPOSE directive in it
    • and run it with the port published on the host

    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 and you need -p 1337:1337.
    Both.

    You can only publish a port which has been declared as exposed.
    Declaring it expose alone is not enough.

    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
    
    Docker will be the best open platform for developers and sysadmins to build, ship, and run distributed applications.