richm
By:
richm

Why can't I connect to this docker container?

February 6, 2017 1.2k views
Docker Networking Ubuntu

I've got a java servlet container running in edgeweb1 which I can access on port 8080 and I can't access 80 or 443 on edgenginx1. Any ideas?

    # docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                      NAMES
    99c26fe2117e        nginx:1             "nginx -g 'daemon ..."   27 minutes ago      Up 27 minutes       0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp   edge_nginx_1
    571ef4787dbc        edge_web            "/tmp/entrypoint.sh"     27 minutes ago      Up 27 minutes       0.0.0.0:8080->8080/tcp                     edge_web_1
    7f0c15522a70        mongo:3             "/entrypoint.sh mo..."   58 minutes ago      Up 27 minutes       27017/tcp                                  edge_db_1

From the docker host:

    # curl localhost:8080
    {"code":404,"message":"HTTP 404 Not Found"}

(The json response means I'm through to the servlet container, a 404 is fine for this).

    # curl localhost:80
    curl: (52) Empty reply from server

I get the same for 443. I've tried using 18080 instead of 80 in case it was something to do with privileged ports. The host is created using docker-machine with the digitalocean driver. The containers are configured with docker-compose and it all works both locally and with the virtualbox driver.

Curiously (to me) on virtualbox docker-machine set things up to run as the docker user, on digitalocean it seems to run as the root user. The iptables rules are very different too, but the digitalocean ones look no different for 80 than 8080.

    # iptables -L -n
    Chain INPUT (policy ACCEPT)
    target     prot opt source               destination

    Chain FORWARD (policy DROP)
    target     prot opt source               destination
    DOCKER-ISOLATION  all  --  0.0.0.0/0            0.0.0.0/0
    DOCKER     all  --  0.0.0.0/0            0.0.0.0/0
    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0

    Chain OUTPUT (policy ACCEPT)
    target     prot opt source               destination

    Chain DOCKER (1 references)
    target     prot opt source               destination
    ACCEPT     tcp  --  0.0.0.0/0            172.17.0.4           tcp dpt:8080
    ACCEPT     tcp  --  0.0.0.0/0            172.17.0.3           tcp dpt:443
    ACCEPT     tcp  --  0.0.0.0/0            172.17.0.3           tcp dpt:80
Chain DOCKER-ISOLATION (1 references)
target     prot opt source               destination
RETURN     all  --  0.0.0.0/0            0.0.0.0/0
2 Answers

@richm

To get a better idea of how things were setup and allow troubleshooting, can you post the details on how and what you used to setup the container? (i.e. build file(s), the compose file, command(s) ran to create, etc) -- as well as any configuration for NGINX.

  • Thanks. This is a snippet of the docker-compose.yml:

    nginx:
      restart: always
      image: nginx:1
      ports:
        - "80:80"
        - "443:443"
      volumes:
        - ./docker/conf.d:/etc/nginx/conf.d
        - ./docker/certs:/etc/nginx/certs/edge
        - ./frontend/target:/usr/share/nginx/html
      links:
        - web
    

    The issue seems to be with the volumes. I was using a file for the first one and it errored on the digitalocean box, so changed it to use a directory and the error went away, but it appears none of the files are present on the nginx container.

    • @richm

      What does the rest of the configuration look like? It's hard to tell where the issue is without knowing how everything was setup beyond the compose file. Testing just the above won't allow me to test it on my end to see if I'm able to reproduce and isolate.

      • Ok. Try this:

        test.yml

        nginx:
          image: nginx:1
          ports:
            - "80:80"
          volumes:
            - ./testconf:/etc/nginx/conf.d
            - ./testhtml:/usr/share/nginx/html
        

        testconf/nginx.conf

        server {
          listen        80;
          server_name _;
        
          location / {
            root /usr/share/nginx/html;
        
            try_files $uri $uri/ @proxy;
          }
        }
        

        testhtml/index.html

        <!DOCTYPE html>
        <html>
          <body>
            <p>Hello</p>
          </body>
        </html>
        
        docker-compose -f test.yml up
        
        • @richm

          That works without any issues for me.

          The only time the above fails is when I have an existing container that's already set with the same forwarding. When that happened, I received:

          ERROR: for nginx  Cannot start service nginx: driver failed programming external connectivity on endpoint dock_nginx_1 (f1b711ceba861d11f3f56db3609275cadbac958ffe49ca675a3e98384c253d3d): Bind for 0.0.0.0:80 failed: port is already allocated
          

          After stopping and removing the container in question and running:

          docker-compose up
          

          The above works without any issues and "Hello" is displayed when I visit the public IP of the Droplet.

          • That's annoying. I've just thrown away the machine, started again and it still does it.

            docker-machine rm edgee
            docker-machine create --driver digitalocean --digitalocean-access-token xxxx --digitalocean-region "ams3" edgee
            eval $(docker-machine env edgee)
            docker-compose -f test.yml up
            
  • This is the error I mentioned using a file (which would normally work for the first volume, but not the others anyway).

    ERROR: for nginx  Cannot start service nginx: oci runtime error: container_linux.go:247: starting container process caused "process_linux.go:359: container init caused \"rootfs_linux.go:54: mounting \\\"/Users/richm/Documents/code/company/edge/docker/conf.d/nginx.conf\\\" to rootfs \\\"/var/lib/docker/aufs/mnt/e2388dac4cc044acceeabd99202c7e4dbace1f713a6870ad2615bf62fa6f2004\\\" at \\\"/var/lib/docker/aufs/mnt/e2388dac4cc044acceeabd99202c7e4dbace1f713a6870ad2615bf62fa6f2004/etc/nginx/conf.d/default.conf\\\" caused \\\"not a directory\\\"\""
    : Are you trying to mount a directory onto a file (or vice-versa)? Check if the specified host path exists and is the expected type
    

@richm

Now if I run the last few commands you provided:

docker-machine rm edgee
docker-machine create --driver digitalocean --digitalocean-access-token xxxx --digitalocean-region "ams3" edgee
eval $(docker-machine env edgee)
docker-compose -f test.yml up

... that doesn't work (using my own token, of course) and the connection fails both locally and when trying to connect from the web to the public IP.

Checking the logs on the container reports absolutely nothing

docker logs edgee

And it appears to be running fine, but it just doesn't respond. I checked the firewall on my end and nothing appears to be preventing the connection, it simply doesn't respond, so I'm trying to see if there's something I'm simply overlooking.

  • Sounds like you've reproduced it then, I think that's good.

    If you run these you should see the volumes issue:

    docker-machine ssh edgee
    docker exec -i -t edge_nginx_1 /bin/bash
    ls /usr/share/nginx/html
    

    i.e. There's no file there, likewise for /etc/nginx/conf.d

    • @richm

      I get the same result.

      Getting NGINX to run and display the default page works, though the volumes that should be mounted and replace the default page don't seem to actually mount, thus allowing the user-configured files to work in place of the default.

      I'll admit, I'm a bit stumped as everything I've looked at is pretty much identical to what you are trying to use and they state it works while it's obviously not for either of us.

Have another answer? Share your knowledge.