How to deploy Sylius to Platform.sh?

Tip

Start with reading Platform.sh documentation. Also Symfony provides a guide on deploying projects to Platform.sh.

The process of deploying Sylius to Platform.sh is based on the guidelines prepared for Symfony projects in general. In this guide you will find sufficient instructions to have your application up and running on Platform.sh.

1. Prepare a Platform.sh project

  • Create an account on Platform.sh.
  • Create a new project, name it (MyFirstShop for example) and select the Blank project template.

Hint

Platform.sh offers a trial month, which you can use for testing your store deployment. If you would be asked to provide your credit card data nevertheless, use this link to create your new project.

../../_images/platform-sh-project.png

  • Install the Symfony-Platform.sh bridge in your application with composer require platformsh/symfonyflex-bridge.

2. Make the application ready to deploy

  • Create the .platform/routes.yaml file, which describes how an incoming URL is going to be processed by the server.
"https://{default}/":
    type: upstream
    upstream: "app:http"

"https://www.{default}/":
    type: redirect
    to: "https://{default}/"
  • Create the .platform/services.yaml file.
db:
    type: mysql:10.2
    disk: 2048
  • Create the .platform.app.yaml file, which is the main server application configuration file (and the longest one 😉).
name: app
type: php:7.3
build:
    flavor: composer

variables:
    env:
        # Tell Symfony to always install in production-mode.
        APP_ENV: 'prod'
        APP_DEBUG: 0

# The hooks that will be performed when the package is deployed.
hooks:
    build: |
        set -e
        yarn install
        GULP_ENV=prod yarn build
    deploy: |
        set -e
        rm -rf var/cache/*
        mkdir -p public/media/image
        bin/console sylius:install -n
        bin/console sylius:fixtures:load -n
        bin/console assets:install --symlink --relative public
        bin/console cache:clear

# The relationships of the application with services or other applications.
# The left-hand side is the name of the relationship as it will be exposed
# to the application in the PLATFORM_RELATIONSHIPS variable. The right-hand
# side is in the form `<service name>:<endpoint name>`.
relationships:
    # NOTE: this will install mariadb because platform.sh uses it instead of mysql.
    database: "db:mysql"

dependencies:
    nodejs:
        yarn: "*"
        gulp-cli: "*"

# The size of the persistent disk of the application (in MB).
disk: 2048

# The mounts that will be performed when the package is deployed.
mounts:
    "/var/cache": "shared:files/cache"
    "/var/log": "shared:files/log"
    "/var/sessions": "shared:files/sessions"
    "/public/uploads": "shared:files/uploads"
    "/public/media": "shared:files/media"

# The configuration of app when it is exposed to the web.
web:
    locations:
        "/":
            # The public directory of the app, relative to its root.
            root: "public"
            # The front-controller script to send non-static requests to.
            passthru: "/index.php"
            allow: true
            expires: -1
            scripts: true
        '/assets/shop':
            expires: 2w
            passthru: true
            allow: false
            rules:
                # Only allow static files from the assets directories.
                '\.(css|js|jpe?g|png|gif|svgz?|ico|bmp|tiff?|wbmp|ico|jng|bmp|html|pdf|otf|woff2|woff|eot|ttf|jar|swf|ogx|avi|wmv|asf|asx|mng|flv|webm|mov|ogv|mpe|mpe?g|mp4|3gpp|weba|ra|m4a|mp3|mp2|mpe?ga|midi?)$':
                    allow: true
        '/media/image':
            expires: 2w
            passthru: true
            allow: false
            rules:
                # Only allow static files from the assets directories.
                '\.(jpe?g|png|gif|svgz?)$':
                    allow: true
        '/media/cache/resolve':
            passthru: "/index.php"
            expires: -1
            allow: true
            scripts: true
        '/media/cache':
            expires: 2w
            passthru: true
            allow: false
            rules:
                # Only allow static files from the assets directories.
                '\.(jpe?g|png|gif|svgz?)$':
                    allow: true

Warning

It is important to place the newly created file after importing regular parameters.yml file. Otherwise your database connection will not work. Also this will be the file where you should set your required parameters. Its value will be fetched from environmental variables.

The application secret is used in several places in Sylius and Symfony. Platform.sh allows you to deploy an environment for each branch you have, and therefore it makes sense to have a secret automatically generated by the Platform.sh system. The last 3 lines in the sample above will use the Platform.sh-provided random value as the application secret.

3. Add Platform.sh as a remote to your repository

Use the below command to add your Platform.sh project as the platform remote:

git remote add platform [PROJECT-ID]@git.[CLUSTER].platform.sh:[PROJECT-ID].git

The PROJECT-ID is the unique identifier of your project, and CLUSTER can be eu or us - depending on where are you deploying your project.

4. Commit the configuration

git add . && git commit -m "Platform.sh configuration"

5. Push your project to the Platform.sh remote repository

git push platform master

The output of this command shows you on which URL your online store can be accessed.

6. Connect to the project via SSH and install Sylius

The SSH command can be found in your project data on Platform.sh. Alternatively use the Platform CLI tool.

When you get connected please run:

php bin/console sylius:install --env prod

Warning

By default platform.sh creates only one instance of the database with the main name. Platform.sh works with the concept of an environment per branch if activated. The idea is to mimic production settings per each branch.

How to deploy Sylius Plus to Platform.sh?

Sylius Plus is installed to Sylius like a plugin, but it needs some changes to the Platform.sh configuration presented above to deploy it properly. First of all, make sure you have your project configured following the Sylius Plus installation guide. After that, you should modify your .platform.app.yaml. Configuration from step 2 should be extended by the following lines.

# ...

hooks:
    build: |
        set -e
        yarn install --ignore-engines # without this flag you will get error related with node version conflict
        GULP_ENV=prod yarn build
        wkhtmltopdf -V # Sylius Plus is installed with InvoicingPlugin, so we need wkhtmltopdf to generate PDF

    deploy: |
        set -e
        rm -rf var/cache/*
        mkdir -p public/media/image
        bin/console sylius:install -n
        bin/console sylius:fixtures:load plus -n # Updating fixtures with new Sylius Plus features
        bin/console assets:install --symlink --relative public
        bin/console cache:clear

dependencies:
    nodejs:
        yarn: "*"
        gulp-cli: "*"
    ruby:
        "wkhtmltopdf-binary": "0.12.5.1" # adding wkhtmltopdf as a one of dependencies

# ...

In order to use the wkhtmltopdf (needed for Invoicing and Refunds) on server properly, you also need to add it to the config\packages'knp_snappy.yaml:

knp_snappy:
pdf:
    enabled:    true
    binary:     wkhtmltopdf # for local purpose was '%env(WKHTMLTOPDF_PATH)%'
    options:    []
image:
    enabled:    true
    binary:     wkhtmltoimage # for local purpose was '%env(WKHTMLTOIMAGE_PATH)%'
    options:    []

Sylius Plus is on Private Packagist, so when you want to download it on server, you need add authentication token before deployment. You can do it by UI on your project page on platform.sh or if you have platform.sh CLI you can add authentication_token:

platform variable:create --level project --name env:COMPOSER_AUTH \
--json true --visible-runtime false --sensitive true --visible-build true
--value '{"http-basic": {"sylius.repo.packagist.com": {"username": "token", "password": "YOUR_AUTHENTICATION_TOKEN"}}}'

All the other steps from the Sylius deployment on Platform.sh remain unchanged.

7. Dive deeper

Add default Sylius cronjobs:

Add the example below to your .platform.app.yaml file. This runs these cronjobs every 6 hours.

crons:
    cleanup_cart:
        spec: '0 */6 * * *'
        cmd: '/usr/bin/flock -n /tmp/lock.app.cleanup_cart bin/console sylius:remove-expired-carts --env=prod --verbose'
    cleanup_order:
        spec: '0 */6 * * *'
        cmd: '/usr/bin/flock -n /tmp/lock.app.cleanup_order bin/console sylius:cancel-unpaid-orders --env=prod --verbose'

Additional tips:

  • Platform.sh can serve gzipped versions of your static assets. Make sure to save your assets in the same folder, but with a .gz suffix. The gulp-gzip node package comes very helpful integrating saving of .gz versions of your assets.
  • Platform.sh comes with a New Relic integration.
  • Platform.sh comes with a Blackfire.io integration

Learn more