DEV Community

Connor Leech
Connor Leech

Posted on • Edited on

Deploy a Laravel 5 app to Heroku

Heroku is an awesome platform originally built on top of AWS and currently owned by Salesforce. Laravel is a powerful PHP web framework for building applications.

In this short tutorial we're going to generate an app from laravel-5-boilerplate and deploy it to Heroku.

By the end of the tutorial we will have a user management and permission system built with Laravel, Bootstrap and live to the internets powered by Heroku.

If you prefer to have a generic Laravel 5 app instead of a massive boilerplate follow this gist. Besides step 1 everything else will be the same.

Without further ado, let's get started.

Steps:

  • Download Laravel 5 Boilerplate according to the Quick Start Documentation. Also git init for the project.

  • Create a local MySQL database for development:

$ mysql -uroot -p
> create database MY_DATABASE_NAME;
Ctrl-C to exit
Enter fullscreen mode Exit fullscreen mode
  • Create a Procfile to teach Heroku how to boot up our app:
$ echo web: vendor/bin/heroku-php-apache2 public/ > Procfile
Enter fullscreen mode Exit fullscreen mode
  • Create a Heroku app. You will need the Heroku CLI installed.
$ heroku create YOUR_APP_NAME
Enter fullscreen mode Exit fullscreen mode
  • Add a PHP buildpack:
$ heroku buildpacks:set https://github.com/heroku/heroku-buildpack-php
Enter fullscreen mode Exit fullscreen mode
  • Add MySQL to our Heroku project:
$ heroku addons:add cleardb
Enter fullscreen mode Exit fullscreen mode

This creates a config variable called CLEARDB_DATABASE_URL which you can view using the following command. Add CLEARDB_DATABASE_URL to our .env file.

$ heroku config | grep CLEARDB_DATABASE_URL
Enter fullscreen mode Exit fullscreen mode

Modify config/database.php so that we connect to our Heroku database.

<?php

$url = parse_url(getenv("CLEARDB_DATABASE_URL"));

$host = $url["host"];
$username = $url["user"];
$password = $url["pass"];
$database = substr($url["path"], 1);

return [
    ...
    'connections' => [
        'mysql' => [
            'driver' => 'mysql',
            'host' => env('DB_HOST', $host),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', $database),
            'username' => env('DB_USERNAME', $username),
            'password' => env('DB_PASSWORD', $password),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'strict' => true,
            'engine' => null,
        ],
Enter fullscreen mode Exit fullscreen mode
  • Set an heroku config variables. Remember, your .env file is not checked into version control so we need to let heroku know about our specific config.:
$ php artisan key:generate --show
$ heroku config:set APP_KEY=app_key_goes_here
$ heroku config:set APP_URL=your_app_name.herokuapp.com
Enter fullscreen mode Exit fullscreen mode

Push to Heroku.

When we created the heroku app through the CLI it automatically added a git remote called "heroku". We can push our code to a Heroku server using this git remote.

$ git remote -v 
$ git add -A
$ git commit -m 'heroku deployment stuff'
$ git push heroku master
$ heroku open
Enter fullscreen mode Exit fullscreen mode

The first command displays the git remotes available to you. The next command adds everything into git including new or deleted files. Then we commit and push. The final command will open your new Laravel heroku app in the browser.

Database stuff

We added a ClearDB database but we have not run our migrations to create our tables. To do this we can run

$ heroku run php artisan migrate
Enter fullscreen mode Exit fullscreen mode

There is a common error many people experience (outlined above)
Now that SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes. Fortunately, Eric Barnes has a solution outlined in this post.

Head into app/Providers/AppServiceProvider.php and add a default string length to the boot method:

use Illuminate\Support\Facades\Schema;

...

public function boot()
{
   Schema::defaultStringLength(191);
}
Enter fullscreen mode Exit fullscreen mode

Commit this change and push to heroku. In order to get our database set up without issue try this command:

$ heroku run php artisan migrate:reset 
Enter fullscreen mode Exit fullscreen mode

If you run a plain old php artisan migrate first the terminal will sqwuak that SQLSTATE[42S01]: Base table or view already exists. Running reset successfully runs our migrations.


SSL/HTTPS stuff

I wrote a more thorough guide on setting up HTTPS through SSL certificates for a custom domain on Medium. For some reason Laravel apps will display HTTP urls which the browser will mark as "Not Secure". Heroku uses https:// by default for deployments. Loading pages over http:// could give us a Mixed Content, insecure stylesheet or insecure script error.

One fix for this is to configure Laravel to load assets over HTTPS in production. To do this, head into App/Providers/AppServiceProvider.php and configure to load everything over HTTPS in production:

use Illuminate\Support\Facades\URL;

...

// Force SSL in production
if ($this->app->environment() == 'production') {
    URL::forceScheme('https');
}
Enter fullscreen mode Exit fullscreen mode

Fin

Congrats! You've deployed your Laravel 5 application to the internet using Heroku.

If you have questions hit me up on twitter. Also, I've got a mailing list going that I send out twice a week with legit tutorials covering Laravel, Vue, Heroku and other fun stuff in addition to open source projects and jobs

Sign up here! http://connorleech.info/

Update:

  • You can make a database using the ClearDB plugin. Then from Sequel Pro or a similar tool you can connect to the production db using this info from the URL: CLEARDB_DATABASE_URL => mysql://[username]:[password]@[host]/[database name]?reconnect=true. Set the config variables for the heroku app with the heroku config command.

Top comments (15)

Collapse
 
mostueck profile image
Moritz Stückler

My deployment seems to work finde, until php artisan is running some script which is trying to connect to the database (which doesn't exist yet, because I haven't run migrations yet). Any idea what that happens?

...

  • Installing graham-campbell/manager (v4.0.0): Downloading (100%)
  • Installing vinkla/hashids (4.0.0): Downloading (100%) Generating optimized autoload files > Illuminate\Foundation\ComposerScripts::postAutoloadDump > @php artisan package:discover

In Connection.php line 664:

SQLSTATE[HY000] [2002] Connection refused (SQL: select * from questions)

...

Collapse
 
connor11528 profile image
Connor Leech

you need to have a production database connected to heroku

Collapse
 
anmollohana profile image
anmollohana

I have deployed a few applications on the AWS server with Devrims Laravel Hosting Services, which was an excellent experience.
Deploying the application on Heroku could be difficult for me, but thank you for sharing this information and making it easy for all who have not deployed their applications on Heroku before.

Collapse
 
azazqadir profile image
Muhammad Azaz Qadir

I have never used Heroku. Is it like Forge, where you have to pay separate invoice to provider and the platform. Or like Cloudways (cloudways.com/en/laravel-hosting.php ), where you only have to pay the invoice to the platform.

Collapse
 
connor11528 profile image
Connor Leech

It’s based on traffic and cpu. Most of the time it’s free. If you need special features the hobby plan is $7/month heroku.com/pricing

Collapse
 
zaratedev profile image
Jonathan Zarate

Thanks! awesome tutorial. :D

Collapse
 
antoine profile image
Antoine Gagnon • Edited

Great tutorial ! Seems like everything worked for me :) Now onto your Vue tutorial ;)

Collapse
 
khalifa profile image
khalifa

Great tutorial
Huge thing missing though:

heroku run composer install

Collapse
 
connor11528 profile image
Connor Leech

There's another helpful tutorial here that uses more steps through the Heroku UI: mikateach.com/setting-up-laravel-5...

Collapse
 
youdevs profile image
Carlos Hernández

Thank you bro <3

Collapse
 
its_phronesis profile image
Joey K

I'm getting an error! That the host, user, and pass indexes of $url are undefined indexes. What am I missing?

Collapse
 
connor11528 profile image
Connor Leech

Do you have CLEARDB_DATABASE_URL as an environment variable set in heroku? You can check by typing herou config devcenter.heroku.com/articles/conf...

Collapse
 
roniemeque profile image
Ronie

man I just had to deploy an Laravel app for a client to see how the project was going in like a EXTREMELY BIG HURRY. You saved my life, for real. God bless you.