Symfony 4: deploying a new application with Heroku
And after our application development is finished, and we have our first version, having slim controllers and fat services with Symfony 4, is time to release it to the world. I choose Heroku to that.
Heroku is a Cloud Platform as a Service that supports several languages.
Among them, theres support for PHP, as well as the Symfony framework.
I like to use it because, from the terminal I can manage the versioning of my code, as well as deploying the application. And Heroku itself, with configurations, automates everything related to infrastructure.
So in this article I will explain how to deploy an application in Symfony 4 in Heroku.
This article is based on official documentation, with some changes, as it has not been updated to version 4 of Symfony.
Step 1 — Create the Symfony Project
I assume that you already have a Symfony project created. If this is not the case, just follow the steps in this link.
Step 2 — Initializing a Git Project
In the project folder, simply execute the following commands.
Note: Before this initial commit do not forget to review your .gitignore. I did not, and I did commit the PHPStorm folder, the .idea. Then I had to reverse the commit of this folder.
git add .
git commit -m 'Initial commit'
Step 3 — Deploying to Heroku
Create a new application in Heroku
Next we will execute the following command to create a new Heroku application.
Configuring Symfony to run in PROD environment
Now we have to explicitly configure the environment to use. Otherwise, Symfony will use the development environment for commands and execution.
This will not work since Symfony in the development environment has some dependencies on packages that will not be installed after push. Composer will not install dev packages when pushing to Heroku.
Let’s define the PROD environment, using the Heroku config feature, since Symfony will read the SYMFONY_ENV environment variable.
heroku config:set SYMFONY_ENV=prod
Pushing to Heroku
Now we can deploy. Just push to master.
Note: I had the following error, because of a problem in Symfony Flex. I just needed to explicitly define the version: “symfony/flex”: “1.0.89”.
git push heroku master
Change the destination of the logs in production
This step is important, for us to know what’s going on in our app.
Typically, at the first deploy the app it will not work, so we having access to the logs are a critical step.
By the documentation, it is recommended to use monolog, so I installed the Monolog Bundle for Symfony, using the following command:
composer require symfony/monolog-bundle
This will allow us to configure the destination of the logs, switching from going to the filesystem, to go STDERR. Heroku will catch all the stream of data that were sent to this standard error by our application.
I went to the monolog production configuration file, available in the path config/prod/monolog.yml and change the path settings to “php://stderr”.
After that, in the project folder, I just run the following command, to see the logs of the application:
heroku logs --tail
Creating a Procfile
The next step is to define what settings the web server should assume.
Heroku will launch a web server with PHP to serve our application, but he doesn’t know where is our document root. Will assume that is in root of the project.
So, I ran the following command, which creates this Procfile, and informs the correct root of the application. In symfony 4 is the public folder.
echo 'web: $(composer config bin-dir)/heroku-php-apache2 public/' > Procfile
Note: If you prefer to use Nginx you could check this very good tutorial.
Now, and to have rewrite rules working, otherwise only the / page route will be working, we will have to install another package.
Let’s install the apache-pack, that places an .htaccess file in our project.
We have to run, with Symfony Flex:
composer require apache-pack
And without Symfony Flex:
composer require symfony/apache-pack
Configuring the Database
There are several options, but I needed a MySQL database. In this case it is possible to have a MySQL database, using the JawsDB add-on.
Using the following command, it will be created a new MySQL instance for us:
heroku addons:create jawsdb
Then just get the URL to connect to the database. This URL is available in this entry in the configuration:
heroku config:get JAWSDB_URL
After that, just place the link URL in the DATABASE_URL environment variable, which Symfony itself will use to connect to the database.
heroku config:set DATABASE_URL=mysql://USER:PASSWORD@HOST:PORT/DATABASE_NAME
Check in the Doctrine configuration file to see where this DATABASE_URL will be used.
Then just clear the cache for the changes to work. Good tip from here.
heroku run "php bin/console cache:clear"
What did you think?
These are the essential steps for launching a Symfony 4 application in a Heroku instance. Notice that logging will also be useful.
What did you think? Was it complete or incomplete? Is there a step missing? Leave me your comment.
This article belongs to a series of posts about Symfony 4: