6
votes

I have apache2 web server running on Ubuntu 14.04. By default when I start apache web server on http://localhost I can see "Apache2 Ubuntu Default Page" which is launched from /var/www/html/index.html file.

I have a flask app at /home/ubuntu/myprojects/ location. The flask app is running on virtualenv and have proper folder structure to render a html file. Below is the folder structure

/home/ubuntu/myprojects/hello/hello.py (flask app rendering a html) /home/ubuntu/myprojects/hello/templates/hello.html

The flask app code is as below:

from flask import Flask
from flask import render_template
from flask import request

app = Flask(__name__)

@app.route('/')
def my_form():
        return render_template("hello.html")

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

When I run http://localhost:5000 the hello.html is rendered. I want to render hello.html from hello.py flask app when http://localhost is called without any port number specified. To do that I added below code:

app.run(host='0.0.0.0', port=80)

But then, when I run the flask app, is exists with error:

 * Running on http://0.0.0.0:80/ (Press CTRL+C to quit)
Traceback (most recent call last):
  File "hello.py", line 21, in <module>
    app.run(host='0.0.0.0', port=80)
  File "/home/ubuntu/myproject/venv/local/lib/python2.7/site-packages/flask/app.py", line 772, in run
    run_simple(host, port, self, **options)
  File "/home/ubuntu/myproject/venv/local/lib/python2.7/site-packages/werkzeug/serving.py", line 618, in run_simple
    test_socket.bind((hostname, port))
  File "/usr/lib/python2.7/socket.py", line 224, in meth
    return getattr(self._sock,name)(*args)
socket.error: [Errno 13] Permission denied

I don't know what I am doing wrong. On http://localhost, the index.html from /var/www/html/ is getting rendering.


In addition to above, when I used mod_wsgi I added below code Added application.wsgi

import os, sys, logging
logging.basicConfig(stream=sys.stderr)

PROJECT_DIR = '/home/ubuntu/myproject/hello'

activate_this = os.path.join(PROJECT_DIR, 'bin', 'activate_this.py')
execfile(activate_this, dict(__file__=activate_this))
sys.path.append(PROJECT_DIR)

from hello import app as application

In /etc/apache2/sites-available/000-default.conf, I added below:

<VirtualHost *:80>
        WSGIDaemonProcess FunRoute user=ubuntu group=root threads=5
        WSGIScriptAlias / /home/ubuntu/myproject/FunRoute/application.wsgi

        <Directory /home/ubuntu/myproject/FunRoute/>
                WSGIProcessGroup FunRoute
                WSGIApplicationGroup %{GLOBAL}
                Order deny,allow
                Allow from all
        </Directory>
</VirtualHost>

Also I changed the hello.py back to :

app.run(host='0.0.0.0')

But then I received 403 Forbidden error when I try to launch http://localhost

Forbidden

You don't have permission to access / on this server.

Apache/2.4.7 (Ubuntu) Server at 52.8.217.39 Port 80
2

2 Answers

5
votes

After little bit for googling I got it resolved.

The Apache 2.4 and above have additional security enabled, where the syntax has changed:

In Apache 2.2 if we want to allow a folder to be accessed, e.g. the site files, then we give below options:

  <Directory /path/to/site/files>
    Order deny,allow
    Allow from all
  </Directory>

But in case of Apache 2.4 we need to give below option:

<Directory /path/to/site/files>
        Options Indexes FollowSymLinks
        AllowOverride None
        Require all granted
</Directory>

This allowed me the access and 403 forbidden error was resolved and also mod_wsgi helped me to create a flask app, which I can access via http://localhost and not http://localhost:5000

2
votes

To start flask on port 80 requires root privileges, but it wouldn't work for you in this case either because Apache is already running on that port, and you can't (generally) have two unrelated processes listening on the same port.

I am assuming you want to do this for general testing/development and one way to do this is to make use of a reverse http proxy which lets you not having to worry about restarting apache all the time when code is changed.

I recommend starting the app on a specific port that is not 5000; try 8000

app.run(host='0.0.0.0', port=8000)

In your default site configuration (it should be /etc/apache2/sites-available/default) you can edit that to include this:

    <Location />
        ProxyPass http://localhost:8000
        ProxyPassReverse  http://localhost:8000
    </Location>

This will take over the root of your default site. If this is not desirable you want to define a separate virtualhost (ideally in a separate file) and then call a2ensite <filename>. Also for the above configuration to function, you will also need to call a2enmod proxy_http. Both those command require root privileges.

For production usage you probably want to use something like mod_wsgi, you can check the list of related questions on the sidebar to help you get started.