PHP - Deploying a Symfony 2 or Symfony 3 application

Detection

When a PHP application is deployed, we’re looking at the composer.json file to know if it is using a particular framework. For Symfony 2 and 3, we’re looking if the Composer dependencies contain symfony/symfony. If so, your app is deployed as a Symfony application.

{
  "require": {
    "symfony/symfony": "~2.8",
    // ....
  }
}

During the deployment process you’ll see the following output, mentioning that the framework has correctly been detected.

-----> Detected Symfony2 App
...
-----> Setting up Symfony2 App

Configuration

The standard way to define environment-dependant variables in Symfony is to modify the app/config/parameters.yml file that is generated by Composer and usually excluded from Git (without that it wouldn’t be safe to store credentials in it). This method to define environement variables is very specific to Symfony, and has been thought to be compatible with shared hostings, where you just drag n’drop your files on an FTP server, without the possibility to set normal environment variables.

With Scalingo, it’s exactly the opposite: you can’t modify the parameters.yml file unless you add it to Git (but as we explained it before, it’s a very bad practice), the good method is to define environement variables!

Now, you will have to choose between two solutions to make your Symfony configuration compatible with environment variables:

Keeping parameters.yml in dev, using environment variables on Scalingo

Luckily, Incenteev/ParameterHandler (the package in charge of managing your parameters) supports environment parameters. Go to the Scalingo dashboard, and add the needed environment variables, ideally respecting the UPPERCASE_SNAKE_CASE. Then, edit your composer.json file and add a extra.incenteev-parameters key that describes the mapping between Symfony parameters and the environment variables:

{
    "extra": {
        "incenteev-parameters": {
            "env-map": {
                "database_host": "DATABASE_HOST",
                "database_port": "DATABASE_PORT"
            }
        }
    }
}

Now, your app will use the environment variables (when defined), and the parameters.yml file.

Get rid of parameters.yml, only use environment variables

For sure, this will make your configuration cleaner. But parameters.yml has the advantage of being easy to edit, and the parameters.yml.dist provides a template and configuration reference which is valuable when working in team (when a coworker enters composer install, the CLI will ask him for the missing values, so he gets noticed of parameters changes).

If you still want to only work with environment variables, let’s remove Incenteev/ParameterHandler:

  • Delete the line "Incenteev\\ParameterHandler\\ScriptHandler::buildParameters", in your composer.json ;
  • Delete ParameterHandler’s configuration in composer.json under extra.incenteev-parameters key ;
  • Run composer remove incenteev/composer-parameter-handler.

Now, you’ll find that Symfony provides a native support for environement variables, but when Incenteev/ParameterHandler is installed (it is, by default), they are overwritten by it, since it is loaded at higher level in the framework.

Symfony will grab any environment variable prefixed with SYMFONY__ and set it as a parameter in the service container. Some transformations are applied to the resulting parameter name:

  • SYMFONY__ prefix is removed;
  • Parameter name is lowercased;
  • Double underscores are replaced with a period, as a period is not a valid character in an environment variable name.

So, if you have a %some.awesome.parameter% in your config, define the SYMFONY__SOME__AWESOME_PARAMETER in Scalingo’s dashboard.

It’s now up to you to define your environment variables in your development environement.

Log files

By default, we are getting the logs written on stdout and send them to our log aggregator system. With PHP it’s not working exactly the same way (since the standard output is what is sent back to the browser), and Symfony is using its own log files.

These files are named var/logs/dev.log and var/logs/prod.log (app instead of var in Symfony 2 applications) by default. The logs stored in those files are visible in the Logs section of the dashboard.

Cache warmup

Towards the end of the deployment process, you will see the following output:

Warmuping cache

It means that we are preparing the cache of your application, to avoid making it at runtime and loosing performance. Under the hood, the following command is executed (replace app with bin in Symfony 3):

app/console cache:warmup --env=prod --no-debug

By default, this command executes the default cache warmers that the framework provides. You can add your own cache warmers: learn more about Symfony’s cache warmup here.

Asset management with Assetic

If you are using Assetic to handle your assets, you may need to run a custom command once Symfony has been installed. To do so, you need to add the following piece of configuration in your composer.json:

{
  // ...,
  "extra": {
    "paas": {
      "compile": [
        "php app/console assetic:dump --env=prod --no-debug"
      ]
    }
  }
}

This configuration node (extra.paas.compile) is defining that after installing symfony, the ‘assetic:dump’ command will be executed, preparing your assets for your application. Of course, you can add any other commands here!

schedule 27 Jun 2016