March 14th, 2018, posted in #howto
A few weeks ago I had to deploy a website on Heroku. We built it on Laravel with the help of our handy open source admin panel Backpack. Sounds like a simple job, right? Wrong. I started at 5 pm and worked well past the midnight. Of course, the client had a launch event next day in the morning.
Because I don’t want to repeat this horrible experience on future app launches, I wrote this practical guide on how to deploy Laravel apps on Heroku. Maybe it will also save you hours of frustration.
Note! This applies mostly to Laravel 5.4
Also note! This guide assumes you will use a pipeline for deploy that automatically builds and deploys every push in the master branch of your repo.
The essential steps to swiftly deploy your Laravel app on Heroku
1. Create the Procfile and add it to your repo. The content should look like this:
web: vendor/bin/heroku-php-apache2 public/
2. Set up the ENV variables. You can do this using Heroku cli and entering this command line:
heroku config:add APP_KEY="base64:enter_your_key" --app
or from Heroku interface by selecting the app and going to Settings -> Config Variables -> Reveal
3. Update the log setting to errorlog. Put this in the app config file:
'log' => 'errorlog'
Pro tip: Add Papertrail add-on to your app to see the log in real time.
For more detailed info on how to get started with Laravel on Heroku you can go trough this official article.
Now the real gold nuggets I learned the hard way
1. The Heroku database is usually in Postgres. And there are a few differences from MySql: char fields, enum fields etc. So you better build the project directly on Postgres.
2. The database config file on Larvel should look like this:
'host' => getenv("DATABASE_URL") ? parse_url(getenv("DATABASE_URL"))["host"] : '', 'port' => getenv("DATABASE_URL") ? parse_url(getenv("DATABASE_URL"))["port"] : '', 'database' => getenv("DATABASE_URL") ? substr(parse_url(getenv("DATABASE_URL"))["path"], 1) : '', 'username' => getenv("DATABASE_URL") ? parse_url(getenv("DATABASE_URL"))["user"] : '', 'password' => getenv("DATABASE_URL") ? parse_url(getenv("DATABASE_URL"))["pass"] : '',
3. Heroku relies on composer.lock to build the environment and pull the required packages. So if you need some libraries or extensions that are not built-in (e.g. gd library for images) and you cannot add them to your composer.json you can add them manually to the composer.lock file. Here is a step by step guide. Also, here you can find a list of available extensions for Heroku.
4. Symlinks do not work. So don’t use the storage folder to save resources, better use a CDN.
5. You can add a free app in Heroku to test you project.
6. You can use iseed package to create seed files in order to populate your database.
7. You can run commands with Heroku CLI. For example, Artisan commands can be called like this:
heroku run "php artisan migrate" --app heroku-app-name
That’s all folks! I wish you easy deployment.