Heroku is a fantastic service that lets you get your app on the web quickly, for free (with the base model).
If you followed my previous post Django, A Framework for Python Web Apps, then you already have most of the tools you need to publish your work on the web for demoing and testing purposes. The final step is hosting your project on Heroku.
Publishing an update to Heroku is as easy as a git remote push (in fact, that’s all there is to it!) Heroku then recognizes the language you’re using and automatically downloads your dependencies, applies your static content, and builds your website from your repository! There are some limitations surrounding what Heroku refers to as dynos, but the important thing is that you’ll be able to get your project hosted with no startup cost, which is useful for testing, sharing your progress, and even using the finished app. I’ve been hosting and USING my recipes, notes, and chores apps for 6+ months and it hasn’t cost me a single cent.
10 Steps to Hosted!
- Step 1: Pull Your Remote GitHub Repository
- Step 2: Install PostgreSQL and Python-Dev
- Step 3: Set Up and Activate Your Virtual Environment
- Step 4: Install Heroku to your Virtual Environment
- Step 5: Create a Requirements File
- Step 6: Add Packages to the Requirements File
- Step 7: Sign Up for Heroku
- Step 8: Configure Your Project for Heroku
- Step 9: Add to Git and Commit
- Step 10: Apply the Migrations
- Step 11: Actually, It Goes to Eleven
Step 1: Pull Your Remote GitHub Repository
First, let’s pull our repository from GitHub, just so that we can keep it in sync with what we’ll be pushing to Heroku. If you’ve made changes of your own, you’ll want to first move (
mv mysite newname) or delete (
rm -rf mysite) your existing mysite folder. Of course, feel free to use your own project, though you may need to tweak the setup slightly to get Heroku to build it out properly.
mkdir ~/mysite cd ~/mysite git init git remote add origin https://github.com/HelloWorldForBeginners/DjangoHelloWorldDemo.git git pull origin master ls -a
We should see all our files from the GitHub repository, and the git log should have two commits.
Step 2: Install PostgreSQL and Python-Dev
Django projects on Heroku use PostgreSQL by default, so we’ll need to install PostgreSQL on our machine. The library
libpq-dev provides the client-side requirements for a PostgreSQL application. This is not a Python specific library, and has to be installed with
apt-get rather than
We’ll also need the python-dev library in order to run our database adapter.
sudo apt-get install libpq-dev sudo apt-get install python-dev
Step 3: Set Up and Activate Your Virtual Environment
If you haven’t already, you’ll want to create a virtual environment for your project. Otherwise, when we install Heroku, it will install in the base Python environment.
The first command will create the virtual environment, and the second will activate it. Once activated,
(venv) will appear at the start of each command entry line in your terminal window.
NOTE: be sure to add
venv/ to your
.gitignore to avoid adding it to your repository.
virtualenv venv source venv/bin/activate
If you need to disable the virtual environment:
Step 4: Install Heroku to your Virtual Environment
pip install heroku
Step 5: Create a Requirements File
A requirements file captures all of the package requirements for your particular project. It also expedites the package install process by allowing you to install all project package dependencies with a single command, rather than one line at a time. This file can be stored anywhere within your project directory; I prefer to keep it at the root.
First, create the
requirements.txt file by using the following command. This command will capture all current dependencies of your project and store them in a file.
pip freeze > requirements.txt
Step 6: Add Packages to the Requirements File
Next, add the following packages to your requirements file. This method is only really recommended when you want to install a particular package version. Alternately, you can install your packages using
pip install, then save the entries into requirements.txt by using the
pip freeze command mentioned above.
- Django - Python web framework
- psycopg2 - PostgreSQL database adapter
- gunicorn - Python WSGI HTTP server for UNIX
echo "Django==1.9.2" >> requirements.txt echo "psycopg2==2.6" >> requirements.txt echo "whitenoise==1.0.6" >> requirements.txt echo "gunicorn==19.2.1" >> requirements.txt
Step 7: Sign Up for Heroku
Now you’ll need to sign up for Heroku. Write down your password so you can connect your machine’s instance to your account.
Once you’ve signed up, install the Heroku toolbelt.
wget -O- https://toolbelt.heroku.com/install-ubuntu.sh | sh
Now we can login to Heroku through the terminal and create our Heroku app! On the first login, the toolbelt, dependencies, and core plugins will all get set up for you (this may take a few minutes). Once this is done, you’ll be prompted for your email and password.
After you’ve logged in, you can go ahead and create your project on your Heroku account.
heroku create mysite-demo
Our project has been created! Note the web and git urls provided in the output. Very handy! Better yet, Heroku can open your web page in a browser. Just type
heroku open in your terminal.
Now let’s navigate to our Heroku dashboard to set up our database and retrieve the connection details; we’ll need these to set up our app.
From the Dashboard:
- Click your project name.
- On the next page, under the Resources header, type postgreSQL into the search box.
- Choose ‘Heroku Postgres’ and select the ‘Hobby Dev - Free’ option.
- Now you should have a PostgreSQL database provisioned, so click the new link named ‘Heroku Postgres’.
- On the next page, click the database name to view the connection details.
- You will need the password in order to connect, so click show.
- Keep this page open for use in the next section.
Step 8: Configure Your Project for Heroku
Add the Procfile
This file goes in the root of your project, with no extension; it tells Heroku what process to run. Notice that we included the project name after gunicorn. This is so Heroku knows where to find the wsgi.py file.
echo "web: gunicorn mysite.wsgi --log-file -" >> Procfile
Update wsgi.py With Whitenoise
Update the wsgi file to include Whitenoise, which tells Heroku what static files to gather.
cd mysite (venv) ~/mysite/mysite > pico wsgi.py
Add the following line to the imports:
<span class="pl-k">from whitenoise.django <span class="pl-k">import DjangoWhiteNoise
Add the following line after the existing
application = ... line:
application <span class="pl-k">= DjangoWhiteNoise(application)
Update settings.py With Database Settings
Update DB info in
settings.py with your Heroku Postgres information. I used a text editor here instead of pico, just for easy information transfer. The settings.py file is located in your projects PROJECT root folder (named the same as the project by default). In our case, that’s the
DATABASES =  section with your PostgreSQL database credentials. If you use the credentials from my screen shot, strange things might happen, so it’s probably best to use your own (lol, red flag)!
NOTE: Heroku Postgres’ Database field maps to the NAME field in the Django
Step 9: Add to Git and Commit
We’re so close I can taste it. Mmmm… Cheetos dust.
When we created our Heroku project, the toolbelt automatically added a remote for us, which saves us a step. Now, we just need to navigate to the project root, commit, and push the project!
First, though, I’m going to branch my GitHub project to preserve the files as they were before the Heroku setup.
git checkout -b heroku git add --all git commit -m 'branching for heroku configuration' git push origin heroku git push heroku master
Issues Encountered During Heroku Build
I ran into an issue involving my branch. Since the requirements.txt file is currently only on the heroku branch of my git, and Heroku only cares about the master branch, it gets ignored. And as we discovered from the first issue, that file is needed for Heroku to build a Python app. To get around this, we alter the push command slightly, to push our local heroku branch to Heroku’s master branch. I ended up merging the heroku and master branches anyway. It turns out that with all the testing I was doing with the
reset commands, I ended up pushing to GitHub without
view.py hello world configurations! I did warn myself that could happen, so it serves me right.
git push heroku heroku:master
Step 10: Apply the Migrations
You may recall from More Nuts and Bolts of a Django App that we created the database using the migrate command. While it may seem intuitive to run this same command to migrate to our Heroku PostgreSQL database, it turns out that the migrations can’t be properly applied from a remote connection. Certain elements, such as new fields in your model, cannot be applied locally. Attempting to do so will result in a remote database that doesn’t match the models.py file. I learned this the hard way. At one point I had to dump my data into .csv files, completely recreate the database, then re-upload my data in order to get my local version in sync with what was in my Heroku instance.
Fortunately, I discovered that Heroku provides us with a way to run the Django command to migrate to a database from inside the Heroku environment. We can invoke this command on the Heroku server from our terminal window by prefixing it with
heroku run. This tells Heroku to start up an instance on their server and run the command. There’s one more piece, and that’s the app name, which is how Heroku knows what migrations to apply to which app if you have multiple apps. Since we only have one, we don’t have to tell it which app to apply the migrations to.
heroku run python manage.py migrate --app mysite-heroku-demo
Step 11: Actually, It Goes to Eleven
Congratulations! You can now view your app on the web! Simply type
heroku open in your terminal, and a browser will open, pointing you to the root of your project.
But what’s this?! Page not found! Well, that’s because we don’t have a base project URL set up yet. All we set up previously was the /myapp URL. You can also see that the admin URL is available, which Django set up for us by default when we created the project.
Go ahead and tack
/myapp on the end of the URL in your browser bar.
Success! Our web page is on the internet!