This tutorial assumes you’re deploying an existing app to Heroku, developed using Flask and Python 3 with no database
Deployment is complicated and requires knowledge of a lot of moving parts. Unfortunately, there often is no one-size-fits-all step-by-step tutorial to deploy a given app. Throughout this article, I’ve linked to important background information that may help you debug if things go wrong.
I’ve worked with a lot of students to get Flask projects deployed to Heroku, so I’m quite familiar with the edge cases and things you may forget while doing this. Commonly missed steps have been included as Notes, so pay close attention to them!
This tutorial assumes you’re deploying an existing app to Heroku, developed using Flask and Python 3 with no database. If your app does use a database, this tutorial will probably help with the non-db parts. If you’re using Postgres, read the Heroku guide on the topic.Heroku Postgres
Heroku Postgres is a managed SQL database service provided directly by Heroku. You can access a Heroku Postgres…devcenter.heroku.com
If you aren’t already developing your app in a
virtualenv, make one now (otherwise skip to the next section):
In your project directory, run:
$ virtualenv -p python3 env
Then, activate it:
$ source env/bin/activate
Note: If you close the shell/terminal window make sure to reactivate the virtualenv!
Check to make sure your
pip are using Python 3:
$ pip --version && python --version
You shouldn’t see Python 2.7 anywhere. If you do, something is wonky with your virtualenv, and you need to fix it before moving on.
Run your app. You’ll probably get missing dependency errors, so you’ll need to
pip install those. For example:
$ pip install flask
If this is your first time using a
virtualenv, I’d highly recommend reading about them here.
Packages to install
You will need Gunicorn:
$ pip install gunicorn
Gunicorn is a WSGI HTTP server that’ll handle requests made to your app when it’s deployed. It’s what most folks use to deploy Python apps.
When you’re done, make sure you have pip installed all the correct dependencies with your
virtualenv active, and run:
$ touch requirements.txt
$ pip freeze > requirements.txt
This command will add all of your app’s dependencies to a file, which will tell Heroku what it needs to install. Double-check your new
requirements.txt file. Make sure Flask and Gunicorn are in there and that you didn’t accidentally
pip freeze your entire local Python environment (Heroku will be very displeased with you if you have).
Files for Heroku
Make the following files in the same directory as your main app:
web: gunicorn -w 4 app_file:app_name
The Procfile is for Heroku specifically. Replace
app_file here with whatever your main app file is called. I usually just name mine
app_name is what you named your Flask app, so if your app is in a file called
salmon.py with a line that looks like
aardvark = Flask(__name__), then the last line would look like
However, you most likely have a file called
app.py with a line that looks like
app = Flask(__name__). In that case, your Procfile should simply contain:
web: gunicorn -w 4 app:app
Heroku needs to know which Python version to use. Unfortunately, it doesn’t support every version, so you usually should just use a supported one in development. How to do that is outside the scope of this tutorial, so we’re just going to pick a version. To find out which runtime you have locally, do
python --version. Then, check Heroku’s supported runtime, and pick whichever is closest to yours (but don’t use 2.7).
.gitignore isn’t strictly required but comes highly recommended. If you don’t have one you’ll upload unnecessary stuff from your development environment.
Note: If you’re using SQLite in development, you’ll really want to add that file as well because Heroku doesn’t need it. Plus, having files in your production environment that you don’t need can cause weird bugs down the line.
If you aren’t already using Git for version control, you’ll need to use it for deploying to Heroku (installation instructions).
$ git init
$ git add -A
$ git commit -m "deploying to heroku"
$ heroku login
$ heroku create example-app-name$ git push heroku master
It’s very likely these turned up some errors. If so, check the debugging tips at the bottom. Once you get this working, run:
$ heroku open
Hopefully, that worked, and you have your app deployed! Let me know in the comments what went wrong for you and how/if you fixed it.
Make extra sure that your app is running locally before you tear your hair out getting it to work on Heroku.
The most common type of error message I get when I first deploy Python apps seems to be
pip install errors. They looks a little like this:
remote: Could not find a version that satisfies the requirement pkg-resources==0.0.0 (from -r/tmp/build_1b06c0323986c42337cfd16a42542c2a/requirements.txt (line 11)) (from versions: )
remote: No matching distribution found for pkg-resources==0.0.0 (from -r /tmp/build_1b06c0323986c42337cfd16a42542c2a/requirements.txt (line 11))
remote: ! Push rejected, failed to compile Python app.
If this happens, try editing the version number in your
requirements.txt file. The above error turned out to be a bug related to my operating system, so I just deleted
requirements.txt and tried again.
Note: Another really common (and difficult to diagnose!) error is where one of your modules/files/folders has thesame name as one of the modules Heroku is using. You can tell this is happening by following the
traceback. Try to find errors thrown by code you didn’t write because it tried to call code you did write. The fix for this is, unfortunately, to rename the folders/files that are conflicting.
If you’re deploying data science projects (like tweet generators, for example), you’ll likely see an error like this at some point:
Error R14 (Memory quota exceeded)
That means your app is using too much memory for Heroku, and you either need to optimize your code or up the amount of memory Heroku will let it use.
To see the most recent error messages:
heroku logs --tail
Heroku logs might look confusing, but look for those familiar Python tracebacks. Look for messages like
Python can not find Flask that might indicate something is wrong with your
You can also try turning it off and on again.
To restart your app:
I’ll update this post with more tips as I come up with them.
Photo by Sharon McCutcheon on Unsplash