These directions are for setting up a new Heroku pipeline and adding 2 apps to it: staging and production. This is intended for hosting a Laravel app, which may not be the configuration for all projects.
You need to have previously configured your Laravel Homestead environment and checked out the codebase from the GitHub repo. Those directions are found elsewhere.
-
If you haven't already done so, create an account at heroku.com.
-
If you haven't done so previously, install the Heroku Toolbelt on your machine.
-
If not done before, install the Heroku pipeline addon:
heroku plugins:install heroku-pipelines
-
Change the current directory to the Laravel app project directory (e.g.
~/Code/russellkeppner.com
). -
Modify
bootstrap/app.php
by adding the following code above thereturn $app;
section:/* |-------------------------------------------------------------------------- | Set Environment Variables |-------------------------------------------------------------------------- | | Split the Heroku-provided environment variables into the individual | pieces that Laravel expects. | */ if ($db_url = getenv('DATABASE_URL')) { if (parse_url($db_url, PHP_URL_SCHEME) == 'postgres') { putenv('DB_CONNECTION=' . 'pgsql'); } putenv('DB_USERNAME=' . parse_url($db_url, PHP_URL_USER)); putenv('DB_PASSWORD=' . parse_url($db_url, PHP_URL_PASS)); putenv('DB_HOST=' . parse_url($db_url, PHP_URL_HOST)); putenv('DB_PORT=' . parse_url($db_url, PHP_URL_PORT)); putenv('DB_DATABASE=' . ltrim(parse_url($db_url, PHP_URL_PATH), '/')); } if ($redis_url = getenv('REDIS_URL')) { putenv('REDIS_USERNAME=' . parse_url($redis_url, PHP_URL_USER)); putenv('REDIS_PASSWORD=' . parse_url($redis_url, PHP_URL_PASS)); putenv('REDIS_HOST=' . parse_url($redis_url, PHP_URL_HOST)); putenv('REDIS_PORT=' . parse_url($redis_url, PHP_URL_PORT)); }
-
Modify
config/database.php
Redis configuration to match the following:'redis' => [ 'cluster' => false, 'default' => [ 'host' => env('REDIS_HOST', '127.0.0.1'), 'username' => env('REDIS_USERNAME', null), 'password' => env('REDIS_PASSWORD', null), 'port' => env('REDIS_PORT', 6379), 'database' => env('REDIS_DATABASE', 0), ], ],
-
Change
config/app.php
logging configuration to:'log' => env('APP_LOG', 'errorlog'),
-
Configure Laravel to trust the Heroku load balancer
-
Add the Laravel Trusted Proxy package:
$ composer require fideloper/proxy
-
Add the service provider in
config/app.php
:'providers' => [ # other providers omitted Fideloper\Proxy\TrustedProxyServiceProvider::class, ];
-
Publish the package config file:
$ php artisan vendor:publish --provider="Fideloper\Proxy\TrustedProxyServiceProvider"
-
Register the HTTP Middleware in
app/Http/Kernel.php
:protected $middleware = [ # other middlewares omitted \Fideloper\Proxy\TrustProxies::class, ];
-
Edit the published
config/trustedproxy.php
config file:return [ 'proxies' => '*', 'headers' => [ Illuminate\Http\Request::HEADER_FORWARDED => null, Illuminate\Http\Request::HEADER_CLIENT_IP => 'X_FORWARDED_FOR', Illuminate\Http\Request::HEADER_CLIENT_HOST => null, Illuminate\Http\Request::HEADER_CLIENT_PROTO => 'X_FORWARDED_PROTO', Illuminate\Http\Request::HEADER_CLIENT_PORT => 'X_FORWARDED_PORT', ] ];
-
Execute these commands in your local environment, to add the Heroku remotes for promotion:
heroku apps:create --addons "heroku-postgresql,heroku-redis" -b https://github.com/heroku/heroku-buildpack-php -r production russellkeppner
heroku pipelines:create -s production -r production russellkeppner
heroku config:set APP_KEY=$(php artisan --no-ansi key:generate --show) -r production
heroku apps:create --addons "heroku-postgresql,heroku-redis" -b https://github.com/heroku/heroku-buildpack-php -r staging russellkeppner-staging
heroku pipelines:add -s staging -r staging russellkeppner
heroku config:set APP_KEY=$(php artisan --no-ansi key:generate --show) -r staging
git config heroku.remote staging
-
First, add the following at the top of the
"scripts": {}
section incomposer.json
"warmup": [ "php artisan config:cache", "php artisan route:cache" ],
-
Procfile
Directives for Heroku environment configuration:web: composer warmup && $(composer config bin-dir)/heroku-php-nginx -C nginx.conf public/
-
nginx.conf
Nginx configuration for the Heroku environment:# prevent HTTPoxy vulnerability fastcgi_param HTTP_PROXY ""; if ($host !~ "^(staging|www)\.expamle\.com$") { return 555; } error_page 555 = @auth; location @auth { auth_basic "Restricted"; auth_basic_user_file /app/basic.htpasswd; try_files $uri @rewriteapp; } location / { # try to serve file directly, fallback to rewrite try_files $uri @rewriteapp; } location @rewriteapp { # rewrite all to index.php rewrite ^(.*)$ /index.php$1 last; }
Modify the domain name appropriately for the environment.
-
basic.htpasswd
Create this file using a tool like the Htpasswd Generator.
-
Commit changes to staging via Git (command line instructions given below, but this can also be done in SourceTree):
$ git add -A . $ git commit -m "Added Heroku configuration." $ git push staging master
-
Share/QA the results at: http://russellkeppner-staging.herokuapp.com
-
When approved, promote the changes to production:
$ heroku pipelines:promote -r staging
-
Double-check site at: http://russellkeppner.herokuapp.com
To run a migration on a Heroku app:
$ heroku run -r staging 'php artisan migrate'