Note: this tutorial assumes you’ve used SQLAlchemy, a very common flask/python package to help you manage your database.
You’ve probably been working on your application offline for some time, working out the kinks and bugs trying to get it the best it can be. Now, you’re ready to deploy the app, but you’re stuck. Hopefully this guide can help.
We are going to be using Heroku to host our application and make setup very easy to do. We’ll also be adding a Dyno for easy Postgresql setup to the website.
Initial Heroku Setup
First things first, create an Heroku account. Once its setup, you’ll want to create an app. Once your app has been created, let’s add a buildpack. In Heroku, Go to the ‘settings’ tab, because we developed a flask app, we’ll select Heroku’s official Python buildpack.
Now, let’s jump to “resources” in the ‘Add-ons’ search box, search for ‘heroku postgres’ click the very first option. Heroku will setup an environment variable and postgres server for you.
Now, before we move to the next step, I suggest adding your files to a github repository to make this part easy for us and enable automatic deployment of our application whenever we make additional changes.
Under Heroku’s “deploy” tab, lets sync our github repository to enable automatic deployment whenever we submit changes to our github repository. Click “Github” you’ll be asked to sign in to your account and add the respective repository you are working from.
Once you select it, you’ll be given the option to enable automatic deployments. You may receive a ‘build failed’ from Heroku, this is because we enable automatic deployments and we’re not done setting up the application.
Configure Your Flask Application
Now the initial setup for Heroku is done. We need to configure our app to make sure we have everything we need for it to deploy correctly. Create these files in your application, “runtime.txt”, “Procfile”, and “requirements.txt”. These files should be inside the root directory of your app.
Note: Procfile should not have ANY file extension, just create a file called Procfile. Nothing more.
In your “runtime.txt” file, you’re going to want to add the version of python you have been developing with. For me I put:
python-3.7.10
Be careful not to add extra spaces and remember the hyphen.
For the Procfile, we’ll need to install ‘gunicorn’ with it we’ll be able to tell Heroku how to run our app. So, lets do:
pip install gunicorn
After, edit the Procfile, inside we’re going to tell Heroku what file will be used to run the application.
web: gunicorn run:app
The web: gunicorn needs to be added for Heroku, the run:app tells Heroku that the file ‘run.py’ is what will run, you will change the name based on whatever you set the filename to and app tells the location of the file.
Note: if you use “app.py” as the file running your application, please change it, Heroku has an issue with the app:app as the statement, because the names are identical. Hence why we’ve named the file “run.py.”
Getting Your Environment Right
Now let’s go into our Flask applications config.py or wherever you’ve defined your configuration variables. We’ll be changing the variables to match Heroku’s settings.
In Heroku, go to the “settings” tab, there will be a button called ‘Reveal config vars’, this will show you sensitive information of the variables you stored inside of your Heroku instance. You’re going to want to copy the variables Heroku defined into your application. In our case we only have the postgresql DATABASE_URL variable available.
Let’s go to our applications config and add this code. We are using Flask’s application factory for our application, so we defined a class Config.
import os
uri = os.environ["DATABASE_URL"]
if uri.startswith("postgres://"):
uri = uri.replace("postgres://", "postgresql://", 1)
SQLALCHEMY_DATABASE_URI = uri
This code applies a fix and the database variable. The fix is for a recurring issue with how Heroku assigns the unchangeable “DATABASE_URL” variable value as “postgres://…” but SQLAlchemy stopped supporting this way of defining postgres. So we need to change the url string to have “postgresql://…” instead.
You may have added a secret key to your app as well. I recommend adding it as an environment variable to Heroku and then adding it to your config using the os.environ[] method. Like so:
SECRET = os.environ["MY_SECRET_DEFINED_KEY_IN_HEROKU"]
Next let’s quickly create a requirements.txt file, in your terminal/bash inside of your project folder, run this command:
pip freeze > requirements.txt
This will create the file automatically and append all the necessary libraries needed.
NOTE: I came across an issue when creating the requirement.txt file and deploying it. when running the command, sometimes this “work@…..” string gets added after the package name, you’ll have to delete every instance of this to stop the problem when it occurs during the Heroku deployment.
Save these changes to github, you’re ready for deployment.
Time to Deploy!
Okay, most likely your build successfully deployed, but when you visit your app through Heroku, you get an application error! Well, here’s a fix, because we used postgres, its possible that when you started first building your app, you used sqlite as the database engine. Well because we changed the configuration variable. We need, to initiate our database. So let’s go to Heroku, in the top right of the page click ‘more’, then run console.
Type ‘Python’ and hit enter. You’ll be inside the python interpreter, we’re going to retrieve our database and run this command.
With Application Factory Database Setup:
>>> from yourapp import create_app
>>> app = create_app()
>>> app.app_context().push(
>>> from yourapp import db, create_app
>>> db.create_all(app=create_app()) # Creates the database using the defined models in your app.
Without Application Factory Database Setup:
>> from yourapp import db
>> db.create_all()
After this, you should successfully see your app loading and now you have successfully deployed your first app! I hope this guide helped you. Please leave comments on any issues you encountered and any suggestions.