Platform.sh is for lazy people (like me)
Who has time to keep a VPS up to date?
In: Drupal · Web Development · store.lathes.co.uk
Context
With the Drupal 7 EOL deadline looming, I needed to rebuild not only a huge website (more than 8000 products in over 2500 major categories) but also my hosting setup.
I had been running Aegir on a Linode VPS for most of the thirteen years of the website’s life. Aegir makes it very easy to spin up a Drupal website, and to make and restore backups. However it is quite time consuming to install and maintain, and I had to do a lot of manual work to keep the server up to date. I had to update Apache, PHP, MySQL, and the OS itself. I had to keep an eye on security updates and apply them manually. I had to keep an eye on the disk space and the memory usage. I had to keep an eye on the backups, because sometimes they would fail silently. I just don’t have that many eyes.
I like to crack a good puzzle, and I like everything to be in its right place. But I am an inherently lazy person. Unless it’s convenient enough for me not to test in production, I will test in production. Clone a VPS just to test a MySQL update? Fuck off. I would just put the site in maintenance mode, back up the whole server and then run the update in the small hours of the morning. If it broke I would roll back and try again.
Initially, Aegir was a good fit. I could create a practically unlimited number of development sites under subdomains of the Aegir front end in moments. Aegir creates the Apache vhosts file and the Drupal settings.php file from templates, and does a lot of other things that would have otherwise been very tedious. This at least made it convenient enough to clone my sites for development purposes rather than working on the live site. In the time before Docker or Composer, this workflow was very much preferable to manually creating virtual hosts entries and databases. It saved me a great deal of time.
Platform.sh
One thing that Linode and Platform.sh have in common is that they both provide excellent documentation. This includes documentation on using DDEV locally, and how to use a GitHub repository as the ‘source of truth’ for your production environment. An environment may be endowed with a particular version of PHP, Apache, MySQL, Redis, Memcached, Varnish, Solr, etc. by specifying their versions in a single YAML file. That configuration can be version-controlled along with the site’s codebase, and the two together can easily be replicated locally using DDEV.
When you make a change to the site’s codebase and push those changes to the repository, Platform.sh will automatically rebuild the environment from the YAML file, and rebuild the site from composer.json.
Drupal configuration can be also be exported to YAML files in the config/sync directory (with drush cex) and version-controlled. When those changes are pushed to Platform.sh, they will be imported automatically when the site is deployed.
Getting Started
There is a Drupal-specific guide that covers both deploying from scratch and migrating an existing site to Platform.sh.
Basically, it goes like this:
- Create a Drupal project from a template through the Platform.sh UI
- Install DDEV:
curl -fsSL https://ddev.com/install.sh | bash - Configure DDEV:
ddev config - Create an API token in your Platform.sh profile and then add it to DDEV:
ddev config global --web-environment-add=PLATFORMSH_CLI_TOKEN=API_TOKEN - Connect DDEV to Platform.sh:
ddev get ddev/ddev-platformsh - Run the project locally:
ddev start
Having followed these steps you’ll have a modern Drupal (10/11 at time of writing) site running locally with the same infrastructure as your production site. You can make changes to the stack locally, and then push the changes to your development or production environment with a simple platform push. Platform.sh will then build the environment with the new configuration and deploy it.
GitHub Integration
Separately, you can set up a GitHub repository as the ‘source of truth’ for your production environment. This is a bit more involved, but it’s worth it. It means that you can make changes to your site’s codebase locally (testing and debugging with DDEV), push them to GitHub, and the changes will be automatically deployed to your development environment for testing. A merge request is created in GitHub, and when it is merged the changes are deployed to the production environment.
This makes it convenient enough for me to no longer test anything in production, and encourages me to log my changes in the merge request. It also means that I can roll back to a previous version of the codebase if I’ve not tested thoroughly enough 😇
Did I mention that can include Drupal’s configuration as well? Pretty sweet.
Handy Commands
platform list- Display a list of all commands
Projects & Environments
platform- Display a list of projects, or within a project show the project’s environments and the console URL
platform mount:list- Get a list of mounts
platform activity:list- Get a list of activities for an environment or project
Mounts
Vanilla mount operations:
platform mounts- Get a list of mounts
platform mount:download --mount private --target ./junk- Download files from the
privatemount to the localjunkdirectory platform mount:upload --mount web/sites/default/files --source ./projects/9000F/docs- Upload files from the local
docsdirectory to the remoteweb/sites/default/filesmount
With rsync:
- If you want to sync the contents of a directory, you need to include the trailing slash.
- If you don’t, you will sync the directory itself.
rsync -azP "$(platform ssh --pipe)":web/sites/default/files/product-images/ ~/projects/9000F/img/- rsync down files from the remote
product-imagesdirectory to the localimgdirectory rsync -azP ~/projects/9000F/img/ "$(platform ssh --pipe)":web/sites/default/files/product-images/- rsync up files from the local
imgdirectory to the remoteproduct-imagesdirectory
Backups
platform backup:list- List available backups of an environment
platform backup:create- Make a backup of an environment
platform backup:restore- Restore an environment backup
Activities
Activities include things like builds, deployments, and backups. Sometimes they can get stuck, and you may need to view the log or report the activity ID to support.
platform activity:list- Get a list of activities for an environment or project
platform activity:get- View detailed information on a single activity
platform activity:log- Display the log for an activity
platform activity:cancel- Cancel an activity
Metrics and Logs
platform metrics:all- Show CPU, disk and memory metrics for an environment. Can also be run with
metrics:cpu,metrics:disk, andmetrics:mem platform ssh -p littertron.uk -e main tail /var/log/access.log -- -n50 -f- Tail the access log for the ‘main’ environment in project ‘littertron.uk’