Deploying a Flask Project on WebFaction August 23, 2013
I've been thoroughly enjoying my exodus from PHP to Python. My first self-assignment was to develop a Flask project, which came easily enough. The more difficult step was deploying it to WebFaction. The below guide are the steps I took to go from 0 - site, hopefully they'll come in useful.
This guide assumes a few things:
- You have a WebFaction account (you can get one here)
- Your Flask project is using a Virtual Environment (it should be)
- You've already set up your Virtual Environment on your Webfaction server
- You have SSH access to your WebFaction server (if not, get that going here)
Okay, let's get going.
Step 1: Add your site to Your WebFaction Account
I'm going to assume you're familiar with your WebFaction console, so this should be pretty simple:
- Log into your WF Console
- Go to your "Websites" tab, click the "Add New Website" button
- Enter the website name and domains as needed for your project
- Under the Contents section, choose Add an Application > Create a New Application
- Set App Category to "mod_wsgi"
- App Type should be the most recent version of mod_wsgi _that supports your Python version._ Make sure that your Python version matches with your mod_wsgi choice (I used "mod_wsgi 3.4/Python 2.7" for this guide).
- Click the Save button to add that application
- Click the Save button to save your website
Now your WebFaction account should have a new domain, website, and mod_wsgi application.
Step 2: SSH into your new application
First, you'll need to SSH into your webfaction account. Once you're there,
cd into your newly created application:
In this directory, you'll see two folders:
- apache2/ # This contains all of your Apache config and action files - htdocs/ # This is the folder Apache looks into (by default) to launch your project
All following instructions will assume you're still in this directory.
Step 3: Edit apache2/conf/httpd.conf
Using your favorite command line editor, open up the apache2/conf/httpd.conf file:
Load Alias module
You'll see a section where Apache Modules are being loaded. I had to manually add the Alias module to the bottom of the list (shown below).
LoadModule dir_module modules/mod_dir.so LoadModule env_module modules/mod_env.so LoadModule log_config_module modules/mod_log_config.so LoadModule mime_module modules/mod_mime.so LoadModule rewrite_module modules/mod_rewrite.so LoadModule setenvif_module modules/mod_setenvif.so LoadModule wsgi_module modules/mod_wsgi.so LoadModule alias_module modules/mod_alias.so # <-- What I added
Your version of mod_wsgi might not need to add this, but mine did.
Add the following parameters to your
<Directory /home/your_username/webapps/application_name/htdocs> AddHandler wsgi-script .py RewriteEngine On # <-- What I added RewriteBase / # <-- What I added WSGIScriptReloading On # <-- What I added </Directory>
Now for the final edit of the config file.
Finally, at the end of the file, add the following lines:
# This will ensure that www.yourdomain.com/static points to your flask static directory Alias /static/ /home/your_username/webapps/application_name/app/main/static/ # This points to the file that launches our site, which we'll get to next Alias / /home/your_username/webapps/application_name/htdocs/index.py/
Now to upload our files.
Step 4: Upload your Flask project
My prefered Flask structure matches the following format:
- My_Flask_Project - fabfile.py - project/ - config.py - libs/ - main/ - static/ - templates/ - __init__.py - views.py - models.my
I upload my project/ folder to my application directory, and rename it to "app" - I don't really know why I feel the need to rename it, in retrospect:
scp -r ~/flask_files/project webfaction:~/webapps/application_name/app
Now, my ~/webapps/application_name directory list looks like the following:
- apache2/ - app/ - config.py - libs/ - main/ - static/ - templates/ - __init__.py - views.py - models.my - htdocs/
Next, we'll get our project's init file in order.
Step 5: Make sure your init.py file is right
Ensure that, whatever your structure, your project's
__init__.py file is launching your Flask application. In the struct I provided above, this is what my file at
app/main/__init__.py looks like:
from flask import Flask # Setting up the App app = Flask(__name__) app.config.from_object('config') # Importing the views for the rest of our site from main import views if __name__ == '__main__': app.run()
This will work nicely with our htdocs/index.py file, which we'll set up next.
Step 6: Modify the htdocs/index.py file
WebFaction should have created this file. In it are a few scripts, but you can completely remove those. Here is what the
htdocs/index.py file should contain:
import sys # Active your Virtual Environment, which I'm assuming you've already setup activate_this='/home/username/.virtualenvs/venv_name/bin/activate_this.py' execfile(activate_this, dict(__file__=activate_this)) # Appending our Flask project files sys.path.append('/home/username/webapps/application_name/app') # Launching our app from main import app as application
Step 7: Restart Apache
The last step will be to restart apache, like so:
apache2/bin/restart Note: you call this script directly and do not need to source it
If you're having trouble, take a look at your logs in the
~/logs/users/ directory. Often my issues come from my Virtual Envs being misaligned.
Hope this guide helps. Please let me know if I missed an important step, or I'm way off on the process