Setup Flask with Apache and wsgi

Why use Apache

Using Apache to serve your Flask App is, in my opinion, the easiest way to move out of development and into production. That is the built-in Flask server isn’t cut out for serving your app to hundreds of people! There are many options available, you can use Apache (like we’re going to do), Nginx, { insert another option here }, or any combination of the tools you can think of. However, I think using Apache is the way to go unless there’s a specific reason something else would be better for your use case! Bonus: Setting up HTTPS using Let’s Encrypt is super easy, I’ll provide a tutorial on that too! Most importantly, we’ll focus on creating a Flask app that runs on Python 3, since Python 2 is on its way out and all.

Server Configuration

We’ll be using Ubuntu 18.04 LTS but feel free to use any distro you wish, just modify the commands accordingly.

1. Install Apache Web Server:

$ sudo apt-get update
$ sudo apt-get install apache2

If you navigate to your server’s internal address you’ll see a “It Works” page.

2. Next, install WSGI, sometimes pronounced “Whiskey,” on podcasts or in polite converstion.

$ sudo apt-get install libapache2-mod-wsgi-py3
$ sudo a2enmod wsgi

You’ll most likely get an “already enabled message here”

3. Now we’ll setup the basic file structure of the app:

$ cd /var/www
$ sudo mkdir FlaskApp
$ cd FlaskApp
$ sudo mkdir FlaskApp
$ cd FlaskApp

4. Now either create the “static and templates” folders “sudo mkdir static templates” or copy them into the directory from your current machine.

5. Now, create (or copy) the “__init__.py” file into the FlaskApp directory, it should be at the same level as the static and templates folders we just created. If you do not have an __init__ file we can create on by running sudo nano __init__.py and placing basic flask code inside.

from flask import Flask
app = Flask(__name__)

@app.route('/')
def index():
   return "I can successfully copy and paste!"

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

6. Next, run the update and upgrade commands again:

$ sudo apt-get update
$ sudo apt-get upgrade

7. We will then set Python 3 as the default Python.

$ ln -sf /usr/bin/python3 /usr/bin/python

Install packages

1. Install pip3:

$ sudo apt-get install python3-pip

2. Install a virtual environment:

$ sudo pip3 install virtualenv
$ sudo virtualenv venv
$ source venv/bin/activate

You will activate the virtual env every time you want to add a new package and/or upgrade an existing one. Notice how the command prompt has change?!

3. Now, let’s install Flask (required for app to run, obviously)

$ sudo pip3 install Flask

You can run “sudo python __init__.py” to check for errors (assuming you’re still in the directory that contains the init file), if no errors are returned it means everything is working and we can proceed to the next step!

WSGI Configuration

1. Open the config file by using:

$ sudo nano /etc/apache2/sites-available/FlaskApp.conf

2. Add in the following lines:

<VirtualHost *:80>
  ServerName yourdomain.com
  ServerAdmin [email protected]
  WSGIScriptAlias / /var/www/FlaskApp/flaskapp.wsgi
  <Directory /var/www/FlaskApp/FlaskApp/>
    Order allow,deny
    Allow from all
  </Directory>
  Alias /static /var/www/FlaskApp/FlaskApp/static
   <Directory /var/www/FlaskApp/FlaskApp/static/>
    Order allow,deny
    Allow from all
  </Directory>
  ErrorLog ${APACHE_LOG_DIR}/error.log
  LogLevel warn
  CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

3. Run the following:

$ sudo a2ensite FlaskApp
$ service apache2 restart

4. Then configure the WSGI file:

$ cd /var/www/FlaskApp
$ sudo nano flaskapp.wsgi

#!/usr/bin/python
import sys
import logging
logging.basicConfig(stream=sys.stderr)
sys.path.insert(0,"/var/www/FlaskApp/")

from FlaskApp import app as application
application.secret_key = 'something super SUPER secret'

We are now, officially complete! Just restart Apache one more time service apache2 restart and enjoy your working site! Remember, any changes to a .py file and you must restart Apache, .html files do not require a restart but you may need to force refresh the browser CTRL + F5 to override the cache!