Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exposing ports in Docker won't work

I'm trying to setup an automated testing platform with Docker and Selenium Grid. In the diagram below you can see the structure that I'm using. On top is the ubuntu server running on Compute Engine. On the left is a docker container running ubuntu 14.04. The container runs our project on localhost:8080 with Google App Engine. On the right is the Selenium Hub with two nodes running on port 4444.

Docker and Selenium setup

This is the output when running docker ps:

CONTAINER ID        IMAGE                               COMMAND                  CREATED             STATUS              PORTS                     NAMES
f5ac6e3c8270        xxxxx/ubuntuport:14.04              "/bin/bash"              3 days ago          Up 13 seconds       0.0.0.0:32777->8080/tcp   drunk_kalam
4246ca0790db        eu.gcr.io/xxxxxx/selenium-chrome    "/bin/sh -c 'rm -rf /"   4 weeks ago         Up 3 days                                     evil_mahavira
8d06f90a1a84        eu.gcr.io/xxxxxx/selenium-firefox   "/bin/sh -c 'rm -rf /"   4 weeks ago         Up 3 days                                     nauseous_torvalds
dc548f638778        eu.gcr.io/xxxxxx/selenium-hub       "/opt/bin/entry_point"   4 weeks ago         Up 3 days           0.0.0.0:32770->4444/tcp   modest_khorana

As you can see both the hub and the ubuntu container have ports activated, and forwarded from the ubuntu host running the docker containers. I've opened these ports in Google Compute Engine.

In the docker container I'm running our project locally with Google App Engine sdk. After using docker exec -it drunk_kalam bash I activate the App Engine server. The command is run from within the docker container. In the future this will be part of the script, but since this is still a work in progress, it is being run from within the container. Below you can see the project running:

root@f5ac6e3c8270:/# google_appengine/dev_appserver.py --php_executable_path=/usr/bin/php5-cgi --php_gae_extension_path=appengine-php-extension/modules/gae_runtime_module.so ./xxxxxxxxxxxxxxx/
INFO     2016-08-08 12:19:49,287 sdk_update_checker.py:229] Checking for updates to the SDK.
WARNING  2016-08-08 12:19:49,532 simple_search_stub.py:1146] Could not read search indexes from /tmp/appengine.xxxxxxxxxxx.root/search_indexes
INFO     2016-08-08 12:19:49,535 api_server.py:205] Starting API server at: http://localhost:39475
WARNING  2016-08-08 12:19:51,217 inotify_file_watcher.py:196] There are too many directories in your application for changes in all of them to be monitored. You may have to restart the development server to see some changes to your files.
INFO     2016-08-08 12:19:51,218 dispatcher.py:197] Starting module "default" running at: http://localhost:8080
INFO     2016-08-08 12:19:51,220 admin_server.py:116] Starting admin server at: http://localhost:8000

The problem is I can't access the project through port 8080. I've exposed the port in my Dockerfile, and I've tried running the container with the -P flag aswell as the -p 8080 flag. Like this:

docker run -dPi xxxxx/ubuntuport:14.04

I've started the selenium hub with exactly the same command, and this port is accessible. When running the following command:

nmap -p 4444 172.17.0.3

I get the following output:

Nmap scan report for 172.17.0.3
Host is up (0.00010s latency).
PORT     STATE SERVICE
4444/tcp open  krb524
Nmap done: 1 IP address (1 host up) scanned in 0.03 seconds

When I run nmap on 8080 on the docker container running the project I get this output:

Nmap scan report for 172.17.0.2
Host is up (0.000085s latency).
PORT     STATE  SERVICE
8080/tcp closed http-proxy
Nmap done: 1 IP address (1 host up) scanned in 0.03 seconds

I believe the problem is somewhere in the Dockerfile of the ubuntu container. Below you can see the Dockerfile, which is the dockerfile from the official ubuntu repository, with the added EXPOSE 8080 line.

FROM scratch
ADD ubuntu-trusty-core-cloudimg-amd64-root.tar.gz /

EXPOSE 8080

# a few minor docker-specific tweaks
# see https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap
RUN set -xe \
    \
    && echo '#!/bin/sh' > /usr/sbin/policy-rc.d \
    && echo 'exit 101' >> /usr/sbin/policy-rc.d \
    && chmod +x /usr/sbin/policy-rc.d \
    \
    && dpkg-divert --local --rename --add /sbin/initctl \
    && cp -a /usr/sbin/policy-rc.d /sbin/initctl \
    && sed -i 's/^exit.*/exit 0/' /sbin/initctl \
    \
    && echo 'force-unsafe-io' > /etc/dpkg/dpkg.cfg.d/docker-apt-speedup \
    \
    && echo 'DPkg::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };' > /etc/apt/apt.conf.d/docker-clean \
    && echo 'APT::Update::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };' >> /etc/apt/apt.conf.d/docker-clean \
    && echo 'Dir::Cache::pkgcache ""; Dir::Cache::srcpkgcache "";' >> /etc/apt/apt.conf.d/docker-clean \
    \
    && echo 'Acquire::Languages "none";' > /etc/apt/apt.conf.d/docker-no-languages \
    \
    && echo 'Acquire::GzipIndexes "true"; Acquire::CompressionTypes::Order:: "gz";' > /etc/apt/apt.conf.d/docker-gzip-indexes \
    \
    && echo 'Apt::AutoRemove::SuggestsImportant "false";' > /etc/apt/apt.conf.d/docker-autoremove-suggests

RUN rm -rf /var/lib/apt/lists/*

RUN sed -i 's/^#\s*\(deb.*universe\)$/\1/g' /etc/apt/sources.list

CMD ["/bin/bash"]

The command used to expose the port is the same as that of the Selenium Hub, only with a different port number. I can't seem to figure out why this port stays closed. Any help would be appreciated.

Thanks in advance

Tijn

like image 494
Tijn Avatar asked Aug 08 '16 11:08

Tijn


1 Answers

From your output: 0.0.0.0:32777->8080/tcp. That says port 32777 listening on all interfaces will be mapped (with NAT and docker-proxy) to port 8080 inside the container. Therefore you'd need to access port 32777 instead of 8080. This random port mapping happens when you expose a port and share it with -P.

If you want to share a specific port without a random mapping, you can define it with the lower case p option: -p 8080:8080 or even -p 8888:8080 to map port 8888 into port 8080 of the container.


From the chat session, this turned out to be the application listening on loopback inside the container. With netstat -lnt, it showed:

tcp 0 0 127.0.0.1:8080 0.0.0.0:* LISTEN 

Updating the application to bind to 0.0.0.0 allowed the port forwarding to work as expected.

like image 158
BMitch Avatar answered Nov 17 '22 13:11

BMitch