Use platform.sh to run your Symfony 3 application

What is platform.sh?

In every software project that relies on a hosting environment, there is the question: “Where to host this app?”

I am currently working on a little side-project based on the Symfony 3.4 LTS framework and I had exactly the same question.

A few months ago, I already had the chance to work on a client-project that contains the platform.sh Enterprise plan and I became very interested in this technology stack.

Also, the upcoming SensioCloud is based on platform.sh so this was a great test scenario for me to dive into this topic beside the Enterprise plan (as it differs from the default PaaS plans the provide!).

Documentation

If you are new to the PaaS solutions they provide, you might want to have a look at the documentation, system overview and pricing model:

The platform stack

If you decide to choose platform.sh for your next project, you will get much more than a default webserver setup and a database.

You will have instantly access (included in each plan!) to the following services:

In my case I just need PHP as programming language, but you can decide between PHP, Node.js, Python, Ruby, Google Go (beta) and soon also Java.

Each main version of a language is supported and can be choosen for each project separately.

Environments

One of the killer-features of platform.sh is the Git-like structure of environments. In fact, each environment contains a Git-branch and allows to test feature-branches separately (with a dedicated database and filesystem for example) so no side effects of previously deployed features will affect your tests.

Depending on your plan, you will have one master and three test environments - but you can add additional environments and users if you need to.

Resources

The whole platform.sh setup is designed to scale very efficiently and fast. Beside the already mentioned services, you also have a huge benefit of the fastly proxy that is always included.

The platform management CLI tool

To maximise the benefit of using platform.sh, you will need to install the CLI tool they provide to control your projects using the command line:

platform.sh project information

You can install the PHP-based tool (Phar) very easily by following the docs.

platform.sh CLI installation

How to setup a Symfony 3 project

When it comes to setting up your first project, you have two ways to get stared. The easiest way is to choose the Symfony 3 template during your project setup.

If you choose the template, you will get a full Symfony 3 project initialized in your environment and you can just clone it to your local machine and you are ready to go.

Create the setup from scratch without template

If you already have an application, the template approach won’t work for you.

But the easiest way to get the platfrom.sh deployment working quickly, is to use the template-project as copy & past base.

You can find the template on GitHub: platformsh/platformsh-example-symfony3

Please note that there is a second project with a project template for Symfony 3, but this isn’t ready yet and wont’ work - so we will stick to the old one for now.

I highly recommend to clone the project to your local machine, this makes the whole copy&paste-thing easier.

Step 1: Copy the files

You will need to copy the following files and place them in exactly the same location in your app:

  1. .platform.app.yaml-file
  2. .platform-folder (including all files)
  3. app/config/parameters_platform.php-file

Step 2: Review/modify the .platform.app.yaml file

As described in the platform.sh documentation, you can modify the file to your needs.

In our case the Symfony 3 template is preconfigured very well and we don’t need to modify any of the settings for now.

While your app is growing and needs special build or deploy steps, this is the file to add them (within the corresponding hooks section).

Step 3: Review/modify the files within the .platform-folder

In these files you will be able to define special routing and to define which services you will use.

The default Symfony 3 template will use a very straight forward routing:

platform.sh routing file

In this example a request including the www.-subdomain will be redirected to the domain without it.

The non www.-domain route will then pass the request to the upstream (in our case the webserver and PHP).

For more information on how you can modify the routing, please refer to the documentation.

The services file is also more or less self-explaining:

platform.sh services file

As you can see there is only a Maria DB service dependency which will get a 2 GB quota of your default 5 GB disk space for storing data.

You can add additional services (e.g. Elasticsearch or REIDS) as described in the service documentation.

Setp4: Review/modify the app/config/parameters_platform.php-file

This file is very important as it will prepare the container parameters for database and other service connections.

Platform.sh stores the connection and access information in ENV-variables and this script will process them and injects them into the container configuration:

platform.sh php container configuration

As you add additional services, you will need to modify this file to add the specific connection details to your container.

Step5: Modify your custom app/config/config.yml-file

Last but not least, we have to add file that handles the dynamic container configuration to your main application configuration file (app/config/config.yml):

platform.sh main container configuration mofidications

It is important to add the dynamic configuration directly below the default parameters.yal-include!

Deploy the project to platform.sh

After the project is setup correctly, we will be able to deploy our project by committing and pushing our changes to the master branch the first time.

Git push deployment

I added a new git remote called platformsh beside the origin, so if I push to the platformsh-remote I will trigger a deployment:

platform.sh git push deployment

(The command will print the full composer install output for debugging and logging.)

After the composer setup is done, the build and deploy steps will be triggered as defined in the .platform.app.yaml-file:

platform.sh build steps

At the end of the deployment you will also get a summary (arrows) of the created services and the routing setup including the URLs for testing the deployment.

Common Pitfalls

The whole setup is easy and very quickly to understand.

Non the less, there is one essential thing to keep in mind: your whole filesystem is read-only!

The read-only filesystem

The only way to get around this is to define the path as mount in your platform.sh configuration (if you need a writable directory for your uploads for example).

But as always, there is one exception to this: within the first step of your deployment.

The filesystem during deployment

Within the build-step, your whole system is read and writable, but in return you do not have access to the external services (e.g. the database).

The build-step is designed to modify and/or clean your filesystem before your app becomes active.

This might be useful for removing unused code or development dependencies you don’t want on your production system.

You can find an example for this cleanup process in the template project too:

# The hooks that will be performed when the package is deployed.
hooks:
    build: |
        rm web/app_dev.php
        bin/console --env=prod assets:install --no-debug
    deploy: |
        bin/console --env=prod cache:clear

During the build step the web/app_dev.php-file will be removed to avoid running the app in dev-mode by accident.

Summary

In my opinion, the platform.sh PaaS approach is very interesting and convenient.

Even though the services are very handy, there is a price for all this we have to pay.

The development plan is not that expensive and for a single developer and/or a small project not a big deal (starts at ~12€).

But as you plan to go live with your application (custom domain etc.), the price increases and might become a showstopper for a personal/side project (starts at ~60 EUR).

For now, I will use platform.sh for my application and post some updates with my personal experiences I made during the project.


Bonus: Symfony 4 and platform.sh

I also plan to publish a Symfony 4 specific setup and deployment guide as it needs some modifications (there is no official platform.sh project template for Symfony 4 by now) but I already managed to create a working deployment for it.

Do not forget to subscribe to my blog-feed, if you want an update on this topic!