Setting up and deploying Python Flask to Dreamhost
I have a few applications I have written that run on Flask. Every time I would go to deploy a new application I would always seem to forget one of the minor details and end up with the ugly An error occurred importing your passenger_wsgi.py
The following are the steps I use to deploy Flask to Dreamhost using Passenger. I haven’t tested it, but this should be roughly the same steps if you want to deploy directly to your domain instead of using a subdomain.
TL;DR; (Quick Setup)
- add a new subdomain on the dreamhost web panel
- cd myappname.domain.com
- git clone https://github.com/icecreammatt/flask-passenger.git .
- virtualenv .
- . bin/activate
- easy_install flask
- git submodule init
- git submodule update
- Replace
myappname.domain.com
in passenger_wsgi.py with your folder path. - touch tmp/restart.txt
- DONE!
Part 1 - Setup Domain
- Go to Manage Domains after logging into the Web Panel
- Add New Domain / Sub-Domain
- Domain to host: I like to use subdomains a lot of testing and the different Flask apps I run, so I tend to use
myappname.domain.com
Obviously swap out myappname.domain.com with your own names. - (Optional) Check remove WWW
- If you have more than one user account make sure to pick the correct one.
- Web directory should fill out automatically for you
- Passenger (Ruby/Python apps only): Check this box
- Domain to host: I like to use subdomains a lot of testing and the different Flask apps I run, so I tend to use
- Fully host this domain!
- SSH into your web server and wait a minute or two for the myappname.domain.com folder to appear
- cd into myappname.domain.com
Part 2 - Install Flask with Passenger
1. Setup a virtualenv
First we need to setup the virtual environment$ virtualenv . $ lsYou should now have a directory that looks something like this:
bin include lib publicNext activate the virtual environment by using
$ . bin/activateThe command line should now show up something like this:
(myappname.domain.com)myappname.domain.com $
2. Install Flask
$ easy_install flask
3. Setup passenger
Create a file named passenger_wsgi.py with the following:NOTE: Make sure to hand type this, as pasting the tabbed lines from the browser can translate to spaces which will evaluate incorrectly.
import sys, os INTERP = os.path.join(os.environ['HOME'], 'myappname.domain.com', 'bin', 'python') if sys.executable != INTERP: os.execl(INTERP, INTERP, *sys.argv) sys.path.append(os.getcwd())NOTE: Don’t forget to change myappname.domain.com to match the setup you are using.from flask import Flask
application = Flask(__name__)
@application.route('/') def index(): return 'Hello Passenger'
4. Start the server
Add a folder calledtmp
with a file named restart.txt
$ mkdir tmp $ touch tmp/restart.txtTo restart the Flask application after making changes you need to update the restart.txt file. This can easily achieved by doing a touch tmp/restart. (For my projects I add a post-receive hook into my git repo to touch the file for me).
The directory should now look something like this:
bin include lib passenger_wsgi.py public tmp
5. Test
At this point you should be able to hit the server addressmynameapp.domain.com
from the browser and see 'Hello passenger'
Part 3 - Deploying a real app
1. Clone sample project from github https://github.com/icecreammatt/flask-empty.git
$ pwd /home/username/myappname.domain.com $ git clone https://github.com/icecreammatt/flask-empty.git myappname
1. Adjust passenger_wsgi.py
Now that the basic stuff is in place a real application can be setup.Edit passenger_wsgi.py
so it now contains
import sys, os INTERP = os.path.join(os.environ['HOME'], 'myappname.domain.com', 'bin', 'python') if sys.executable != INTERP: os.execl(INTERP, INTERP, *sys.argv) sys.path.append(os.getcwd()) sys.path.append('myappname') from myappname.app import app as application
Note: Make sure if you copy this to tab os.excl… since it will copy as spaces and cause a runtime error.
Restart Flask
$ touch tmp/restart.txt