Search code examples
pythonnetwork-programmingflaskport

How do I get Flask to run on port 80?


I have a Flask server running through port 5000, and it's fine. I can access it at http://example.com:5000

But is it possible to simply access it at http://example.com? I'm assuming that means I have to change the port from 5000 to 80. But when I try that on Flask, I get this error message when I run it.

Traceback (most recent call last):
  File "xxxxxx.py", line 31, in <module>
app.run(host="0.0.0.0", port=int("80"), debug=True)
   File "/usr/local/lib/python2.6/dist-packages/flask/app.py", line 772, in run
run_simple(host, port, self, **options)
  File "/usr/local/lib/python2.6/dist-packages/werkzeug/serving.py", line 706, in run_simple
    test_socket.bind((hostname, port))
  File "<string>", line 1, in bind
socket.error: [Errno 98] Address already in use

Running lsof -i :80 returns

COMMAND   PID     USER   FD   TYPE   DEVICE SIZE/OFF NODE NAME
apache2   467     root    3u  IPv4 92108840      0t0  TCP *:www (LISTEN)
apache2  4413 www-data    3u  IPv4 92108840      0t0  TCP *:www (LISTEN)
apache2 14346 www-data    3u  IPv4 92108840      0t0  TCP *:www (LISTEN)
apache2 14570 www-data    3u  IPv4 92108840      0t0  TCP *:www (LISTEN)
apache2 14571 www-data    3u  IPv4 92108840      0t0  TCP *:www (LISTEN)
apache2 14573 www-data    3u  IPv4 92108840      0t0  TCP *:www (LISTEN)

Do I need to kill these processes first? Is that safe? Or is there another way to keep Flask running on port 5000 but have the main website domain redirect somehow?


Solution

  • So it's throwing up that error message because you have apache2 running on port 80.

    If this is for development, I would just leave it as it is on port 5000.

    If it's for production either:

    Not Recommended

    • Stop apache2 first;

    Not recommended as it states in the documentation:

    You can use the builtin server during development, but you should use a full deployment option for production applications. (Do not use the builtin development server in production.)

    Recommended

    • Proxy HTTP traffic through apache2 to Flask.

    This way, apache2 can handle all your static files (which it's very good at - much better than the debug server built into Flask) and act as a reverse proxy for your dynamic content, passing those requests to Flask.

    Here's a link to the official documentation about setting up Flask with Apache + mod_wsgi.

    Edit 1 - Clarification for @Djack

    Proxy HTTP traffic to Flask through apache2

    When a request comes to the server on port 80 (HTTP) or port 443 (HTTPS) a web server like Apache or Nginx handles the connection of the request and works out what to do with it. In our case a request received should be configured to be passed through to Flask on the WSGI protocol and handled by the Python code. This is the "dynamic" part.

    reverse proxy for dynamic content

    There are a few advantages to configuring your web server like the above;

    • SSL Termination - The web server will be optimized to handle HTTPS requests with only a little configuration. Don't "roll your own" in Python which is probably very insecure in comparison.
    • Security - Opening a port to the internet requires careful consideration of security. Flask's development server is not designed for this and could have open bugs or security issues in comparison to a web server designed for this purpose. Note that a badly configured web server can also be insecure!
    • Static File Handling - It is possible for the builtin Flask web server to handle static files however this is not recommended; Nginx/Apache are much more efficient at handling static files like images, CSS, Javascript files and will only pass "dynamic" requests (those where the content is often read from a database or the content changes) to be handled by the Python code.
    • +more. This is bordering on scope for this question. If you want more info do some research into this area.