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:
- We are now limited to what drivers we can use. We cannot use things like the
memorydriver or caching things to the disk because the entire disk will be wiped.
- 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
With all this in mind let’s explain what needs to be done that is Masonite specific.
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.
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.
We’ll need to now specify Gunicorn in our
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
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
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.
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:
We can add that to our Config Vars as a KEY like so:
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:
If we break it down it looks more like this:
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!