East PaaS

Create a custom PaaS manager following the #East programming philosophy.


Package, to use with East Foundation, to implement custom PaaS manager to deploy easily containerized applications on container-orchestration system like Kubernetes.

This package was inspired by commercial solutions such as Platform.sh, Symfony Cloud or Heroku.

The library is provider free. Thanks to interfaces defined in this library, DI and Teknoo/Recipe you can adapt this library to any orchestration system.

However, a Docker client and a Kubernetes client are bundle with the library.

You can use directly this library on your personal Docker registry and Kubernetes cluster or use any commercial solution.

An implementation of this library is available here

A demo deployed by the project above is available here

Kubernetes

Features


Flexible

PaaS adapts to your projects

Independent

Not require any cloud provider or on-premise solution

Docker / Kubernetes

Docker and Kubernetes clients are natively bundled

Extendable

Can be extendable only via the DI's configuration or thanks to Recipe.

GitHub


Fork the project on GitHub

It is open source! It's hosted, developed, and maintained on GitHub by folks like you.


View GitHub Project

Patreon


Support this project on Patreon

This project is free and will remain free, but it is developed on my free time. If you like it and help me maintain it and evolve it, don't hesitate to support me on Patreon. Thanks :) Richard.


Support it

File deployment example



paas: #Dedicated to compiler
  version: v1

#Custom image, not available in the library
images:
  foo:
    build-name: foo
    tag: lastest
    path: '/images/${FOO}'

#Hook to build the project before container, Called in this order
builds:
  composer-build: #Name of the step
    composer: ${COMPOSER} #Hook to call

#Volume to build to use with container
volumes:
  main: #Name of the volume
    target: '/opt/paas/' #Path where data will be stored into the volume
    add: #folder or file, from .paas.yml where is located to add to the volume
      - 'src'
      - 'vendor'
      - 'composer.json'
      - 'composer.lock'
      - 'composer.phar'
  other_name: #Name of the volume
    target: '/opt/vendor/' #Path where data will be stored into the volume
    add: #folder or file, from .paas.yml where is located to add to the volume
      - 'vendor'

#Pods (set of container)
pods:
  php-pods: #podset name
    replicas: 1 #instance of pods
    containers:
      php-run: #Container name
        image: php-run #Container image to use
        version: 7.4
        listen: #Port listen by the container
          - 8080
        volumes: #Volumes to link
          - main
        variables:
          SERVER_SCRIPT: '/opt/paas/src/server.php'

#Pods expositions
services:
  php-pods: #Pod name
    - listen: 9876 #Port listened
      target: 8080 #Pod's port targeted

Manager implementation example



//Kernel
<?php

declare(strict_types=1);

use 
DI\Bridge\Symfony\Kernel as BaseKernel;
use 
Symfony\Component\Config\Loader\LoaderInterface;
use 
DI\ContainerBuilder as DIContainerBuilder;

class 
Kernel extends BaseKernel
{
    protected function 
buildPHPDIContainer(DIContainerBuilder $builder)
    {
        
// Configure your container here
        
$rootPath /**/;

        
$builder->addDefinitions($vendorPath '/teknoo/east-foundation/src/di.php');
        
$builder->addDefinitions($vendorPath '/teknoo/east-foundation/infrastructures/symfony/Resources/config/di.php');

        
$builder->addDefinitions($vendorPath '/teknoo/east-website/src/di.php');
        
$builder->addDefinitions($vendorPath '/teknoo/east-website/infrastructures/doctrine/di.php');
     & nbsp;  
$builder->addDefinitions($vendorPath '/teknoo/east-website/infrastructures/symfony/Resources/config/di.php');
        
$builder->addDefinitions($vendorPath '/teknoo/east-website/infrastructures/di.php');
        
$builder->addDefinitions($vendorPath '/teknoo/east-paas/src/di.php');
        
$builder->addDefinitions($vendorPath '/teknoo/east-paas/infrastructures/Doctrine/di.php');
        
$builder->addDefinitions($vendorPath '/teknoo/east-paas/infrastructures/Flysystem/di.php');
        
$builder->addDefinitions($vendorPath '/teknoo/east-paas/infrastructures/Git/di.php');
        
$builder->addDefinitions($vendorPath '/teknoo/east-paas/infrastructures/Kubernetes/di.php');
        
$builder->addDefinitions($vendorPath '/teknoo/east-paas/infrastructures/Docker/di.php');
        
$builder->addDefinitions($vendorPath '/teknoo/east-paas/infrastructures/Composer/di.php');
        
$builder->addDefinitions($vendorPath '/teknoo/east-paas/infrastructures/Symfony/Components/di.php');

        
$builder->addDefinitions($rootPath.'/config/di.php');

        
/**/
        
$builder->addDefinitions([
            \
Doctrine\Common\Persistence\ObjectManager::class => \DI\get('doctrine_mongodb.odm.default_document_manager'),
        ]);

        return 
$builder->build();
    }
}

//bundles.php
return [
    
//...
    
Teknoo\East\FoundationBundle\EastFoundationBundle::class => ['all' => true],
    
Teknoo\East\WebsiteBundle\TeknooEastWebsiteBundle::class => ['all' => true],
    
Teknoo\East\Paas\Infrastructures\EastPaasBundle\TeknooEastPaasBundle::class => ['all' => true],
    
//...
];

//In doctrine config
doctrine_mongodb:
    
document_managers:
        default:
            
auto_mappingtrue
            mappings
:
            
TeknooEastWebsite:
                
type'xml'
                
dir'%kernel.project_dir%/vendor/teknoo/east-website/infrastructures/doctrine/config/universal'
                
is_bundlefalse
                prefix
'Teknoo\East\Website\Object'
            
TeknooEastWebsiteDoctrine:
                
type'xml'
                
dir'%kernel.project_dir%/vendor/teknoo/east-website/infrastructures/doctrine/config/doctrine'
                
is_bundlefalse
                prefix
'Teknoo\East\Website\Doctrine\Object'
            
TeknooEastPaas:
                
type'xml'
                
dir'%kernel.project_dir%/vendor/teknoo/east-paas/infrastructures/Doctrine/config/universal'
                
is_bundlefalse
                prefix
'Teknoo\East\Paas\Object'
            
TeknooEastPaasInfrastructuresDoctrine:
                
type'xml'
                
dir'%kernel.project_dir%/vendor/teknoo/east-paas/infrastructures/Doctrine/config/odm'
                
is_bundlefalse
                prefix
'Teknoo\East\Paas\Infrastructures\Doctrine\Object\ODM'

//In messenger.yml
framework:
    
messenger:
    
transports:
        
app_message_job'%env(MESSENGER_JOB_TRANSPORT_DSN)%'

    
routing:
        
Teknoo\East\Paas\Infrastructures\Symfony\Messenger\Message\Job'app_message_job'


//In security.yml
security:
    
//..
    
providers:
    
main:
        
id'teknoo.east.website.bundle.user_provider'

//In routing.yml
website:
    
resource'@TeknooEastWebsiteBundle/Resources/config/routing.yml'
    
app_job_new:
    
path'/project/{projectId}/environment/{envName}/job/create'
    
methods:  ['GET''POST''PUT']
    
defaults: { _controller'teknoo.east.paas.symfony.end_point.new_job' }

app_job_add_history:
    
path'/project/{projectId}/environment/{envName}/job/{jobId}/log'
    
methods:  ['PUT']
    
defaults: { _controller'teknoo.east.paas.symfony.end_point.job_add_history' }

app_worker_job_run:
    
path'/project/{projectId}/environment/{envName}/job/{jobId}/run'
    
methods:  ['PUT']
    
defaults: { _controller'teknoo.east.paas.symfony.end_point.job_run' }

//in config/di.php
return [
    
'app.paas.hostname' => env('WEBSITE_HOSTNAME''localhost'),
    
'app.paas.job_root' => env('JOB_ROOT', \sys_get_temp_dir()),

    
'teknoo.east.paas.worker.add_history_pattern' => function (ContainerInterface $container): string {
        return 
'https://' $container->get('app.paas.hostname') . '/project/{projectId}/environment/{envName}/job/{jobId}/log';
    },

    
'teknoo.east.paas.conductor.images_library' => [
        
'php-run-74' => [
            
'build-name' => 'php-run',
            
'tag' => '7.4',
            
'path' => '/library/php-run/7.4/',
        ],
        
//...
    
],

    
'teknoo.east.paas.root_dir' => \dirname(__DIR__),
    
'teknoo.east.paas.worker.tmp_dir' => get('app.paas.job_root'),

    
HooksCollectionInterface::class => static function (ContainerInterface $container): HooksCollectionInterface {
        return [
            
'composer' => $container->get(ComposerHook::class);
        ]
    },

    
UriFactoryInterface::class => //...
    
ResponseFactoryInterface::class => //...
    
RequestFactoryInterface::class => //...
    
StreamFactoryInterface::class => //...
  & nbsp; 
ClientInterface::class => //...
];