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
  • 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 .
$ ls

You should now have a directory that looks something like this:

bin     
include  
lib 
public

Next activate the virtual environment by using

$ . bin/activate

The 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())

from flask import Flask
application = Flask(__name__)

@application.route('/')
def index():
    return 'Hello Passenger'

NOTE: Don’t forget to change myappname.domain.com to match the setup you are using.

4. Start the server

Add a folder called tmp with a file named restart.txt

$ mkdir tmp
$ touch tmp/restart.txt

To 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 address mynameapp.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

Other Resources:

I am by no means an expert at Python or Flask, I just like to code in it during my free time. Feel free to correct me on my style of code. Please post any questions or comments.

5 thoughts on “Setting up and deploying Python Flask to Dreamhost

  1. Ben Rousch

    I haven’t played with Flask on Dreamhost for a while. I’m glad to see someone is still keeping up the wiki page.

    Reply
    1. Matt Post author

      @Ben, I wish I could claim credit for the wiki page. I just used that to help me setup my own. I just thought I would do something that is a little bit more detailed.

      Reply
  2. Bill

    Super helpful, I had some trouble, though.

    I wasn’t able to include the flask directly in passenger_wsgi.py
    So my passenger_wsgi.py file is:
    ___
    import sys, os
    INTERP = os.path.join(os.environ['HOME'], ‘mysite.com’, ‘bin’, ‘python’)
    if sys.executable != INTERP:
    os.execl(INTERP, INTERP, *sys.argv)
    sys.path.append(os.getcwd())
    from be import app as application
    ___
    and my be.py is:
    ___
    from flask import Flask
    app = Flask(__name__)

    @app.route(‘/’)
    def index():
    return ‘Hello, World!nFrom Sunny Flask’
    ___

    Took me a few hours to work out that I had to import, but without this post I wouldn’t have gotten even that far.

    Reply
    1. Matt Post author

      Thanks Gopi,

      I’m actually running my site on DigitalOcean now. While Dreamhost was nice for starters I have much more flexibility now than I did before. I’ll try to write a similar tutorial that uses Docker instead when I get some time.

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>