Platform.sh User Documentation

Configure Drupal for Platform.sh

Upsun Beta

Access our newest offering - Upsun!

Get your free trial by clicking the link below.

Get your Upsun free trial

You now have a project running on Platform.sh. In many ways, a project is just a collection of tools around a Git repository. Just like a Git repository, a project has branches, called environments. Each environment can then be activated. Active environments are built and deployed, giving you a fully isolated running site for each active environment.

Once an environment is activated, your app is deployed through a cluster of containers. You can configure these containers in three ways, each corresponding to a YAML file:

  • Configure apps in a .platform.app.yaml file. This controls the configuration of the container where your app lives.
  • Add services in a .platform/services.yaml file. This controls what additional services are created to support your app, such as databases or search servers. Each environment has its own independent copy of each service. If you’re not using any services, you don’t need this file.
  • Define routes in a .platform/routes.yaml file. This controls how incoming requests are routed to your app or apps. It also controls the built-in HTTP cache. If you’re only using the single default route, you don’t need this file.

Start by creating empty versions of each of these files in your repository:

# Create empty Platform.sh  configuration files
mkdir -p .platform && touch .platform/services.yaml && touch .platform/routes.yaml && touch .platform.app.yaml

Now that you’ve added these files to your project, configure each one for Drupal in the following sections. Each section covers basic configuration options and presents a complete example with comments on why Drupal requires those values.

Configure apps in .platform.app.yaml Anchor to this heading

Your app configuration in a .platform.app.yaml file is allows you to configure nearly any aspect of your app. For all of the options, see a complete reference. The following example shows a complete configuration with comments to explain the various settings.

.platform.app.yaml
# This file describes an application. You can have multiple applications
# in the same project.
#
# See https://docs.platform.sh/configuration/app.html

# The name of this app. Must be unique within a project.
name: 'drupal'

# The runtime the application uses.
type: 'php:8.2'

dependencies:
    php:
        composer/composer: '^2.1'

runtime:
    # Enable the redis extension so Drupal can communicate with the Redis cache.
    extensions:
        - redis
        - sodium
        - apcu
        - blackfire

# 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:
    database: 'db:mysql'
    redis: 'cache:redis'

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

# The 'mounts' describe writable, persistent filesystem mounts in the application.
mounts:
    # The default Drupal files directory.
    '/web/sites/default/files':
        source: local
        source_path: 'files'
    # Drupal gets its own dedicated tmp directory. The settings.platformsh.php
    # file will automatically configure Drupal to use this directory.
    '/tmp':
        source: local
        source_path: 'tmp'
    # Private file uploads are stored outside the web root. The settings.platformsh.php
    # file will automatically configure Drupal to use this directory.
    '/private':
        source: local
        source_path: 'private'
    # Drush needs a scratch space for its own caches.
    '/.drush':
        source: local
        source_path: 'drush'
    # Drush will try to save backups to this directory, so it must be
    # writeable even though you will almost never need to use it.
    '/drush-backups':
        source: local
        source_path: 'drush-backups'
    # Drupal Console will try to save backups to this directory, so it must be
    # writeable even though you will almost never need to use it.
    '/.console':
        source: local
        source_path: 'console'

# Configuration of the build of this application.
build:
    flavor: composer

# The hooks executed at various points in the lifecycle of the application.
hooks:
    # The build hook runs after Composer to finish preparing up your code.
    # No services are available but the disk is writeable.
    build: |
        set -e        
    # The deploy hook runs after your application has been deployed and started.
    # Code cannot be modified at this point but the database is available.
    # The site is not accepting requests while this script runs so keep it
    # fast.
    deploy: |
        set -e
        php ./drush/platformsh_generate_drush_yml.php
        # if drupal is installed, will call the following drush commands:
        #   - `cache-rebuild`
        #   - `updatedb`
        #   - and if config files are present, `config-import`
        cd web
        bash $PLATFORM_APP_DIR/drush/platformsh_deploy_drupal.sh        

# The configuration of app when it is exposed to the web.
web:
    locations:
        # All requests not otherwise specified follow these rules.
        '/':
            # The folder from which to serve static assets, for this location.
            #
            # This is a filesystem path, relative to the application root.
            root: 'web'

            # How long to allow static assets from this location to be cached.
            #
            # Can be a time in seconds, or -1 for no caching. Times can be
            # suffixed with "s" (seconds), "m" (minutes), "h" (hours), "d"
            # (days), "w" (weeks), "M" (months, as 30 days) or "y" (years, as
            # 365 days).
            expires: 5m

            # Redirect any incoming request to Drupal's front controller.
            passthru: '/index.php'

            # Deny access to all static files, except those specifically allowed below.
            allow: false

            # Rules for specific URI patterns.
            rules:
                # Allow access to common static files.
                '\.(avif|webp|jpe?g|png|gif|svgz?|css|js|map|ico|bmp|eot|woff2?|otf|ttf)$':
                    allow: true
                '^/robots\.txt$':
                    allow: true
                '^/sitemap\.xml$':
                    allow: true

                # Deny direct access to configuration files.
                '^/sites/sites\.php$':
                    scripts: false
                '^/sites/[^/]+/settings.*?\.php$':
                    scripts: false

        # The files directory has its own special configuration rules.
        '/sites/default/files':
            # Allow access to all files in the public files directory.
            allow: true
            expires: 5m
            passthru: '/index.php'
            root: 'web/sites/default/files'

            # Do not execute PHP scripts from the writeable mount.
            scripts: false

            rules:
                # Provide a longer TTL (2 weeks) for aggregated CSS and JS files.
                '^/sites/default/files/(css|js)':
                    expires: 2w

crons:
    # Run Drupal's cron tasks every 19 minutes.
    drupal:
        spec: '*/19 * * * *'
        commands: 
            start: 'cd web ; drush core-cron'

source:
  operations:
    auto-update:
      command: |
        curl -fsS https://raw.githubusercontent.com/platformsh/source-operations/main/setup.sh | { bash /dev/fd/3 sop-autoupdate; } 3<&0        

Add services in .platform/services.yaml Anchor to this heading

You can add the managed services you need for you app to run in the .platform/services.yaml file. You pick the major version of the service and security and minor updates are applied automatically, so you always get the newest version when you deploy. You should always try any upgrades on a development branch before pushing to production.

We recommend the latest MariaDB version for Drupal, although you can also use Oracle MySQL or PostgreSQL. For Drupal caching, we strongly recommend Redis. Drupal’s cache can be very aggressive, and keeping that data out of the database helps with both performance and disk usage. See an example of Redis for caching in our Drupal template.

You can add other services if desired, such as Solr or Elasticsearch. You need to configure Drupal to use those services once they’re enabled.

Each service entry has a name (db and cache in the example) and a type that specifies the service and version to use. Services that store persistent data have a disk key, to specify the amount of storage.

# The services of the project.
#
# Each service listed will be deployed
# to power your Platform.sh project.

db:
    type: mariadb:10.11
    disk: 2048

cache:
    type: redis:7.2

Define routes Anchor to this heading

All HTTP requests sent to your app are controlled through the routing and caching you define in a .platform/routes.yaml file.

The two most important options are the main route and its caching rules. A route can have a placeholder of {default}, which is replaced by your domain name in production and environment-specific names for your preview environments. The main route has an upstream, which is the name of the app container to forward requests to.

You can enable HTTP cache. The router includes a basic HTTP cache. By default, HTTP caches includes all cookies in the cache key. So any cookies that you have bust the cache. The cookies key allows you to select which cookies should matter for the cache. Generally, you want the user session cookie, which is included in the example for Drupal. You may need to add other cookies depending on what additional modules you have installed.

You can also set up routes as HTTP redirects. In the following example, all requests to www.{default} are redirected to the equivalent URL without www. HTTP requests are automatically redirected to HTTPS.

If you don’t include a .platform/routes.yaml file, a single default route is used. This is equivalent to the following:

.platform/routes.yaml
https://{default}/:
  type: upstream
  upstream: <APP_NAME>:http

Where <APP_NAME> is the name you’ve defined in your app configuration.

The following example presents a complete definition of a main route for a Drupal app:

.platform/routes.yaml
# The routes of the project.
#
# Each route describes how an incoming URL is going
# to be processed by Platform.sh.

"https://{default}/":
    type: upstream
    upstream: "drupal:http"
    cache:
      enabled: true

      # Base the cache on the session cookie and custom Drupal cookies. Ignore all other cookies.
      cookies: ['/^SS?ESS/', '/^Drupal.visitor/']

"https://www.{default}/":
    type: redirect
    to: "https://{default}/"

Is this page helpful?