Robin van der Vleuten

Running Symfony on Heroku

If you mostly work with PHP, Heroku may not be the first platform you reach for. It started with Ruby applications, but buildpacks made it possible to run many other stacks. At the time, Heroku did not have an official PHP buildpack, but Christoph Hochstrasser had one that made Symfony deployments possible.

First, install the Heroku CLI so you can access your Heroku account from the command line. Make sure this works:

bash
# Will output something like 'heroku/7.42.1 darwin-x64 node-v12.16.2'
$ heroku --version

Now create a Symfony application with Composer:

bash
$ php composer.phar create-project symfony/framework-standard-edition myapp/ 2.3.6

Composer creates the application in myapp/ and installs the dependencies. Move into that directory and edit composer.json so the buildpack knows which document-root to use and which PHP settings to apply. Add this to the extras section:

json
{
"extra": {
"heroku": {
"document-root": "web",
"php-config": [
"date.timezone=Europe/Amsterdam",
"display_errors=off",
"short_open_tag=off"
]
}
}
}

Every Heroku application is backed by a Git repository. When you push a new commit to the Heroku remote, Heroku deploys that commit as a new version of the application. Before deploying, initialize a Git repository and commit the Symfony application files:

bash
# Run this commands from your application directory.
$ git init
$ git add .
$ git commit -m "Initialized a base Symfony application"

The Symfony application is now ready to deploy. Create a Heroku app that uses Christoph's PHP buildpack:

bash
heroku create myapp --buildpack https://github.com/CHH/heroku-buildpack-php

Heroku creates the application and adds a heroku remote to the Git repository. Push the commit to that remote:

bash
$ git push heroku master

When Heroku receives the commit, it deploys the application through the buildpack. After the deploy, opening the app may show a 404. That is expected with the Symfony standard edition because it only includes AcmeDemoBundle, and that bundle is only visible in the dev environment through app_dev.php.

There are a few Heroku-specific things to watch. The first is parameters.yml. In the Symfony standard edition, Composer generates it and asks for input the first time. During a Heroku deploy, you cannot provide that input. A better approach is to remove parameters.yml from config.yml and configure everything with environment variables. Symfony reads them when they are prefixed with SYMFONY__. To set the secret value on Heroku, run:

bash
$ heroku config:set SYMFONY__SECRET=ThisTokenIsNotSoSecretChangeIt

You also need environment variables during the compile process. To make them available, enable the user-env-compile labs feature:

bash
$ heroku labs:enable user-env-compile -a myapp

You can enable New Relic support by adding this to composer.json:

json
{
"extra": {
"heroku": {
"newrelic": true
}
}
}

That is enough to get a Hapi application running behind Passenger on Heroku.