Building a cloud-friendly application

Presented by Larry Garfield (@Crell)


Larry implements Huggable
  • Director of DX,
  • PHP-FIG Core Committee
  • implements Huggable
Software is eating the world, and cloud is eating software. (Source: @bassamtabbara)
What is cloud
What is
The Cloud?

These are separate questions...

The Cloud™: noun

Someone else's hard drive

Cloud computing: noun

Abstracting away physical infrastructure

Disposable application design

What makes an application cloud-friendly?

They're not rules

They're more like guidelines...

They're more like guidelines

Split code from content


  • Provided by developer
  • Carefully tested
  • Lives in version control
  • Read-only runtime


  • Provided by users
  • Frequently ad hoc
  • Lives in DB or filesystem
  • Writeable runtime
Don't mix the filesystems

Your application is disposable. Your data is not.

Data flow

You don't get an in-between option


Cleanly separate "Dev provided" and "user provided" files

What is configuration?

Does config come from the developer or the user?

Git or Database?

Drupal Config Management

Drupal 8
  1. Configure in UI / DB
  2. Export to YAML
  3. Commit to Git
  4. Push / Pull
  5. Import back to DB



What happens at runtime
stays at runtime

Application slots into cluster

Dependency inject your environment

  • DB credentials (Solr, Redis, etc.)
  • API keys
  • All paths on disk
  • Domain names

Environment variables




Only ever use getenv()

Need glue code

Symfony 3

// platform_parameters.php
// Configure the database.
    $dbRelationshipName = 'database';
    $relationships = json_decode(base64_decode(getenv('PLATFORM_RELATIONSHIPS')), true);

    foreach ($relationships[$dbRelationshipName] as $endpoint) {
        if (!empty($endpoint['query']['is_master'])) {
            $container->setParameter('database_driver', 'pdo_'.$endpoint['scheme']);
            $container->setParameter('database_host', $endpoint['host']);
            $container->setParameter('database_port', $endpoint['port']);
            $container->setParameter('database_name', $endpoint['path']);
            $container->setParameter('database_user', $endpoint['username']);
            $container->setParameter('database_password', $endpoint['password']);
            $container->setParameter('database_path', '');
// Set a default unique secret, based on a project-specific entropy value.
    $container->setParameter('kernel.secret', getenv('PLATFORM_PROJECT_ENTROPY'));
 / Symfony 4

composer require platformsh/symfonyflex-bridge


function mapPlatformShEnvironment() : void
    if (!getenv('PLATFORM_APPLICATION')) {

    $secret = getenv('APP_SECRET') ?: getenv('PLATFORM_PROJECT_ENTROPY') ?: null;
    setEnvVar('APP_SECRET', $secret);

    $appEnv = getenv('APP_ENV') ?: 'prod';
    setEnvVar('APP_ENV', $appEnv);

    if (!getenv('DATABASE_URL')) {
// ...
 / Laravel

composer require platformsh/laravel-bridge


function mapPlatformShEnvironment() : void
    if (!getenv('PLATFORM_APPLICATION')) {


    $secret = getenv('APP_KEY') ?: getenv('PLATFORM_PROJECT_ENTROPY') ?: null;
    setEnvVar('APP_KEY', $secret);

    $secure_cookie = getenv('SESSION_SECURE_COOKIE') ?: 1;
    setEnvVar('SESSION_SECURE_COOKIE', $secure_cookie);

    if (getenv('PLATFORM_RELATIONSHIPS')) {
        $relationships = json_decode(base64_decode(getenv('PLATFORM_RELATIONSHIPS'), true), true);
        mapPlatformShDatabase('database', $relationships);
        mapPlatformShRedisCache('rediscache', $relationships);
        mapPlatformShRedisSession('redissession', $relationships);
// ...

Glue of last resort


    "autoload": {
        "files": ["extra-bridge.php"]

Only works if your app reads env vars...

Use DotEnv

(PHP has several... because PHP)





Dependency inject your environment

User-configured connections


  1. Ask for DB credentials
  2. Ask user for basic site info
  3. Write credentials to config file
  4. Populate DB
  5. Write basic site info to config file/DB
  6. Profit!!!


Better installers

  • Pre-include connection glue
  • Installer skips pre-populated values
  • Do not download from installer

Avoid lock-in

Always be able to
take your business elsewhere.

Use Free Software

Use replaceable services

Google has killed...

  • Reader
  • iGoogle
  • Google Talk
  • Google Health
  • Knol
  • Google Insights
  • Picnik
  • Buzz
  • Aardvark
  • Sidewiki
  • Notebook
  • Dictionary
  • Labs
  • Wave
  • SearchWiki
  • Dodgeball
  • Jaiku
  • Lively
  • Page Creator
  • Zeitgeist
  • Answers
  • Google X
  • Catalog
  • Web Accelerator
  • Video Player
  • Sets
  • SearchMash
  • Writely

Source: WordStream (2015)


  • MySQL/MariaDB
  • PostgreSQL
  • MongoDB
  • RabbitMQ
  • Solr/Elasticsearch
  • InfluxDB


  • Amazon RDS
  • Amazon DynamoDB
  • Azure Cosmos DB
  • Anything you can't replace in a day

Microservices: Threat or menace

What is a microservice?

There is no industry consensus yet regarding the properties of microservices, and an official definition is missing as well.


Properties of microservice design

  • Single-purpose components
  • Dumb pipes (HTTP, IPC, etc.)
  • Separate teams
  • Independent releases

(Sources: Wikipedia, Martin Fowler)

Every microservice treats every other microservice as a separate 3rd party that may as well be a different company.


  • Different tools/languages
  • Small, focused, interdisiplinary teams
  • Strong separation of concerns
  • Scale/evolve/replace separately
Any organization that designs a system (defined broadly) will produce a design whose structure is a copy of the organization's communication structure.

Conway's Law


  • Network latency
  • Network points of failure (plural)
  • Transitioning code is 10x harder
  • API versioning
  • More staff needed
  • PHP startup time
"If one of your microservices going down means the others don't work, you don't have a microservice; you have a distributed monolith."

—A few dozen people

So if microservices aren't for me, what is?

Clustered applications

Clustered applications

  • Single team
  • Disrete components
  • Deploys as once
  • Usually one language (not required)
  • May share datastores

You've probably already done this

Clustered applications

Cron jobs

"Admin" application

Queue workers

API app

All asynchronous

Microservices * More points of failure * Split by team * Split by async * "If the request can't complete if the service goes down, it's not a microservice." * If they deploy together are they microservices? Maybe. (Workers vs. separate apps.)

To summarize...

Remember what they say when you assume

Larry Garfield


Director of Developer Experience

Continuous Deployment Cloud Hosting

Stalk us at @PlatformSH