Blog

How the Platform.sh PaaS works

In this post I will present, in very broad strokes, the workings of Platform.sh from a functional perspective. This will not be a discussion of the intricate technical details, but rather a high-level description to help you understand what is happening under the hood.

– TLDR; Now go read the whole thing.

Platform.sh is a PaaS

Basically what this means, is that you, the user, only have to concern yourself with writing the application code. We take care of all the rest. We automatically manage everything that is needed to deploy the application, and all of its runtime dependencies. You need a database? We will deploy and configure it. And we will configure your app so it connects to it, as well as the copies of it that are made for each git branch. The same goes for search engines, caches, and the file system. We will configure the web server, we will configure the network. We take care of making sure everything can be consistently backed up, restored, etc. If something crashes, we take care of healing it; it’s our job to make sure your application’s infrastructure stays alive.

You take care of the code. That’s all. Batteries included. You don’t have to do any kind of sysadmin work. In order to put your code intro production, you just git push it.

We do give you all the tools to see what’s happening and to control precisely everything. It’s not a black box. You can ssh to the server. You can connect directly to the database and continue to use all the tools you are accustomed to. You can also automate everything. We have a REST API, as well as a very convenient CLI (command line interface) tool.

Platform.sh is a new kind of PaaS

You can call it a “second generation PaaS”. In first generation PaaS systems, like Heroku (but basically all the others), the service would manage the application (and do the same kind of magic, you push code and it puts it into production), and sometimes another service (like for Heroku a PostgreSQL database), but everything else was still the responsibility of the user. If you want a search engine, or another type of database, well you needed to get that from a third party, as an add-on.

They tried to make it as painless as possible, with integrated billing, and some help in injecting the configuration to your application, so it would be a bit more seamless, but this of course makes it more expensive, and more importantly much more complex (with many more possible failure scenarios, each different provider becomes a single point of failure - SPOF - for the whole thing). Because first generation PaaS systems manage only a small part of the application, you are still left with many things you need to care of by yourself.

Platform.sh manages everything it manages

In Platform.sh all the services you use are fully managed by the platform itself. This means that when you back up your application, everything get backed up. Consistently. Simply speaking, Platform.sh is a more general form of the same idea. This is why we always talk about “clusters”. When we deploy your application we build the different services the application will need and tie them together into a cluster. A group of servers that are a “whole”. Some of these services will be things like infrastructure elements, databases and such, but you can also deploy multiple applications in the same cluster.

Platform.sh supports multiple apps per cluster

If you have a website that runs on multiple APIs, each such service will be run as an independent server, but the whole thing will be tied together into a single cluster to form a coherent entity. This is really nice for people that like the “micro-service” style of architecture. With Platform.sh, we make it easy to manage a host of apps that work together.

Platform.sh has a persistent file system

Most PaaS systems, if not all, impose a unique constraint on developers. Their file system is either fully Read-Only, or are ephemeral. So basically you can not write to disk, or simply can not be sure it is going to be there. The main file system in Platform.sh is read-only, but we allow you to declare as many Read/Write directories as you would like. And the storage is managed. So when you back up your system they also get backed-up. When you clone a cluster they also get cloned. This means you do not need to hack your application to use something like S3 in order to have file uploads. Applications like Drupal, Magento, Prestashop or Wordspress, for example, function unmodified.

Platform.sh can clone a running cluster

This is probably the most useful, and most innovative feature we have to propose. Because Platform.sh manages everything as a coherent entity, with some powerful black magic we can almost instantly take a snapshot of the application cluster, duplicate it and create a new one, and push it to production. Because everything is managed, the new cluster will get new URLs, and all the apps inside it will get configured to work with each other. This allows you to create development or staging environments as you need those. You can develop using “feature branches” and for each feature have a fully isolated environment, so you can rapidly validate just that feature. This also means that you never have bugs that only appear on production, because you can test each branch with real content.

What happens when you deploy an app

Deploying an app means simply pushing the source code to our git server. The git server that runs on Platform.sh is at the same time “just a normal git repository” and a very smart piece of software. When you have pushed to it, it will try to understand what it needs to do. But you can also explicitly tell it precisely what requirements your application has.

The only modification you need to do to your application is to tell it to load its configuration from the environment (and we supply all the examples you need).

There are a couple of “dot files” in YAML format you can put at the root of your application that will describe its dependencies. You can say for example “my app needs mysql as a database”, or “my app needs this or that other php extension”, or you can say “my front web app depends on these three API apps”. If for example you need to build your app a specific Node.js, Python or Ruby library (for example Less or Jekyll) you simply specify those in the YAML file. There are many other aspects of the application you can control through this simple declarative style. You don’t write scripts, you just tell Platform.sh what you need.

Platform.sh is build oriented

This very smart git server on the other side is going to operate in five steps.

Configuration validation

First the git server is going to inspect what you have sent it and see that it understands what it is supposed to do. If for example you have a syntax error in a configuration file, it will simply refuse the push. The same with code where there is a huge security risk that Platform.sh knows how to detect. This is a good thing; Because it means you can’t break your production system that easily. Once the git server has validated the configuration and sees it can satisfy the requirements, it will build the cluster.

The git server is smart. It can diff not only the code but also the infrastructure; Say you had a single MySQL database in your cluster. And now you want two of those, maybe a PostrgreSQL and an Elastic Search instance. It will understand what it needs to do in the next phase to make sure the topology of your cluster is modified to your new needs.

Build

I already said the git server was smart… and it is a git server. So it will only build stuff that has changed. This is one of the things that make Platform.sh so fast in deployment. Using Linux Containers, Platform.sh will now, in parallel, build each server that had something that changed. If for example you pushed a Drupal Drush Makefile, or a PHP composer.json file, it will know it needs to go search for the dependencies, and shuffle things around to create the correct directory structure. If in your .platform.app.yaml file you also specified a “build hook”, you can now run whatever scripts you wish.

It is important to note that at this point the cluster has not been created yet. So you should not try to connect to a database or imagine anything was daemonized; This is just a build phase.

Prepare slug

The result of the build phase will be a file system, of which we now create an archive. We put this in permanent storage. So the next time push code, if a server did not change.. well we can just use this one; It also means that if you want to revert a deploy, it is basically instantaneous. Deterministic deployments are repeatable and reversible, after all.

Deploy slugs and cluster

Now Platform.sh provisions of all the elements it needs to run your application cluster. It will mount each service in its own container, configure the network so they can see each other (and only each other!) Here you need to remember that the main file system is read-only. This is what guarantees the fact that we can do deterministic deployments.

It will also mount all of the read/write directories you specified. Again unlike other PaaS systems, Platform.sh gives you persistent, normal, storage, it just needs to know which directories contain stuff that is mutable.

Deploy hooks

A last step allows you to run a post-deploy script (you can use this for example to run an anonymization script for deployment on development environments, clear caches, ping external CI tools, etc.) When this script runs you already have access to a fully running application.

Configure routing

If everything went fine, we are now ready to configure routing, so your web traffic will arrive at your newly created cluster. If something failed, well then nothing would have happened; the “old cluster” is still there, so from your users’ perspective, nothing changed. Neither failed nor successful deployments result in application downtime. Because we also route SSH you can also simply SSH to your cluster where you have the same permissions to execute commands as the web server.

Post-Scriptum

This was not a detailed explanation. Platform.sh has many other bells and whistles, but I hope this gives you a general idea on what is happening behind the scenes.

As a user, you don’t really need to know all of this; Most of the time for a relatively simple app, you would just push the code, and it would run. You would click on “branch” and it will create a new development cluster. It is our job to try to absorb all the tedious complexities. You do features, we run the infrastructure.

But as you can understand, because Platform.sh uses standard tools (git), exposes a rich API and has a very cool CLI, you can integrate it in more complex workflows. You could for example use the Github integration, or webhooks, to make it work with an existing workflow or CI system like Jenkins or Travis. You could dynamically configure access rights and per-environment routing rules; but most of the time, you’d just push code and not care about all of this.

Ori Pekelman
Ori Pekelman