Search code examples
linuxapiflaskdockerports

Docker Exposing ports for Flask API


Problem Statement

I am running a Flask-based API within a Docker container that is exposed on the port 5000, however no requests are even getting to the API.

To reproduce

  1. Get jupyter/all-spark-notebook docker image
  2. Within the Docker container, get any Flask-based API, for reproducibility purposes try https://github.com/miguelgrinberg/oreilly-flask-apis-video (for understanding a very simple Python-based API switch to v0.1 in releases)
  3. Run the Docker using the standard command as described here (https://github.com/jupyter/docker-stacks/tree/master/all-spark-notebook). Forget about the notebook part, and only use -p 5000:5000 to get the API preferred port to run. Don't use HTTPS, but do install ssh on the container. (So unless you are using a custom Dockerfile like me, you will need to enable SUDO)
  4. Try to make any request to API (e.g. http GET http://localhost:5000/customers/1) --> this fails and gets different error messages depending
    • whether it is Python based urlib request (IOError: ('http protocol error', 0, 'got a bad status line', None))
    • or HTTPie based (http: error: ConnectionError: HTTPConnectionPool(host='localhost', port=5000): Max retries exceeded with url: /filterReplies/aaaaa/aaaa (Caused by <class 'http.client.RemoteDisconnected'>: Remote end closed connection without response))
  5. Check logs, where no record of any API request

Notes

  • I am running on a linux machine so no VM necessary.
  • There is a difference in making a wget http://localhost:5000 (gets Connecting to localhost (localhost)|127.0.0.1|:5000... connected. HTTP request sent, awaiting response... No data received. Retrying.) and wget http://localhost:1234 (gets Resolving localhost (localhost)... 127.0.0.1 Connecting to localhost (localhost)|127.0.0.1|:8888... failed: Connection refused.) so the port is open on some level, but there just does not seem to be anything waiting on the other side?
  • The original purpose of the image still works--i.e. if I specify both ports to be forwarded, I can still have a browser-based access to the Jupyter notebooks within the docker container. So some port forwarding on this machine works.

Solution

  • Binding to 0.0.0.0 will bind your app in any interface available, localhost does not. There is one post that describes the difference between localhost and 0.0.0.0, if I find I will update this post.