Deploying Symfony5 / Webpack / Apache / MySQL with Heroku

Marvin Courcier
4 min readMay 9, 2020

--

In case I wanted to make another app with Symfony/Webpack using Apache and MySQL, here is the step by step guide to each step, with a link to the documentation.

Prerequisites:

On this tutorial I’m assuming you already have the following ready and steady:

  • Php and Composer
  • Node and npm
  • Git

Installing Heroku CLI:

Installing Heroku CLI :

On Mac OS :

$ brew tap heroku/brew && brew install heroku

On Ubuntu 16+:

$ sudo snap install --classic heroku

Setting Up Heroku CLI:

All the following steps should be executed with the terminal at the root of your project.

Let’s getting started and login using Heroku CLI:

$ heroku login

You can create a new Heroku Project:

$ heroku create your-project-name

Or if you have already created your Heroku app using Heroku Dashboard, you can easily add a remote to your local repository with the following command:

$ heroku git:remote -a your-project-name

Configuring a Web Server with Symfony

when running the application in the production environment, you’ll need to use a fully-featured web server.

$ composer require symfony/apache-pack

Creating a Procfile

In Symfony application the document root is in the public/ directory, and not in the root directory, of the application.
Consequently you need to create a Procfile which tells Heroku what command to use to launch the web server with the correct settings.

In short the Procfile will tell Heroku to start the Apache WebServer using the public/ directory as root.

$ echo 'web: heroku-php-apache2 public/' > Procfile
$ git add Procfile
$ git commit -m "Heroku Procfile"

Configuring Symfony and Node to run in prod environment

You need to direct Heroku to only install the right dependencies by setting up the environment variables.

Symfony:

$ heroku config:set APP_ENV=prod 

Node:

$ heroku config:set NPM_CONFIG_PRODUCTION=true NODE_MODULES_CACHE=false

Note: You can also set the Env using the Heroku Dashboard.

Specifying Node and NPM Version:

You should always specify a Node.js and npm version that matches the runtime you’re developing and testing with. To find your version locally

$ node -v && npm -v

Now, use the engines section of the package.json to specify the version of Node.js to use on Heroku.

#package.json"name": "your-project-name",
"description": "a really cool app",
"version": "1.0.0",
"engines": {
"node": "v13.11.*",
"npm": "6.14.*"
}

Using Multiple Buildpacks

By default Heroku will only build one buildpack. Even though your project is using php and nodejs, it will only take the first one and will ignore the second one.

If PHP is taken by default you’ll need to add nodejs buildpack:

$ heroku buildpacks:add heroku/nodejs

With the second buildpack installed, by typingheroku buidpacks you should see:

=== your-project-name Buildpack URLs1. heroku/php2. heroku/nodejs

Note:

  • This command accepts an optional --index argument, which can be used to set the position of the given buildpack in the order of execution. If --index is provided, the command will overwrite the buildpack at the given position.
  • You can also add the buildpacks using the Heroku Dashboard.

Setting up the log destination for production

Installing Monolog:

Symfony integrates seamlessly with Monolog, the most popular PHP logging library, to create and store log messages in a variety of different places and trigger various actions.

$ composer require symfony/monolog-bundle

Writing Logs to different Locations

# config/packages/prod/monolog.yamlmonolog:
handlers:
main:
type: fingers_crossed
action_level: error
handler: nested
excluded_http_codes: [404, 405]
nested:
type: stream
path: "php://stderr"
level: debug

MySQL using JawsDB

Even though JawsDB base plan is FREE, this step requires you to enter your billing information to Heroku.
You can create a virtual card with 0$/€ using Revolut

Once this is done you can now install the shared MySQL add-on :

$ heroku addons:create jawsdb:kitefin

You can retrieve your database URL by issuing the following command:

$ heroku config:get JAWSDB_URL
mysql://adffdadf2341:adf4234@us-cdbr-east.cleardb.com/heroku_db?reconnect=true

finally you need to update your doctrine.yaml file as followed:

# config/packages/doctrine.yamldbal:
# configure these for your database server
driver: 'pdo_mysql'
server_version: '5.7'
charset: utf8mb4
default_table_options:
charset: utf8mb4
collate: utf8mb4_unicode_ci
url: '%env(resolve:JAWSDB_URL)%'
# rename DATABASE_URL to JAWSDB_URL

Last Step

You need to configure the heroku-postbuild in your package.json

#package.json"scripts": {
"dev-server": "encore dev-server",
"dev": "encore dev",
"watch": "webpack -d --watch --config ./webpack.config.js --display-error-details",
"build": "webpack -p --config ./webpack.config.js --display-error-details",
"heroku-postbuild": "webpack -p --config ./webpack.config.js && php bin/console d:s:u --force"
}

And that’s it !

One last command to start building all of this

$ git push heroku master

Go on your brand new website and have fun with it !

--

--