loading...
Masonite

Deploying a Masonite Application to Heroku

josephmancuso profile image Joseph Mancuso Updated on ・5 min read

Introduction

Ok so you have an awesome and badass application that you built with Masonite. Maybe its a SaaS or the next Instagram. Before you start cutting your checks, you’ll need to deploy it somewhere.

Heroku makes for an excellent deployment system for Masonite because Heroku’s CLI tool makes it simple to communicate with you Heroku application and deploying WSGI apps to Heroku is dead simple.

Masonite is just a WSGI application. This means that most tutorials from Heroku about WSGI deployments can be follows closely and still work well with only minor adjustments.

A few things to note

Heroku is an interesting deployment platform. Heroku is what is called an “ephemeral” system. This means that randomly, every few hours a few days, the entire application is wiped and put somewhere else on the internal Heroku infrastructure.

This means several things:

  1. We are now limited to what drivers we can use. We cannot use things like the memory driver or caching things to the disk because the entire disk will be wiped.
  2. Everything will need to be self contained inside the repository. Meaning we can’t install masonite-cli on the system. This will have to be a dependency for our application so even when our app is shifted to another server on Heroku (because of how Heroku works) our masonite-cli follows.

Getting Started

With all this in mind let’s explain what needs to be done that is Masonite specific.

Drivers

Make sure all drivers are setup in a way that will work on Heroku's ephemeral system. Masonite was built with Heroku in mind so all of Masonite's features have a driver that will work on an ephemeral system. For example we won't be able to use the memory session driver but instead need to use the cookie session driver (which will encrypt and set session data on the client browser).

All drivers are set up correctly for an ephemeral system out of the box so you shouldn't need to worry about this unless you have changed it during development.

Procfile

Heroku has this concept of a Procfile which is just a file that explains how Heroku should deploy our application.

We just just create a simple Procfile in the root of our directory structure where wsgi.py is located:

We are going to be using Gunicorn to deploy our WSGI application so inside this Procfile should be a simple line of text:

web: gunicorn wsgi:application

It might be useful to specify the number of workers, though:

web: gunicorn -w 2 wsgi:application

Once that is done we can submit that to source control.

Requirements.txt

We’ll need to now specify Gunicorn in our requirements.txt file.

We should also peg these versions to a specific version to prevent Heroku from upgrading our dependencies:

waitress==1.1.0
masonite==2.0.9
gunicorn==19.9.0

Perfect. If you are connecting to a database then you’ll also need to specify a database driver. You likely installed one as you need one while development but we’ll need to specify one here now because of Heroku’s ephemeral system again. You will likely be using Postgres but feel free to install any database driver you need:

waitress==1.1.0
masonite==2.0.9
gunicorn==19.9.0
psycopg2==2.7.5

Also you likely want to be running craft commands using the heroku run CLI command.

So let’s install masonite-cli. There is a caveat here that masonite-cli might require a different cleo version based on the version of masonite-cli that you have. So we can add that here:

waitress==1.1.0
masonite==2.0.9
gunicorn==19.9.0
psycopg2==2.7.5
masonite-cli==2.0.10

If you get an error for an incompatible cleo version then you should add that cleo version right above the masonite-cli dependency:

waitress==1.1.0
masonite==2.0.9
gunicorn==19.9.0
psycopg2==2.7.5
cleo==0.6.5
masonite-cli==2.0.10

Great! Now we can do things like:

$ heroku run craft migrate

Database (optional)

If you are deploying an application WITHOUT a database then everything above should be fine for you. You can deploy your application now (via the next section on deploying).

If you are deploying an application that does need a database then I suggest you use Heroku’s Postgres database. It has a very generous free plan to just get your application up and running and you can also upgrade to a larger database later.

This is Heroku specific so you can follow their documentation on their site here on how to get a Postgres database deployed: Heroku Postgres | Heroku Dev Center

Deployment

We can now deploy your application! This is also Heroku specific so read the documentation here: Deploying with Git | Heroku Dev Center

It would e too redundant to copy and paste the instruction here so be sure to give that a read.

Environment Variables

Ok this section is important! Since we can’t add environment variables to the system itself (again, because of Heroku) so we will need to add them all to the dashboard inside Heroku.

We can add all environment variables in the Heroku dashboard under the Dashboard>Your-App-Name>Settings>Config Vars. Heroku calls them Config Vars but they are just environment variables really.

Again, if you are not deploying with a database then you really only need a KEY environment variable.

You should generate a new key for production only but feel free to use the key inside your .env file if you want them to be the same:

$ craft key

This will generate a new key:

KEY CQxnLONbVOO67gy2MWULKJPWXzZiEgyA1x36qnu3iYs=

We can add that to our Config Vars as a KEY like so:

Database Configuration

If you are running a database then you will need to break that DATABASE_URL Config Var into separate environment variables that Masonite uses.

Heroku generates a big string called a DATABASE_URL that looks like this:

postgres://user3123:passkja83kd8@ec2-117-21-174-214.compute-1.amazonaws.com:6212/db982398

If we break it down it looks more like this:

postgres://DB_USERNAME:DB_PASSWORD@DB_HOST:DB_PORT/DB_DATABASE

So broken down again we would need to add these as Config Vars:

DB_USERNAME = user3123
DB_PASSWORD = passkja83kd8
DB_HOST = ec2-117-21-174-214.compute-1.amazonaws.com
DB_PORT = 6212
DB_DATABASE = db982398

We’ll also need to add our driver we are using:

DB_DRIVER = postgres

By default there APP_DEBUG environment variable will be set to False internally if no environment variable is found. For a while you might want to set it to true so you can see any errors you have while testing to make sure everything works. We can set that to True:

APP_DEBUG = True

Your final Config Vars will look something like this:


Congratulations! You now have an awesome Masonite application ready to deploy!

Posted on by:

josephmancuso profile

Joseph Mancuso

@josephmancuso

Creator of the Masonite Framework NY Software Developer.

Masonite

The modern and developer centric Python web framework that strives for an actual batteries included developer tool with a lot of out of the box functionality with an extremely extendable architecture.

Discussion

markdown guide