June 27, 2017
by Serhey Dolgushev
We had eZ Publish 4.3 website with DFS cluster and wanted to move it to a Production Standard platform.sh instance. The main steps in this process are:
- Setup platform.sh services and routes.
- Describe the platform.sh application.
- Inject service configurations into the eZ Publish settings.
- Deploy code base to platform.sh.
Setting up platform.sh services and routes
Platform.sh uses services.yaml for services and routes.yaml for routes configuration. Both of them are well documented, so we will focus only on our use case.
Our project does not using any custom rewrite rules, that’s why our routes definition file is the simplest possible:
upstream: "theoneweekboutique:http"
|
view raw routes.yaml hosted with ❤ by GitHub
We are not using SOLR on our project, so MySQL was the only other service needed. But we were using a separate database for DFS clusterization on our previous hosting platform, and we wanted to keep it. That’s why we need two databases on platform.sh: main and cluster. In this case the services definition file looks like:
view raw services.yaml hosted with ❤ by GitHub
It looks pretty simple and please feel free to ask a question in comments or check platform.sh Database service documentation if you have some questions about it.
The last remaining configuration file is the application definition file, which is .platform.app.yaml.
Describe platform.sh application
In our case the application definition file was the following:
# This file describes an application. You can have multiple applications
|
# The name of this app. Must be unique within a project.
|
# The type of the application to build.
|
# 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>`.
|
database: "mysqldb:mysql"
|
# The configuration of app when it is exposed to the web.
|
# The public directory of the app, relative to its root.
|
# The front-controller script to send non-static requests to.
|
"^/var/([^/]+/)?storage/images-versioned/.*":
|
passthru: "/index_cluster.php"
|
"^/var/([^/]+/)?storage/images/.*":
|
passthru: "/index_cluster.php"
|
"^/var/([^/]+/)?cache/public/(stylesheets|javascript)":
|
passthru: "/index_cluster.php"
|
# The size of the persistent disk of the application (in MB).
|
# The mounts that will be performed when the package is deployed.
|
"/var": "shared:files/var"
|
"/mount": "shared:files/mount"
|
# The hooks that will be triggered when the package is deployed.
|
# Build hooks can modify the application files on disk but not access any services like databases.
|
php bin/php/ezpgenerateautoloads.php -o
|
php bin/php/ezpgenerateautoloads.php
|
# Deploy hooks can access services but the file system is now read-only.
|
php bin/php/ezcache.php --clear-all
|
view raw .platform.app.yaml hosted with ❤ by GitHub
Some comments about it:
- We decided to use PHP 5.4 for this application because of the eZ Publish version.
- Composer is not used in this case and that’s why "build.flavor” is set to “none”.
- web.locations./.rules defines the eZ Publish clustering rewrite rules.
- /mount is the DFS mount point, specified eZ Publish Legacy clustering configuration. And please note that only /var and /mount paths are writeable after the application is built on platform.sh.
- In “hooks.build” we are overriding eZ Publish kernel autoloads to be able to use a custom eZINI class to read database settings from environment variable and it will be covered below. Also we are regenerating regular autoloads file.
- In hooks.deploy we clear the caches.
Inject service configurations to eZ Publish settings
Platform.sh assumes that application will read service configurations from PLATFORM_RELATIONSHIPS environmental variable. But eZ Publish Legacy does not have any built-in functionality for doing this. That’s why we came up with our solution: override eZINI class and implement some custom code to read configurations from the environment variable. In order to implement it, you need to:
- Set EZP_AUTOLOAD_ALLOW_KERNEL_OVERRIDE to true in config.php file
- Copy eZINI class (lib/ezutils/classes/ezini.php) to a site specific extension. Let’s assume you are using “site” extension for your project settings and templates. Than you need to run: $ cp lib/ezutils/classes/ezini.php extension/site/classes/override/ezini.php
- Regenerate autoloads with-o flag:
$ php bin/php/ezpgenerateautoloads.php -o
|
Scan complete. Found 483 PHP files.
|
Searching for classes (tokenizing).
|
Class eZINI in file extension/site/classes/override/ezini.php will override:
|
lib/ezutils/classes/ezini.php (autoload/ezp_kernel.php)
|
function parse( $inputFiles = false, $iniFile = false, $reset = true, $placement = false )
|
$files = array( 'site.ini', 'file.ini' );
|
if ( in_array( $this->FileName, $files ) )
|
$relationships = getenv('PLATFORM_RELATIONSHIPS');
|
if ( $relationships !== false )
|
$relationships = json_decode( base64_decode( $relationships ), true );
|
foreach ( $relationships['database'] as $endpoint )
|
if ( $endpoint['query']['is_master'] !== true )
|
if ( $this->FileName === 'site.ini' )
|
$this->BlockValues['DatabaseSettings']['Database'] = 'main';
|
$this->BlockValues['DatabaseSettings']['Server'] = $endpoint['host'];
|
$this->BlockValues['DatabaseSettings']['Port'] = $endpoint['port'];
|
$this->BlockValues['DatabaseSettings']['User'] = $endpoint['username'];
|
$this->BlockValues['DatabaseSettings']['Password'] = $endpoint['password'];
|
else if ( $this->FileName === 'file.ini' )
|
$this->BlockValues['eZDFSClusteringSettings']['DBName'] = 'cluster';
|
$this->BlockValues['eZDFSClusteringSettings']['DBHost'] = $endpoint['host'];
|
$this->BlockValues['eZDFSClusteringSettings']['DBPort'] = $endpoint['port'];
|
$this->BlockValues['eZDFSClusteringSettings']['DBUser'] = $endpoint['username'];
|
$this->BlockValues['eZDFSClusteringSettings']['DBPassword'] = $endpoint['password'];
|
-
view raw custom_ezini.php hosted with ❤ by GitHub
After these steps the database settings are extracted from PLATFORM_RELATIONSHIPS environment variable and injected into site.ini and file.ini configuration files. Please note, you will need to modify this code if you are using SOLR or trying to inject settings to eZ Publish legacy for any other platform.sh services.
Deploy code base to platform.sh
This is probably the simplest step - you just need to follow platform.sh suggestions. In two words: platform.sh provides you a git repository for the project. You should add that repository as an additional origin. Each time you push the master branch to that origin, the application is build and deployed on platform.sh.
If you are using git submodules (which is quite common phenomenon for eZ Publish Legacy projects), you need to add platform.sh deploy key to list of your SSH keys on Github/Gitlab/Bitbucket/etc. You can find it on configure project page, DEPLOY KEY tab.
We hope this blog post was useful for you! If you have any questions, please contact us or leave a comment.