Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deploying a minimal flask app in docker - server connection issues

People also ask

Can I deploy Flask app in Docker?

In this tutorial, we built a simple Flask app and containerized it with Docker. We also deployed the created and pushed the image to Docker Hub as well as the containerized application to Heroku. Just as demonstrated with a Flask application, you can also explore how to containerize other applications here.

Can I deploy Flask on Apache?

Deploy Flask app to apache If you insist on running your own server (with all the maintenance burden), you can do so with Apache. But, life is short and it's easier to use PythonAnywhere. mod_wsgi is an Apache module that provides a WSGI compliant interface for hosting Python-based web applications on an Apache server.


The problem is you are only binding to the localhost interface, you should be binding to 0.0.0.0 if you want the container to be accessible from outside. If you change:

if __name__ == '__main__':
    app.run()

to

if __name__ == '__main__':
    app.run(host='0.0.0.0')

It should work.

Note that this will bind to all interfaces on the host, which may in some circumstances be a security risk - see https://stackoverflow.com/a/58138250/4332 for more information on binding to a specific interface.


When using the flask command instead of app.run, you can pass the --host option to change the host. The line in Docker would be:

CMD ["flask", "run", "--host", "0.0.0.0"]

or

CMD flask run --host 0.0.0.0

Your Docker container has more than one network interface. For example, my container has the following:

$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
32: eth0@if33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

if you run docker network inspect bridge, you can see that your container is connected to that bridge with the second interface in the above output. This default bridge is also connected to the Docker process on your host.

Therefore you would have to run the command:

CMD flask run --host 172.17.0.2

To access your Flask app running in a Docker container from your host machine. Replace 172.17.0.2 with whatever the particular IP address is of your container.


First of all in your python script you need to change code from

app.run()

to

app.run(host="0.0.0.0")

Second, In your docker file, last line should be like

CMD ["flask", "run", "-h", "0.0.0.0", "-p", "5000"]

And on host machine if 0.0.0.0:5000 doesn't work then you should try with localhost:5000

Note - The CMD command has to be proper. Because CMD command provide defaults for executing container.


You need to modify the host to 0.0.0.0 in the docker file. This is a minimal example

# Example of Dockerfile

FROM python:3.8.5-alpine3.12

WORKDIR /app

EXPOSE 5000
ENV FLASK_APP=app.py

COPY . /app
RUN pip install -r requirements.txt

ENTRYPOINT [ "flask"]
CMD [ "run", "--host", "0.0.0.0" ]

and the file app.py is

# app.py
from flask import Flask

app = Flask(__name__)

@app.route("/")
def home():
    return "Hello world"


if __name__ == "__main__":
    app.run()

Then compile with

docker build . -t deploy_flask

and run with

docker run -p 5000:5000 -t -i deploy_flask:latest

You can check the response with curl http://127.0.0.1:5000/ -v