Deploying Symfony5 / Webpack / Apache / MySQL with Heroku
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 !