Deploying a Laravel App from GitHub to Heroku

Deploy a Laravel application from GitHub to Heroku using Codeship for continuous integration and deployment.



Introduction

In this tutorial we will be setting up continuous integration and deployment from GitHub to Heroku for a Laravel application. First I'll show you how to set up continuous integration on Codeship, and then I'll show you how to deploy the application to from Codeship to Heroku.

I've created a Laravel application called webflix on GitHub that I will be using for this tutorial. You can fork the repository and follow along or you can use your own application.

The main limitation of Heroku is that it does not support MySQL databases. You can only opt for a PostgreSQL database. You can always use a remote MySQL database; that will work, but for this tutorial, I have decided on using PostgreSQL database since it simplifies things a lot. Laravel supports PostgreSQL database out of the box.

If you already have a working application that uses a MySQL database, you can follow this article to migrate your MySQL database to a PostgreSQL database.

About Webflix

Webflix is dummy Laravel application which simulates Netflix. You can log in, browse movies and mark movies watched. It uses Bootstrap 4 for the design. Bootstrap 4 is still in the alpha stage, but I found it suitable for this application.

This is how the application looks like once you log in:

Webflix home page

To be able to mark movies watched, you first have to log in:

Webflix login page

User credentials

Email: test@test.com
Password: secret

Tests

Webflix comes with two functional tests written with Codeception. First test tests if the user can log in. The second test tests if the user can mark the movie as watched.

To run the tests execute vendor/bin/codecept run functional.

Codeception PHP Testing Framework v2.2.9
Powered by PHPUnit 5.7.14 by Sebastian Bergmann and contributors.

Functional Tests (2) -------------------------------------------------------------------------------------------------------------------------------------------------------------------------
✔ LoginCept: Login to my account (1.80s)
✔ WatchMovieCept: Mark a movie as watched (0.25s)
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Time: 5.2 seconds, Memory: 22.00MB

OK (2 tests, 5 assertions)

Tests are located in tests/functional directory.


The purpose of this application is to demonstrate how a working Laravel application, that is hosted on GitHub, can be easily added to Codeship for continuous integration, and deployment to Heroku.

Codeship

We now have a Laravel application repository hosted on GitHub. Now, I will show you how to connect your repository to Codeship and run our first integration. Later, I will show you how to use Codeship to automatically deploy our application to Heroku.

If you haven't already, be sure to create a free account on Codeship. You can sign up with your Github, GitLab or Bitbucket account, or you can use your own email.

Free plan & pricing

There are two Codeship platforms: Basic and Pro.

Basic

"Codeship Basic: A simple out-of-the-box Continuous Integration service that just works." - source

In Basic, there is a Free, Starter and Essential Plan. Each plan offers 100 builds per month, 1 concurrent build, 1 parallel test pipeline, unlimited projects and unlimited users.

In Basic, you get a "shared" virtual machine preinstalled with almost everything you need. You can choose some things like PHP versions etc. It is something like Laravel Homestead. You get a virtual machine with preinstalled software that just works. Then, it is up to you to install your application and run tests on it.

Free plan is free :) as the name says. You get to use it with unlimited open source and private projects. This is what we will be using for this tutorial.

Pro

"Codeship Pro: A fully customizable Continuous Integration service with native Docker support." - source

Pro is pro. You get a dedicated virtual machine which you can configure however you like to install and test your application. If you are using Docker to set up your development environment, you can use it in Codeship Pro also.

Pricing is a bit higher than for Basic, but that is to be expected. You can read more about Codeship Pro features.

Let's get started!

Continuous Integration

Log in to your Codeship account. Once logged in, you will be asked to connect your first project to Codeship:

Connect Your SCM

We will choose the GitHub logo here.

On the next screen it will ask you to connect your GitHub repository:

Choose Your Repository

Here, paste the URL of your repository. I will use the repository URL for Webflix: https://github.com/laravelista/webflix.

If you get "Your organization restricts third-party applications access, please make sure Codeship has access.", when you press Connect, you have to head over to Codeship application on GitHub and in the section labeled Organization access either click on:

  • Request access if you are not an administrator for the organization or
  • Grant access if you are an administrator

Codeship application on GitHub

After you have completed the step above, paste the repository URL in the textbox and press Connect.

You will now be asked to select your project type: Basic or Pro.

Basic or Pro

Click on Select Basic project, since that is what we will use for this tutorial.

Next, it will ask you to configure Setup Commands and Test Commands.

In Setup Commands choose I want to create my own custom commands, and enter bellow:

phpenv local 7.1
composer install --prefer-source --no-interaction

The first command tells Codeship to change the version of PHP to 7.1. The default version used is 5.5. Once the machine is created, the repository of your application will be copied onto it. The next command will use Composer to install the required dependencies for our application.

Since we are using Codeception, in Test Commands you only need to enter:

vendor/bin/codecept run functional

Next, click on Save and go to dashboard.

You will be instructed to push to your repository to trigger your first build, but wait.

To trigger or not to trigger

There are a few things that we first need to configure, like our environment variables. On the upper right parts of the page, you will see Project Settings. Click on that, and then on Environment Variables.

PostgreSQL

Since our application uses PostgreSQL, we will need to create a new database connection in our Laravel application for Codeship. This connection will only be used for testing on Codeship.

In your application open file config/database.php and under connections add this:

'pgsql_codeship' => [
    'driver' => 'pgsql',
    'host' => 'localhost',
    'port' => '5432',
    'database' => 'development',
    'username' => env('PGUSER'),
    'password' => env('PGPASSWORD'),
    'charset' => 'utf8',
    'prefix' => '',
    'schema' => 'public',
    'sslmode' => 'prefer',
],

You can view the commit here.

Back to Environment variables. We need to set an environment variable to tell our application to use our newly created database connection. Under Key enter DB_CONNECTION and in Value enter pgsql_codeship.

Environment Variables

Now click on Save Configuration.


Let's get our first green build.

Make a change in your application, commit the change and push to GitHub. You should see a new build on the Codeship dashboard page saying that the build is running. When the build completes, you should see a green Success message on that build.

Success

If the build fails saying Failed, recheck the steps in this tutorial and/or click on that build to see the details and locate in which step the build failed. You can even remotely log into the virtual machine using SSH to inspect the application.

From this point on, every test commit you make will trigger a build and you will get a notification if the build fails.

Continuous integration complete!

Continuous Deployment

We will now set up automatic deployment to Heroku on each successful build on the master branch.

On the upper-right part of the page, you will see Project Settings. Click on that, and then click on Deployment.

Deployment

Make sure that it says "Branch is exactly", and then in the branch name enter master. Click on Save pipeline settings. You will be presented with a grid of supported deployment ways.

Deployments grid

Click on the Heroku logo. You will be greeted with the following screen:

Heroku deployment

Pause here.

Now, the next part we have to do on Heroku. We will create an account, create an application and obtain the API key.

Heroku

If you don't have an account on Heroku, you will have to sign up. You can do that from the Heroku home page by clicking on the Sign up for free button.

Once you log in, you will be on the dashboard page.

Heroku dashboard

From here you can create a new app by clicking on Create New App button. On the following screen, you will be asked to enter the application name or one will be chosen for you. You can also select the region of your application: Europe or United States.

Heroku dashboard

I have entered webflix-laravelista and selected Europe.

There are three things that we need to obtain from Heroku:

  • Application name
  • API key
  • Application URL

So, in my case, the application name is webflix-laravelista. Application URL can be found if you navigate to settings and then under Domains you will see the URL. In my case, it is https://webflix-laravelista.herokuapp.com/.

Application name

To obtain the API key, you have to go to Account Settings. Click on your profile image and then on Account Settings. At the bottom of the page you will see a section called API Key.

Application name

Click on Reveal to see your API key.

We now have everything needed to continue setting up deployment on Codeship.


Navigate back to our deployment page on Codeship and enter the obtained information. (Click on More options to see the application URL input box.)

Once done, click on the Create Deployment button.

Before we continue there are a few things that we have to do before Laravel and Heroku are compatible.

On Heroku, go to Application settings, and in the section Config Variables click on Reveal Config Vars. Here enter these key/value pairs:

  • APP_KEY: base64:Th9tL32tWxfpvCBJ00FiAaJqb81v+toYKsZ29A6L7Y0=
  • APP_LOG: errorlog
  • DB_CONNECTION: pgsql_heroku

Now, to install PostgreSQL add-on, go to Application overview page and click on Configure Add-ons.

Add-ons

On the next screen in the search box, search for Heroku Postgres and click on it. A modal window will pop up prompting you to choose a plan. Select Hobby Dev - Free and click on Provision button. You now have a database connected to your Heroku application.

Now we have to tell Heroku to configure Nginx to serve our application from the /public directory and to use a special Nginx config file. In your Laravel application, first, you have to add a Procfile file in your repository root. The Procfile should contain this code:

web: vendor/bin/heroku-php-nginx -C nginx_app.conf public/

Then, we now need to instruct Nginx to handle Laravel by removing the index.php part of the URI. Create a file called nginx_app.conf in your repository root, and inside it paste this code:

location / {
    try_files $uri @rewriteapp;
}

location @rewriteapp {
    rewrite ^(.*)$ /index.php$1 last;
}

Also, we need to create a database connection for pgsql_heroku. Go to your config/database.php and at the top of the file, just bellow <?php and above return [ add this code:

$host = null;
$username = null;
$password = null;
$database = null;

if(!is_null(env('DATABASE_URL')))
{
    $url = parse_url(env("DATABASE_URL"));

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

Then, under connections add this code:

'pgsql_heroku' => [
    'driver' => 'pgsql',
    'host' => $host,
    'port' => 5432,
    'database' => $database,
    'username' => $username,
    'password' => $password,
    'charset' => 'utf8',
    'prefix' => '',
    'schema' => 'public',
    'sslmode' => 'prefer',
],

One last step, on each deployment to Heroku we should automatically run migrations on our database. To do so, open composer.json file and append this line under post-install-cmd:

"php artisan migrate --force"

Now your post-install-cmd script looks like this:

"post-install-cmd": [
    "Illuminate\\Foundation\\ComposerScripts::postInstall",
    "php artisan optimize",
    "php artisan migrate --force"
],

Great, now make a commit and push. You should see a new build appear in Codeship. If the build turns green (success; and it should at this point) you can browse to your application URL and see that it works. In my case, it is http://webflix-laravelista.herokuapp.com/.

Application online


This completes this tutorial. You have now implemented continuous integration and continuous deployment from GitHub to Heroku on a Laravel application using Codeship. Thank you for reading.

In my opinion, I think that this is the most detailed and comprehensive tutorial on how to deploy Laravel to Heroku.

If you have any questions, leave me a comment bellow and I will respond promptly.

Also, if you need more resources on the subject, take a look at the sources bellow. They helped me a lot during this tutorial. Have a great week!

Sources

Comments