The recommended way to deploy Drupal 8 on Platform.sh is to use Composer. Composer is the PHP package management suite, and is now supported by Drupal 8 (and Drupal 7 in a pinch). There is an unofficial but well-supported Composer flavor of Drupal 8 called Drupal Composer that we recommend. If you use the Drupal 8 Example Repository or select the Drupal 8 option when creating a new project from a template, that’s what you will be using.
You can also create your own project directly from that repository and add the Platform.sh-specific configuration files. Note that you will also need to add the Drupal.org Composer repositories to
composer.json if you are not working from our template.
If you use Drupal Composer, note that any 3rd party modules, themes, or PHP libraries you install, as well as Drupal core itself, will not be checked into your repository. They are specifically excluded from Git by a
.gitignore file, as they will be re-downloaded when you run
composer install or
composer update. Rather than downloading modules or themes using wget or FTP, you can add them using composer. For example, to add the
devel module you would run this command:
$ composer require drupal/devel
And then commit just the changes to
composer.lock to your repository. That also means that to get a working copy of your site locally you will need to run
composer install to download all of the necessary libraries and modules.
We also strongly recommend installing the Platform.sh Config Reader library, which simplifies access to the Platform.sh environment. The rest of this documentation assumes you have it installed.
$ composer require platformsh/config-reader
When using Composer, your docroot where most of Drupal lives will be called
web, but the
vendor directory will be outside of that directory in contrast to how a standard Drupal download
.tar.gz file is organized. The config export directory will also be outside of the web root. This is normal, expected, and more secure.
Your repository should be laid out as follows:
composer.json composer.lock config/ sync/ <this is where exported configuration will go> drush/ .git/ .gitignore .platform/ routes.yaml services.yaml .platform.app.yaml scripts/ web index.php ... (other Drupal core files) modules/ contrib/ <empty until composer runs> custom/ <your custom modules here> themes/ contrib/ <empty until composer runs> custom/ <your custom themes here> sites/ default/ settings.php settings.platformsh.php
Platform.sh exposes database configuration, as well as other configuration values such as a hash salt, to PHP as environment variables available either via
getenv(). That means you’ll need to tell Drupal how to get that information. Additionally, Drupal needs to be told where the config export directory is, where the private files directory is (which is outside of the web root), and so on.
The easiest way to access that information is via a small configuration add-on we provide. See our recommended
, which includes a file called
. The latter maps all Platform.sh-provided environment values to Drupal settings, either the Drupal database array or the global
$settings object. If run on a non-Platform.sh server this file does nothing so it is safe to always include.
If you need to add additional Platform.sh-specific configuration, such as to enable a
for caching, we recommend also putting it into
If you prefer, Drupal 8 can also be installed “vanilla” from Drupal.org, with the entire site checked into the repository. While not recommended it is fully supported. At the end of the day Platform.sh doesn’t care where your files come from, just that you tell the system where they are!
You will still need to put the Drupal docroot in a subdirectory of your repository. We recommend
web for consistency but any directory name will do.
If using a vanilla Drupal install, your repository should look something like this:
.git/ .gitignore config/ sync/ .platform/ routes.yaml services.yaml .platform.app.yaml web/ index.php ... (other Drupal core files) core/ modules/ sites/ sites/ default/ settings.php settings.platformsh.php
settings.platformsh.php files. Both should be identical to the ones used for a Composer-based site. Also note that the
config/sync directory is still outside the docroot. That is recommended for all Drupal installs generally, and is configured by the
.platform.app.yaml file will vary from project to project, and you are free to customize yours as needed. A recommended baseline Drupal 8 configuration is listed below, and can also be found in our
Drupal 8 template project
# This file describes an application. You can have multiple applications # in the same project. # # See https://docs.platform.sh/user_guide/reference/platform-app-yaml.html # The name of this app. Must be unique within a project. name: 'app' # The runtime the application uses. type: 'php:7.4' # 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: '/web/sites/default/files': source: local source_path: 'files' '/tmp': source: local source_path: 'tmp' '/private': source: local source_path: 'private' '/.drush': source: local source_path: 'drush' '/drush-backups': source: local source_path: 'drush-backups' '/.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. build: | set -e bash install-redis.sh 4.3.0 # The deploy hook runs after your application has been deployed and started. deploy: | set -e php ./drush/platformsh_generate_drush_yml.php cd web drush -y cache-rebuild drush -y updatedb drush -y config-import # The configuration of app when it is exposed to the web. web: # Specific parameters for different URL prefixes. locations: '/': # 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 # Whether to forward disallowed and missing resources from this # location to the application. # # Can be true, false or a URI path string. passthru: '/index.php' # Deny access to static files in this location. allow: false # Rules for specific URI patterns. rules: # Allow access to common static files. '\.(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 '/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. scripts: false rules: # Provide a longer TTL (2 weeks) for aggregated CSS and JS files. '^/sites/default/files/(css|js)': expires: 2w # The configuration of scheduled execution. crons: drupal: spec: '*/20 * * * *' cmd: 'cd web ; drush core-cron'