Lab 8: Introduction to
Web Applications
Web Applications
Part 5: Getting Started
with Heroku (hello world)
with Heroku (hello world)
Table of Contents
If you find typos or problems with the lab instructions, please let us know.
In this part, we'll be learning how to put a simple Hello World web app online using Heroku.
This part just concentrates on all of the Heroku specific stuff. We keep the web app itself very simple so that we can just focus on the new concepts involving Heroku.
You can also come back later and use these same instructions (from Step 4 to the end) to convert any of your other Flask webapps into ones that you can deploy on Heroku.
You can do quite a bit building a Python Flask-based webapp on top of Repl.it. But hosting your web app on repl.it does have some drawbacks
Heroku gives us additional capabilities for hosting web apps beyond what repl.it provides, including:
Keeping apps online longer
Providing logs of errors
Providing a free database platform
In addition, Heroku is often used in professional development environments, especially for prototyping.
Here's the outline:
You'll create a free Heroku account (each pair partner should do this). We suggest using your UCSD account just to keep things simple.
You'll create a very simple flask app, first in repl.it and see it run locally in repl.it first
You'll then see how to connect that app to Heroku and get it running online.
Please visit heroku.com and signup for a free account.
As shown in the animation below, you just have to provide your name and email, nothing more. You can leave “company name” blank. Select "Student" and "Python" when asked about your role, and your preferred development language.
It's probably a good idea to sign up with your ucsd.edu email, because companies such as Heroku sometimes give discounts for folks at .edu addresses, but its up to you.
After going through the initial steps, you'll need to go to your email and confirm your account.
Here's what the email looks like to confirm your account:
Once you click on the link, you'll be asked to set a password, and accept the Terms of Service.
You'll then arrive at this page, which is called the Heroku Dashboard.
You'll need this page frequently, so it's a good idea to memorize the URL: dashboard.heroku.com
For now, you can just leave this page open. We'll need it in a later step.
Before going on:
Be sure that each pair partner (or all three in a trio) completes Step 1 individually.
You can then proceed to Step 2 with just one pair partner driving if you want.
Open this repl, which will take you to a very simple flask example.
https://replit.com/@PhillipConrad/spis2022-lab08-heroku-minimal#main.py
Once there, click the "Fork" button at the top of the Repl.it page, which will create a new Repl.it project for you with the same code. We're going to try and put this simple flask app online in Step 4.
Or, just create a new repl and paste this code into it:
# This repl.it is intended for publishing to Heroku
from flask import Flask
app = Flask(__name__)
@app.route('/')
def helloRoot():
return f'''
<h1>Congratulations!</h1>
<p>You are up and running.</p>
'''
if __name__=="__main__":
app.run(host='0.0.0.0')
You should be able to run the app by clcking the Run button in repl.it.
Check out the mini Repl.it browser window, does it look like it's working correctly? You should see "Congratulations! You are up and running."
Make sure that works. If so, you are ready to try running it on Heroku.
Next, you will need to add the heroku command line to the Shell window of your repli.it, and login.
Those instruction can be found in this tutorial article:
Please follow those instructions, then return to this page and continue with the next step.
You are now ready to create a new app in Heroku.
The first thing you need to do is choose a name. Note that there are some rules for heroku app names:
Must start with a lowercase letter
Must not contain spaces: only lowercase letters, numbers, and the hyphen (-)
No more than 30 characters
Must be globally unique: no other app on Heroku can have the same name.
To help ensure uniqueness, we suggest that you prefix your app names with your pair name from bit.ly/spis2022-pairs, in lowercase.
For example, for this app, we suggest if your pair name is Alex-Chris, we suggest that you use alex-chris-hello as your app name.
If you find that your pair name is really long (e.g. if you are in a trio such as Alexandria-Benjamin-Christina, you might go with a prefix such as spis22-abc instead, so your app name would be spis22-abc-hello.
There are more hints about naming your heroku apps here: Heroku: Naming apps
You can create an new Heroku app using the Heroku CLI and link it to your repl using git, by typing these two commands in the Shell window (assuming you already did the steps to install the CLI and login to your heroku account)
git init
heroku create name-of-your-app
It is important to do the two commands in this order.
Here's what that looks like. Note that we start with the two commands to install the CLI and login (you can skip these if you did them already):
adding the heroku CLI, with heroku -v (pressing Enter when it asks us to select one to run)
then logging in with heroku login -i
We then use git init to initialize a git repository in the repl, and then heroku create name-of-your-app
Afterwards, we use one more command, git remote -v, to show that our repl and Heroku are now linked.
We can now go to the Heroku Dashboard (https://dashboard.heroku.com) and see that our app exists:
It's fairly straightforward to get a Flask web app up an running on repl.it. There are a few extra steps we have to take to get one of these apps ready to run on Heroku.
Here are the four requirements—each of these communicates information that Heroku needs to know how to deploy our app.
You need to install a package called gunicorn, which is a web server that Heroku uses to launch your web app. We'll take care of this in Step 6a below.
You need a file named Procfile — which usually includes just one line of code. We'll take care of this in Step 6b below.
You need file called app.json that specifies the buildpacks used to deploy this application. We'll take care of this in Step 6c below.
You need to change the Python version in the file pyproject.toml to a specific version; we suggest 3.10.6, which is the most current version as of SPIS 2022. We'll describe how to do this in Step 6d below.
Once those four things are taken care of, we can use git commands to deploy the app to Heroku (which we'll do in Steps 7 , 8, and 9).
To install gunicorn, type the following in the Shell window:
python3 -m poetry add gunicorn
The output should look like what you see in the image at right.
We need a file called Procfile in our git repo. This file tells Heroku what to do with our github repo when we push it to github.
Click the + at the left hand side of the repl.it interface to add a new file and call it Procfile
Note: it must be exactly Procfile
upper case P then the rest in lowercase, with no extension.
NOT: procfile, procFile, Procfile.py, Procfile.txt, etc.
It should contain the following:
web: gunicorn main:app --log-file=-
Important: The part of this line that reads main:app assumes that the main python code for your web app is in main.py, and that the variable app is the one that appears in the line of code app = Flask(__name__). If you use a different name for your file other than main.py, or a different variable other than app, you'll need to change the contents of the Procfile accordingly.
Here's what adding the Procfile looks like:
We now need to add a second file called app.json that specifies the "buildpacks" that Heroku uses for our app.
This is described in detail at the following link— you probably don't need to read this, but I'm including the link in case you are curious, or in case we need it to troubleshoot issues: https://elements.heroku.com/buildpacks/moneymeets/python-poetry-buildpack
The file is called app.json, and you add it the same way you added Procfile. Here's what goes inside:
{
"buildpacks": [
{ "url": "https://github.com/moneymeets/python-poetry-buildpack.git"},
{ "url": "heroku/python" }
]
}
Now, find the file pyproject.toml; this is a file that repl.it sets up for you.
Locate these two lines:
[tool.poetry.dependencies]
python = ">=3.8.0,<3.9"
Change them to this:
[tool.poetry.dependencies]
python = "3.10.6"
One you've established that you have a remote called heroku, we are ready to push to Heroku.
However: only the most recent commit gets pushed to Heroku, so it's important that if we've changed anything, we need to do a commit before we try to deploy to Heroku.
Even if we've made changes and seen those changes work when we click Run in the local repl.it environment, those changes will not work on Heroku if we haven't committed them yet.
If you don't remember how to make a commit in repl.it, consult this page of instructions:
Now we need to check that we have a remote called heroku.
If we did the earllier steps in the right order, the git repository in our repl should have a remote called heroku.
A remote is a git repository somewhere else on the internet that our local git repository can push code to, and pull code from
The most common name for a remote is origin; that's the remote that is usually used to refer to a repository on GitHub's servers
We will also have a remote in this instance called heroku; that's the remote we'll use to refer to the git repository on Heroku's servers
To check this, we can type this command in the Shell window
git remote -v
Here's what that looks like if it works properly. If you get something other than what's shown below, scroll down to "What if it git remote -v doesn't work?"
The response in the animation above shows us that the remote heroku points to https://git.heroku.com/phill-aammya-hello-2.git which is the address of the git repo on Heroku that we can push to in order to deploy the application. So we are now ready to deploy.
Note: It's ok if the output also mentions a remote called origin. The important thing right now is that we must have a remote called heroku. So output like this is ok:
If the command git remote -v doesn't show a remote called heroku, here are two possible ways it could have gone wrong, and how to fix each one.
(1) If you see this, it means you didn't make a git repo yet. Type git init in the Shell window, and then try the command again. You'll probably then get output like what's seen in item (2) below.
~/EssentialQuirkyNetframework$ git remote -v
fatal: not a git repository (or any parent up to mount point /home/runner)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).
~/EssentialQuirkyNetframework$
(2) If you get no output at all, like this:
~/EssentialQuirkyNetframework$ git remote -v
~/EssentialQuirkyNetframework$
Or if you get output that only mentions origin but not heroku, like this:
~/EssentialQuirkyNetframework$ git remote -v
origin https://github.com/phconrad/phconrad-test-2 (fetch)
origin https://github.com/phconrad/phconrad-test-2 (push)
~/EssentialQuirkyNetframework$
That means that you didn't set up a remote for Heroku yet.
Normally that happens at the same time you create the Heroku app with the command line, i.e. with
heroku create app-name
But if you already did that, then here's how you can set up the remote after the fact (as long as you are logged in to the heroku CLI in the Shell window.)
heroku git:remote --app app-name
Try that, and then run the git remote -v command again. Here's what that looks like:
To deploy your code, use this command in the Shell window.
git push heroku main to deploy your application.
You can watch the progress in your Shell window.
If you are asked for a username/password, use control-C to stop the command and then first use heroku login -i to reestablish your login session on Heroku.
If you get the message Everything up-to-date, that means that git doesn't want to do a push, because it doesn't think anything has changed. You can create a fake empty commit so that you can push again by typing this in the Shell window: git commit --allow-empty -m "empty" and then you can try again.
After you press “enter” on the git push heroku main command, you’ll see a LOT of output and may take around 5 minutes.
This is the log of heroku doing everything necessary to put your application on the web. You might get errors, and if so, you’ll need to figure out what’s wrong. But, you will likely get some “warnings” that can be safely ignored.
You can also see the progress by going to the Heroku dashboard, going to the page for the app, and going to the Activity tab, and clicking on the most recent deployment, as shown at right.
The image at right shows what it looks like when the build process fails; the error messages shown should also show up in the Console window of your repl, but if you close that window, you can still them here on the Heroku Dashboard.
In theory, the following step should not be necessary—repl.it uses a package manager called poetry, and the steps we've already taken should take care of installing requirements using the poetry package manager.
However, if it doesn't work, there is an older package manager called pip; it uses a file called requirements.txt. Some mentors and students have found that adding a file called requirements.txt with the following contents will make things work on Heroku where the instructions above did not:
gunicorn==20.1.0
Flask==2.2.0
Note that if you go this route, if there are other dependencies later that you need to install for more complex webapps, you may need to add them to this file as well. If you run into issues, you can use the #projects-web channel on the Discord to ask for additional guidance.
New: This document has some additional suggestions for getting things to work on Heroku:
Near the end of the output, what you hope to see is something such as this:
remote: -----> Compressing...
remote: Done: 66.2M
remote: -----> Launching...
remote: Released v5
remote: https://phill-hello.herokuapp.com/ deployed to Heroku
remote:
remote: This app is using the Heroku-20 stack, however a newer stack is available.
remote: To upgrade to Heroku-22, see:
remote: https://devcenter.heroku.com/articles/upgrading-to-the-latest-stack
remote:
remote: Verifying deploy... done.
To https://git.heroku.com/phill-hello.git
7327a71..14006f3 main -> main
~/NervousSaltyActivecell$
Notice the line that says: https://phill-hello.herokuapp.com/ deployed to Heroku
Here, https://phill-hello.herokuapp.com/ is the URL that we can copy/paste in into our browser to see if the application works.
In general, it will be https://your-app-name.herokuapp.com where your-app-name is whatever you called the app when you created it with heroku create your-app-name
So, visit that URL and see if the web app is there.
Congraulations! You've deployed a simple Hello World app to Heroku!
Now that we've got the mechanics of Heroku down, the next step is to deploy something a bit more interesting to Heroku, and start taking advantage of the features it offers us.
That's what we'll do in Part 5.
In that case, here are some things you can do to try to figure out what went wrong:
Go to the heroku dashboard (dashboard.heroku.com), find your app.
At the upper right hand corner there is a button labelled More.
Click it, and you'll see a menu item called View Logs
On that page, you'll see the most recent error messages for the application. Sometimes these will help you understand what went wrong.
If that doesn't help, then try typing this in the Shell window of your repl.it
heroku logs --app my-app-name
You'lll be able to see the most recent errors there. But if you want to see the errors flow by in real time, use this:
heroku logs --app my-app-name --tail
And then refresh the home page of yoru web app again
(e.g. https://my-app-name.herokuapp.com)
In your lab08-name1-name2 repo, in the README.md, add a heading
# Part 5
And under that, put links to:
your repl for the Hello World app that you deployed to Heroku
the URL of the deployed app on Heroku.
The last step is much shorter than the previous ones, so don't worry: you are almost finished with lab08.
Let's move on to Step 6