Heroku provides a simple way to deploy PHP and Laravel applications without managing the underlying web server. In this guide, we will deploy a Laravel application to Heroku using Git, configure the application environment, and connect it to a MySQL database.

Heroku’s PHP runtime automatically handles PHP, Composer, Apache/Nginx, and PHP-FPM. ([Heroku Dev Center][2])

1. Prerequisites

Before deploying the Laravel application, make sure the following are installed and working on your local machine:

  • PHP
  • Composer
  • Git
  • Heroku CLI
  • A Heroku account
  • An existing Laravel application

On macOS, install the Heroku CLI using Homebrew:

brew install heroku/brew/heroku

Login to Heroku:

heroku login

Verify that PHP, Composer, and Git are available:

php --version
composer --version
git --version
heroku --version

2. Prepare the Laravel Application

Go inside your Laravel project:

cd /path/to/your/laravel-project

Make sure your Laravel project has a composer.json and composer.lock file.

It is also a good practice to test the application locally before deploying:

php artisan serve

If your Laravel application uses frontend assets, make sure those assets are built before deployment or configure the appropriate Node.js build process in Heroku.

3. Create a Procfile

Laravel’s document root is the public/ directory. Therefore, Heroku needs to be instructed to serve the application from that directory.

Create a file named exactly Procfile in the root of your Laravel project:

echo "web: heroku-php-apache2 public/" > Procfile

The Procfile must not have an extension such as .txt and must be located in the project root. ([Heroku Dev Center][3])

The contents should be:

web: heroku-php-apache2 public/

Add and commit the file:

git add Procfile
git commit -m "Add Heroku Procfile"

4. Create a Heroku Application

Create a new Heroku application:

heroku create laplus-heroku

This creates the Heroku application and adds a heroku Git remote to your local repository.

You can verify it using:

git remote -v

You should see something similar to:

heroku  https://git.heroku.com/laplus-heroku.git

5. Configure the PHP Buildpack

For a traditional Heroku Cedar application, you can explicitly configure the PHP buildpack:

heroku buildpacks:set heroku/php --app laplus-heroku

Heroku can also automatically detect PHP applications from files such as composer.json, but explicitly setting the buildpack can be useful when a project contains multiple types of application files. ([Heroku Dev Center][4])

6. Configure the Laravel APP_KEY

Laravel requires an application encryption key.

Generate the key locally and configure it as a Heroku Config Var:

heroku config:set APP_KEY="$(php artisan key:generate --show --no-ansi)" --app laplus-heroku

Check the configured environment variables:

heroku config --app laplus-heroku

Do not commit your .env file to Git.

Heroku Config Vars are the appropriate place for production environment variables such as:

APP_KEY
DB_HOST
DB_DATABASE
DB_USERNAME
DB_PASSWORD

7. Configure Laravel Logging

Heroku collects application output from stdout and stderr and provides it through its logging system. ([Heroku Dev Center][2])

For older Laravel applications, you may have configuration such as:

'log' => 'errorlog',

However, for newer Laravel applications, logging is normally configured through the LOG_CHANNEL environment variable.

For example:

heroku config:set LOG_CHANNEL=errorlog --app laplus-heroku

The exact logging configuration depends on your Laravel version and config/logging.php.

You can view the application logs using:

heroku logs --tail --app laplus-heroku

This is generally preferable to writing application logs to local files because Heroku’s filesystem is ephemeral.

8. Deploy Laravel Application

Make sure all changes are committed:

git add .
git commit -m "Prepare Laravel application for Heroku"

Heroku deployments should use the main branch:

git push heroku main

If your local branch is not named main, you can explicitly push it:

git push heroku your-branch:main

During deployment, Heroku detects the PHP application, installs the required PHP runtime and Composer dependencies, and starts the process defined in the Procfile. ([Heroku Dev Center][2])

9. Open the Laravel Application

Once deployment is complete:

heroku open --app laplus-heroku

Or get the application URL:

heroku info --app laplus-heroku

Your Laravel application should now be accessible through the Heroku URL.

10. Setup MySQL Database

You can add a MySQL-compatible database through a Heroku Add-on such as JawsDB Maria or JawsDB MySQL. Both are currently listed in Heroku’s Add-ons documentation. ([Heroku Dev Center][5])

For example, if your Heroku account has access to JawsDB Maria:

heroku addons:create jawsdb:maria --app laplus-heroku

The exact plan name can vary, so you can first check the available plans:

heroku addons:plans jawsdb:maria

After adding the database, check the Config Vars:

heroku config --app laplus-heroku

The add-on may provide a database URL such as:

JAWSDB_URL

Depending on the add-on and Laravel version, you can either configure Laravel using the individual database variables or parse the provided database URL.

For example:

DB_CONNECTION=mysql
DB_HOST=xxxxxxxx
DB_PORT=3306
DB_DATABASE=xxxxxxxx
DB_USERNAME=xxxxxxxx
DB_PASSWORD=xxxxxxxx

Set them using Heroku Config Vars:

heroku config:set DB_CONNECTION=mysql --app laplus-heroku
heroku config:set DB_HOST=xxxxxxxx --app laplus-heroku
heroku config:set DB_PORT=3306 --app laplus-heroku
heroku config:set DB_DATABASE=xxxxxxxx --app laplus-heroku
heroku config:set DB_USERNAME=xxxxxxxx --app laplus-heroku
heroku config:set DB_PASSWORD=xxxxxxxx --app laplus-heroku

Alternatively, these values can be configured from:

Heroku Dashboard → Application → Settings → Config Vars

11. Configure Application URL

Configure the Laravel application URL:

heroku config:set APP_URL=https://laplus-heroku.herokuapp.com --app laplus-heroku

If your application uses a custom environment variable such as REDIRECT_HTTPS, configure it as well:

heroku config:set REDIRECT_HTTPS=true --app laplus-heroku

Your application might therefore have Config Vars similar to:

APP_ENV=production
APP_KEY=base64:xxxxxxxx
APP_URL=https://laplus-heroku.herokuapp.com

DB_CONNECTION=mysql
DB_HOST=xxxxxxxx
DB_PORT=3306
DB_DATABASE=xxxxxxxx
DB_USERNAME=xxxxxxxx
DB_PASSWORD=xxxxxxxx

LOG_CHANNEL=errorlog
REDIRECT_HTTPS=true

12. Run Laravel Database Migration

Once the database connection is configured, run Laravel migrations using a Heroku one-off dyno:

heroku run php artisan migrate --app laplus-heroku

If you also need to seed the database:

heroku run php artisan migrate --seed --app laplus-heroku

For a development/test environment where you intentionally want to recreate all tables:

heroku run php artisan migrate:fresh --seed --app laplus-heroku

Be careful with migrate:fresh in production because it drops all database tables before recreating them.

Your original command:

heroku run --app laplus-heroku php artisan migrate:refresh --seed

is valid Laravel syntax, but migrate:refresh rolls back migrations and then runs them again. For normal production deployments, prefer:

heroku run php artisan migrate --app laplus-heroku

13. Clear Laravel Cache

After changing environment variables or configuration, clear Laravel’s cached configuration:

heroku run php artisan optimize:clear --app laplus-heroku

You can also run:

heroku run php artisan config:clear --app laplus-heroku

For production optimization, Laravel can cache configuration:

heroku run php artisan config:cache --app laplus-heroku

14. Check Heroku Application Status

Check the running dynos:

heroku ps --app laplus-heroku

You should see something similar to:

=== web (Basic): heroku-php-apache2 public/ (1)
web.1: up

Heroku’s web process is special because it receives HTTP traffic from Heroku’s routing layer. ([Heroku Dev Center][3])

15. View Laravel / Heroku Logs

To continuously monitor logs:

heroku logs --tail --app laplus-heroku

You can also view recent logs:

heroku logs --app laplus-heroku

This is especially useful when Laravel returns a 500 Internal Server Error.

For example:

heroku logs --tail --app laplus-heroku

Then open the application in your browser and reproduce the error.

16. Deploy Future Changes

Once the initial deployment is complete, future deployments are simple.

Make your Laravel changes:

git add .
git commit -m "Update Laravel application"

Then deploy:

git push heroku main

If database migrations are included:

heroku run php artisan migrate --app laplus-heroku

Then clear the Laravel cache if required:

heroku run php artisan optimize:clear --app laplus-heroku

17. Useful Heroku Commands

Here are some commands that are useful when managing a Laravel application on Heroku:

# Login
heroku login

# List applications
heroku apps

# Application information
heroku info --app laplus-heroku

# View Config Vars
heroku config --app laplus-heroku

# Set Config Var
heroku config:set KEY=value --app laplus-heroku

# View logs
heroku logs --tail --app laplus-heroku

# Check dynos
heroku ps --app laplus-heroku

# Open application
heroku open --app laplus-heroku

# Open Heroku bash
heroku run bash --app laplus-heroku

# Run Laravel Artisan command
heroku run php artisan migrate --app laplus-heroku

# Clear Laravel cache
heroku run php artisan optimize:clear --app laplus-heroku

Final Deployment Flow

The basic Laravel deployment process can be summarized as:

# Install Heroku CLI
brew install heroku/brew/heroku

# Login
heroku login

# Go to Laravel project
cd /path/to/laravel-project

# Create Procfile
echo "web: heroku-php-apache2 public/" > Procfile

# Commit
git add .
git commit -m "Prepare Laravel application for Heroku"

# Create Heroku application
heroku create laplus-heroku

# Configure PHP buildpack
heroku buildpacks:set heroku/php --app laplus-heroku

# Configure Laravel application key
heroku config:set APP_KEY="$(php artisan key:generate --show --no-ansi)" --app laplus-heroku

# Configure application URL
heroku config:set APP_URL=https://laplus-heroku.herokuapp.com --app laplus-heroku

# Deploy
git push heroku main

# Run migrations
heroku run php artisan migrate --app laplus-heroku

# Clear Laravel cache
heroku run php artisan optimize:clear --app laplus-heroku

# Open application
heroku open --app laplus-heroku

Done!