Building a Site with Flask... Part 1 - Static Pages and Heroku Hosting

2012-05-04

I have been wanting to build a site that showcases tech posts I write and projects I work on for a while now. I was thinking of using wordpress or writing something in django but those both seemed to be overkill for the simple task I wanted to do. Then I came across Flask, a micro-framework written in Python. This looked like just enough helper code to make things easier while staying out of my way. Boy was I right in my choice. This is the first part of a series talking about building a site. In this part I will talk about setting up Flask, serving static pages and hosting it Heroku.

Setting Up Flask Environment

This post requires that you have a machine with Python, Git, pip and virtualenv installed. I have my setup with my code/git repo in a directory and then my virtual environment in another directory where I test and run my code. You need to create and source your virtual environment with:

virtualenv projectName --distribute 
source bin/activate

Now you will need to install Flask with pip

pip install flask

Building A Flask App Servering Static Pages

The following code below will setup our Flask app and set it to serve index.html on the root url (/). This also serves up any static files that are located in the static directory within our repo. Call this file projectName.py and save it in your git repo.

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')  
def index():
  return render_template('index.html')

Now to run this application you can just run the command below from inside your virtual environment.

python projectName.py

This will running your site accessible at http://127.0.0.1:5000 with the built-in wsgi server.

You might be thinking that this isn’t that exciting, it is just serving up a static HTML page and static media. You are right and this isn’t really that exciting, yet. Now we will throw this up on Heroku so we can actually host our site.

Setting Up Our App on Heroku

First you need to create a Heroku account. Don’t worry for a simple site you can host it on Heroku for free if you just use one web worker. After you create your account you will need to install the Heroku toolkit on your machine.

gem install heroku

Next you will need to log into your Heroku account from your terminal.

heroku login

Now we have Heroku setup on our machine and can start configuring our application stack for Heroku. You can just use the built-in web server with Flask on Heroku but it is recommend to use a different wsgi server such as Gunicorn. So install Gunicorn into your virtual environment.

pip install gunicorn

Now we need to build a requirements file for Heroku so it knows what to install to run our app. Luckily pip makes this very easy. Just run this command from inside to your virtual environment.

pip freeze > 'path to repo'/requirements.txt

The other file we need for our Heroku configuration is a Procfile in our repo. Create that file and add the line below to it.

web: gunicorn projectName:app -b 0.0.0.0:$PORT -w 3

This will have Gunicorn run your app on 0.0.0.0 with the port passed to it from Heroku. Now we can create our Heroku stack. That is easily done by running the next command from inside our project’s git repo.

heroku create --stack cedar

This will add a remote hook for Heroku to your git repo so now we can deploy our code to Heroku.

git push heroku master

Next we need to tell Heroku how many web workers we want for our app. To use Heroku for free hosting use 1 worker. This works fine on low traffic sites and if you need to increase it later that is easily done. Run the following command from your terminal to specify how many workers you want to use.

heroku ps:scale web=1

Now you should be able to see your 1 worker state as ‘up for Xs’ with the following command.

heroku ps

If that shows your worker status as up that means you have your first Flask app up and running on Heroku. Congrats! In the next post I will talk about how to actually make this app do some fun stuff like dynamic pages and caching.