3

I have a flask app that runs a couple of things based on the user call. In this app, I also have one basic endpoint that just returns a string which would help me to see if the app is running or not.

@app.route("/hello")
def hello():
    return "Hello World!"

Now I tried to dockerize this app using this tutorial from the official docker site. The flask app listens on the port 5000 and so I added an entry in my Dockerfile to expose the port 5000.

EXPOSE 5000

And the command that I am using in the Dockerfile to run the app is

CMD ["python","model.py"]

model.py file has the flask code that calls other functions based on the user input.

Now when I run my app after containerizing it, I see the required output on the terminal that the flask app is indeed running. This is the command that I used to run the app.

docker run -p 5000:5000 firstContainer

When I try to call the basic helloWorld method above by using the request http://localhost:5000/hello, I get an error message saying that the site is unavailable. Is there anything that I am doing wrong wrt the port mappings here? How do I fix this issue ?

EDIT: Adding more details

So I tried to go into the container to see what's happening and I was able to view the files that were available on the container and they look good. When I tried to start the app again in the container using the base command

python model.py

it returned an error saying that the port is already in use. So this should mean that the app is indeed listening on the port. I also installed curl inside the container to browse the URL and it returned the expected string when I ran it inside the container. I just don't understand how I can expose it to outside world

EDIT 2:

Container logs

 * Serving Flask app "model" (lazy loading)
 * Environment: production
   WARNING: Do not use the development server in a production environment.
  Use a production WSGI server instead.
 * Debug mode: on
kr.wrk
  • 53
  • 1
  • 6
  • Try being more explicit: `docker run -p localhost:5000:5000 firstContainer`. You can also substitute a specific ip address for `localhost` – Paul Oct 24 '18 at 19:54
  • Are you able to reach your app at http://127.0.0.1:5000/hello and how is docker installed/running? What is the value of $DOCKER_HOST? – BMitch Oct 24 '18 at 23:17
  • @BMitch I was not able to reach 127.0.0.1:5000/hello when it running from docker but when I start the app on my host machine, I was able to hit that endpoint. And regarding the $DOCKER_HOST value, I will have to check on that. – kr.wrk Oct 25 '18 at 16:19
  • Note in my question, "127.0.0.1" was not "localhost". – BMitch Oct 25 '18 at 16:46
  • I am not able to reach 127.0.0.1/hello when the app was running on docker. And $DOCKER_HOST returned nothing when I tried to view it using echo $DOCKER_HOST – kr.wrk Oct 26 '18 at 03:46
  • Can you show the actual main function in `model.py`? What about the container logs? – Reut Sharabani Oct 26 '18 at 04:15
  • It is actually the same code that I posted in my first code block in this question. The hello() function that returns "Hello World!" string. I was able to get the expected output when I called this http://localhost:5000/hello endpoint from inside the container. – kr.wrk Oct 26 '18 at 04:19
  • @ReutSharabani added container logs to the main question, it doesn't indicate any contact with host environmnet, it just shows that the app is starting up. It is weird as I entered the container and installed curl and called the hello endpoint. Nothing is logged in it. – kr.wrk Oct 26 '18 at 04:30
  • 1
    If you did not set the host to `0.0.0.0` programatically, CMD may need to be `flask run --host=0.0.0.0` to expose the server. There is also a container running flask behind ngnix out-of-the-box (google: "tiangolo flask docker") – Reut Sharabani Oct 26 '18 at 04:37
  • try the -P option instead of -p, it will choose for you an open port, then you make docker ls -a to view which port has been mapped, it has helped me back in the day! – Manu Oct 26 '18 at 04:42
  • I tried using -P command and when I check the current running containers, I see this in the PORTS column `0.0.0.0:32769->5000/tcp` So does this mean that the app is mapped to port 32769 ? I tried browsing it but still the server was not reachable – kr.wrk Oct 29 '18 at 03:19
  • 1
    @ReutSharabani I had to set the host to 0.0.0.0 to get it working. I somehow missed your comment earlier. Feel free to mention that as an answer so that I can accept it. – kr.wrk Oct 31 '18 at 03:28

3 Answers3

2

The problem is the server defaults to answer internal requests only. You have two options.

You can set the host programatically to:

0.0.0.0

Use the CMD:

flask run --host=0.0.0.0`

Tip: There is also a container running flask behind ngnix out-of-the-box.

Reut Sharabani
  • 30,449
  • 6
  • 70
  • 88
0

try this :

docker run --rm -it --network=host -p 5000:5000 firstContainer

the problem is probably related to networking. so --network=host connects the container to underlying host.

Mehdi
  • 278
  • 4
  • 11
  • When I try this command to start the app on docker, I see that the request will keep waiting for a response from the server i.e. earlier I used to get an immediate error saying that it is unable to connect to the URL. No it keeps on waiting for a response. Any pointers on what is happening under the hood ? Also, after starting the app on docker, I did docker ps in another terminal window. I was able to see this image running but under the ports column, it was showing empty. Is that expected ? – kr.wrk Oct 26 '18 at 03:54
  • make sure you have not set port and host in app.run(....) : if __name__ == "__main__": app.run(host='0.0.0.0', port=80) – Mehdi Oct 26 '18 at 08:01
  • I did set a port number in my app.run() command. I've set it to 5000. Why would it be a problem if I ask my app to listen on a specific port ? – kr.wrk Oct 29 '18 at 03:00
  • if you set it to 5000 that is exactly the port number you expose, it will be ok. I thought you might set different port numbers in app.run and docker expose. – Mehdi Oct 29 '18 at 05:16
  • the actual issue is networking. change --network=host to --net=host and if the problem is still there check your iptables (firewall) and remove all rules. if the problem persists give me your code and dockerfile to check on my laptop. – Mehdi Oct 29 '18 at 21:12
  • With the help of other users in a slack group I m on, I was able to fix the issue. The issue was with the app.run() in flask code. I had to manually set the host value to 0.0.0.0 to get it working. I somehow missed Reut Sherabani's comment which was talking about the same thing. – kr.wrk Oct 31 '18 at 03:27
  • good to hear the problem solved. but in production that a webserver like uwsgi will be running your app, no need to set anything inside app.run() because webservers do not care about app.run(--with whatever inside) – Mehdi Oct 31 '18 at 08:24
0

I have the same issue on my Flask App in the docker container. I have used --network=host and resolved the issue.

# docker run -it -p 8080:8080 --network=host mbilgen/metacriticv3:1.0
WARNING: Published ports are discarded when using host network mode
 * Serving Flask app "main" (lazy loading)
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: on
 * Running on http://127.0.0.1:8080/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 258-420-336
127.0.0.1 - - [12/May/2019 03:55:08] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [12/May/2019 03:55:13] "GET /games HTTP/1.1" 200 -
INFO:werkzeug:127.0.0.1 - - [12/May/2019 03:55:13] "GET /games HTTP/1.1" 200 -
mbilgen
  • 1
  • 1