As I promised in the most recent Laravel post, today we are going to talk about how to deploy a Laravel app to a production environment. At the time that I write this, the most recent version of Laravel is 9.x but when you read this, there is a good chance that 10.x or 11.x will be available. Starting with the release of Laravel 8, they transitioned to yearly releases. Prior to that they were releasing major versions every 6 months. Version 9 was released on February 8, 2022, it is scheduled to receive bug fixes until August 8, 2023, and it is scheduled to receive security fixes until February 8, 2024. Laravel used to have an LTS (long-term support) version (similar to what Ubuntu does) but the LTS had 3 years of support and every version after version 8 has two years of support, so I’m guessing that it is what killed the LTS. For this post, we are going to focus on version 9.
So, let’s start with the dependencies. Laravel 9 requires PHP >= 8.0, the BCMath PHP extension, the Ctype PHP extension, the cURL PHP extension, the DOM PHP extension, the Fileinfo PHP extension, the JSON PHP extension, the Mbstring PHP extension, the OpenSSL PHP extension, the PCRE PHP extension, the PDO PHP extension, the Tokenizer PHP extension, and the XML PHP extension. You could totally just install nginx, PHP, and the assorted extensions on a server, and run the app but this is 2022 so let’s try setting up a “serverless” solution.
I have been pretty vocal in the past about my fondness for Render and they have a method for deploying a laravel app using a docker image but their method uses Laravel 5.8, so let’s move on.
Similarly, Heroku has a method for deploying a laravel app to Heroku. This method uses the Heroku CLI. The first step is to install the Heroku CLI. For this demo, I am using my trusty MacBook Pro, so we are going to install it with homebrew (if you haven’t yet installed brew on your mac, just read their website for instructions).
If you run brew install heroku/brew/heroku
and let it install, homebrew will install the CLI for you. If you run heroku --version
, you can verify that it installed properly.
At this point, you need to create a new laravel app, using the one of the many tools we covered earlier.
Running composer create-project laravel/laravel heroku-test
, should get you a new laravel app in called heroku-test
in the current directory.
Next, you need to create a file called Procfile in the root of the folder. Procfile is a file that specifies the commands that are executed by an Heroku app on startup. Inside the file, you need to enter: web: vendor/bin/heroku-php-apache2 public/
.
Next, you need to initialize the project as a git repo by entering git init
. After that, you need to enter heroku login
to enter your heroku credentials and heroku create
to actually create your heroku application.
You should now have an application name. Mine is blooming-bastion-49178 and a URL like https://blooming-bastion-49178.herokuapp.com/. Next, you need to set a laravel encryption key by entering php artisan key:generate --show
and heroku config:set APP_KEY={your key copied from the previous step}
.
At this point, you can commit your changes to the git repo by running git add .
, git commit -m "Initial deployment to heroku"
, and git push heroku master
.
Now that the application is on the server, you can run heroku open
to start it. You can see mine at https://blooming-bastion-49178.herokuapp.com/.
Last time, we went over how to define a database connection in laravel. One of the benefits of using Postgres with Heroku is that it is free (at least at the “Hobby Dev” level). You can create the Postres database by running heroku addons:create heroku-postgresql:hobby-dev
and you can see the details of the database by running heroku config
. At this point, you should have an APP_KEY and a DATABASE_URL value. If you add $DATABASE_URL = parse_url('Your database URL');
between the top <?php
and the return
at the top of the config/database.php file, you can then replace the pgsql definition with:
'pgsql' => [
'driver' => 'pgsql',
'host' => $DATABASE_URL["host"],
'port' => $DATABASE_URL["port"],
'database' => ltrim($DATABASE_URL["path"], "/"),
'username' => $DATABASE_URL["user"],
'password' => $DATABASE_URL["pass"],
'charset' => 'utf8',
'prefix' => '',
'schema' => 'public',
'sslmode' => 'require',
],
At that point, you just need to commit the changes to the git repo …
… run the migrations (by running heroku run php artisan migrate
) …
… and then the only thing left is to create an authentication system by running composer require laravel/ui
, running php artisan ui vue --auth
, and committing that to the repo.
You can tell that the authentication scaffolding is there because there are auth links on the page, now.
Want to play around with the result? I will keep https://blooming-bastion-49178.herokuapp.com/ up and running for the time being. Have any questions, comments, etc? Feel free to drop a comment, below.
[ Cover photo by Fotis Fotopoulos on Unsplash ]