In this post, we will be deploying a Flask application using Heroku. Heroku is a popular Platform as a Service (PaaS) that is used to deploy, manage and scale web applications. It comes with a lot of features built-in that abstract away most of the complications involved in traditional web-based deployments. Deployments on Heroku are quick and the platform ensures that you do not have to worry about the infrastructural maintenance headache's that accompany website / server maintenance.
This post assumes that the reader is familiar with the basics of Python and Flask. The post does not include the steps to create an account on Heroku as the process is pretty straightforward.
Our flask application
The application that we are deploying uses some popular flask extensions like
A complete list can be found in the requirements.txt file in the repository. It is critical to have the requirements file in our repository to not only have Heroku install the dependencies
but also because it helps Heroku identify this as a Python project. The application is a website for a fake organic produce startup and contains a few forms wherein a new user can register or an existing user may login. Upon
logging in, the user will be redirected to a feedback page to provide feedback of their most recent experience with the company.
Before we start deploying, let's clone the repository using
git clone https://github.com/AbhishekPednekar84/flask_demo_app.
As we will see later on, Heroku requires us to specify the repository url as part of the deployment process. Now, while
I admit that this repository contains our finished code (with the Heroku specific files) and can be deployed as-is, in a real scenario, we
will probably be working on a local repository and periodically pushing our changes to a remote repository. Since this is a demo, we will not be creating
new branches and will be using the master branch itself. If you are planning to deploy the same demo application, you can push this to your remote
git push -u <your remote repo url>.
Getting started with Heroku
Once logged into Heroku, we will see an option called Create new app on the dashboard. In Heroku nomenclature, a server is called as a dyno, We will be using a free dyno for this demo.
The region can be the United States or Europe. This doesn't matter for our demo application. I've chosen Europe simply because, geographically, my current location is closer to Europe. We will not be adding a pipeline in this example.
On the subsequent page, we will be selecting our deployment method as GitHub. As mentioned in the previous section, this will trigger a build whenever we push changes to our GitHub repository. We will need to authorize Heroku to access GitHub repositories and specify which repository will be used in our current deployment.
Next, we will enable automatic deployments. At this point, I would like to point out that our repository does have continuous integration (CI) configured in TravisCI due to which we will be checking the Wait for CI to pass before deploy box. However, this can be skipped by simply removing the .travis.yml file from the repository. A separate article pertaining to the CI pipeline will be posted soon.
This completes our initial setup on Heroku.
Creating environment variables
For the local deployment, all our environment variables were included in a
.env file (which was deliberately excluded
from the repository). There is however a skeleton file called
.env.example that shows all the attributes that need to
be configured. The values of these attributes are being read into our
Config class in
On Heroku, rather than using a
.env file, we will be creating the environment variables on the dashboard itself. The
first of these will be a connection string to a new Postgres database. To do this, on the Resources section of our
dashboard, we will specify heroku-postgres and provision the database on our free dyno.
Once this is complete, we can see the environment variable containing the connection string by navigating to the Settings and revealing our config variables.
Since we have a few more to add (see
.env.example), we will do that as well. To obtain the reCAPTCHA public and private keys,
one will need to signup for the service on Google and follow the steps.
Here is a final screenshot of this section.
Creating the Heroku
Heroku requires a file named
Procfile that contains all the commands to be executed by an app on startup. The commands
need to be specified using the syntax
<process name>: <command>. Before, we update this file, let's look at how we are exposing
our flask application instance.
app.py file in our project contains a
create_app function which returns our flask application named app. To correctly specify
this in our Procfile, we have a separate module called
wsgi.py containing the following code.
from app import create_app from config import Config app = create_app(config_class=Config)
app instance defined here can be used in our Procfile. For this demo, we will be using
gunicorn as our WSGI server.
So let's first install it using
pip install gunicorn and add it to our requirements using
pip freeze > requirements.txt.
This is the command that will be included in the Procfile -
web: gunicorn wsgi:app This tells Heroku to use the Heroku web process run an
application called app that is present in a module named wsgi using gunicorn.
At this point, if you have worked on these changes locally, they should be pushed to the remote repository using
git push origin master
so that an initial build can be triggered. We can follow the build in the Overview section of the dashboard. Details of
any build errors can be found in the logs - More > View Logs.
Creating our database tables
models.py file in our
models package indicates that the application uses two tables -
To create these on Heroku, we will be using a custom flask command called create_tables present in
The command is created in
app.py as part of the app creation process -
To run this command, navigate to More > Run Console and run the command -
flask run create_tables. If everything runs
as expected, we will simply see a Process Exited message on the console.
Now our app is fully set up and deployed. To run the application, click Open App on the dashboard. The url https://flask-organic-foods-app.herokuapp.com/ was assigned by Heroku. This can be changed with a custom domain name in the application settings.