How to run your Symfony2 PHP app on Azure website

Windows AzureBestComparator is part of the DojoBoost accelerator in Paris and a Bizpark partner. We have the chance to have some partnerships with Microsoft and thus have some support and early access to some technology. Especially about Windows 8 and Azure.

Talking about Azure, they made tremendous upgrades to the platform during the year. They moved from a PAAS platform to a full layered cloud solution. From SAAS to IAAS you can do almost everything. Create a WordPress in a few clicks, create a VM, configure a VPN, create a SQL server, create a mobile service that interface an autogenerated backend storage with your iPhone/Android/Windows phones, scale your services by moving a slider…
Being at the Azure Open Source Summit really amazed me about all the possibilities that are offered to developers and how fast new features comes to the portal. One of those which interested me the most is the possibility to run a PHP website on Azure using the Web Site feature.

About PHP and Azure

PHPYou currently have two main options to run PHP on azure.

First you can simply create a VM using Azure Virtual Machine, after choosing an OS (Windows Server, CentOS, Suse, Ubuntu…) you just connect to your server and configure everything you need. You can change the size of you VM, it goes up to 8 cores and 15GB of RAM. I am running it in production for a few mounts now, and it is pretty stable and reliable. Nevertheless there are some drawbacks. You have to maintain your environment (which is not my job) and it has some limitations in terms of scalability (if you want more power, you will need to maintain another VM and start configuring load balancing and synchronization…). This is pure IAAS.

The other option I recently explored is using Azure website. You simply ask for a computation service which uses a code synchronized via git. It takes care about all the environment maintenance for you and just runs your code. Moreover, you can leverage some nice features such as the possibility to increase the size of the underlying instance (up to 4 cores and 7GB of RAM), but also increase the number of instances (up to 20) seamlessly. Azure takes care of the rest for you. This is more PAAS oriented and let you concentrate on developing your app.

Let’s start a first PHP website:

  1. First of all go to your azure portal
  2. Create a new website using the custom wizard
  3. Select the name of your website, the region, a database (or not) and check the “publish from source control” option
    step2
  4. Choose “git” and “local git repository” as source control setup
    step3
  5. In a third step select your credential, they will be required for git synchronization and ftp login (if you want to)
  6. Now, open the deployments panel in the newly created website you will find there the git url
    step4
  7. On your local machine, simply clone the repository (or set a remote): git clone https://michel@blog-test.scm.azurewebsites.net/blog-test.git
  8. Put your PHP code in the cloned repository, commit, and push to azure
  9. When pushing to azure, it will automatically publish the newly updated code to the website, you can visualize it directly by connecting to the url of the website displayed in the website dashboard

At this point you can upload PHP code to Azure and run it. Here is what you might want to know:

  • You can switch PHP version (5.3 and 5.4) in the configure tab
  • You can scale the size and the number of the instances in the scale tab
  • You can map your domain name using the “manage domain” option available in the bottom bar if you are in “shared” or “reserved” mode (available in the scale tab)
  • If you don’t want to deploy from a local git repo, you can using github, codeplex or bitbuket. It is configurable from the wizard in step 4.
  • You can set environment variables in the configure tab
  • You can choose which branch of your git to deploy in the configure tab
  • You can access the server via ftp using the credential given in step 5 and the ftp configuration in the dashboard
  • You can override the php.ini by giving a .user.ini at the root of your repo

What about Symfony2 websites?

Symfony2 LogoRunning a Symfony2 website is doable but it will require some more work. You will have two main issues to fix:

  1. Activate url rewriting to web/app.php, and reroute web requests to the web directory
  2. Find a way to use the composer and the console

The first issue can be tackled simply by adding a Web.Config file at the root of you repo. It works just like .htaccess for apache but for IIS. Here is the content:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="web directory">
                    <match url=".*" ignoreCase="false" />
                    <action type="Rewrite" url="web/{R:0}" appendQueryString="true" />
                </rule>
                <rule name="app_php handling" stopProcessing="true">
                    <match url="^(.*)$" ignoreCase="false" />
                    <conditions logicalGrouping="MatchAll">
                        <add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
                    </conditions>
                    <action type="Rewrite" url="/web/app.php" appendQueryString="true" />
                </rule>
            </rules>
        </rewrite>
    </system.webServer>
</configuration>

In the Web.Config file we define two rules. The first one reroutes every request to the web directory, and the second one routes the requests to the web/app.php script when there is no physical file requested.

I did not yet tackled the second issue (ie. composer and console use). What I know is that there is no command line access to Azure website but it seems like you can use the exec PHP function from PHP scripts. So everything seems doable with some web interface that simulates command line using PHP functions. I will edit this post as soon as I find a better solution.

What if I want to add some extensions/tweak to PHP runtime?

You may notice that Symfony recommends the use of the intl extension for PHP which is used for internationalization of the validation component (and also in some BCC bundles). You might also need a specific setup of PHP such as a specific version, a configuration which cannot be overridden in the .user.ini file or another extension.

Don’t worry, you can give to Azure you own PHP runtime:

  1. Go to http://windows.php.net/download/ and get the version of PHP you want (which has to be “VC9 x86 Non Thread Safe”)
  2. Unzip it to a directory in your repo, in my case in a ./bin directory
  3. Configure your php.ini file in bin/php.ini
  4. Remove the extensions you don’t want in bin/ext/*
  5. Add, commit and push the files (which might take some time considering the size of your php runtime)
  6. When git is synchronized, go the configure tab on azure
  7. At the bottom of the section, add a handler mapping configuration. The extension is *.php and the script processor path is D:\home\site\wwwroot\bin\php-cgi.exe (because D:\home\site\wwwroot\ is the root of the website and my PHP runtime is in the bin directory)
    step5

Everything is set and you website now runs on your own PHP runtime.

Wrap up

Despite Azure is very young, it offers a lot of possibilities in terms or configuration. I hope this post will help you understand better how it works and how to setup your favorite PHP environment while leveraging all the nice features of Azure.

Advertisements

My take on the Mahout and Myrrix recommendation algorithms

MahoutWhereas BestComparator has his own recommendation engine based on user profiling, behavior analysis and analysis of product specs, I recently wanted to explore the possibilities of the famous recommendation engine built inside Mahout.

First of all, Mahout is a set of machine learning algorithms which leverage the Hadoop environment, providing powerful and scalable algorithms. One of its main target is the recommendation algorithms also known as taste collaborative filtering.

Recommendation algorithms have been made famous by websites such as Amazon, Youtube or Netflix. They use it to make suggestions based on what you bought, watched or liked.

Myrrix

MyrrixOne of the author of Taste/Mahout recommender engine, Sean Owen decided to give the engine a more formal structure by building Myrrix.

Myrrix is a recommendation engine based on Mahout. It offers an out of the box configuration for a recommendation engine accessible with a Rest API. The good to know are:

  • Scalable as Mahout and Hadoop are scalable, using computing parallelization and a distributed file system
  • Runs an optimized version of Taste (currently Taste 3)
  • Runs in real time
  • Can be efficient even with a relatively small amount of data

Recommendation process

The first thing you want to do is to feed your model (ie. Your algorithm) with current observed data. The models aggregates users, items and the associations between them. These associations are called preferences and are qualified by their value, describing the strength of the association between the user and the item.

Feeding the engine means pushing every observed associations with the user id, the item id and the strength. You are simply giving the engine your current taste graph, linking users to items via their tastes.

When your engine is fed, you have to ask it to refresh. Thus it will re-analyze the given graph and compute an actualized, and thus better, model. This may take some time, but Myrrix has the ability to continue answer your requests during this time.

Finally, with your shinny model you can ask questions and get recommendations. Here are the main queries:

  • Recommend to a user
  • Recommend to a group of users
  • Recommend to an anonymous user
  • Recommend similar items
  • Estimate the strength of the preference between an user and an item

With such a panel of tools you can easily guess that answering the question “What item users like me also liked?” becomes accessible.

Consuming Myrrix from PHP

PHPIn order to integrate Myrrix results to my recommendation engine, I had to build a PHP Myrrix client. I decided to use the Guzzle library that provides a really neat way of building a PHP client for Rest APIs. You can download my library on the open source Github Project: https://github.com/michelsalib/bcc-myrrix.

After installing the library, you can write some very fancy code:

// Get a client
$this->client = MyrrixClient::factory(array(
    'hostname' => 'localhost',
    'port'     => 8080,
));

// Put a user/item assocation, here use #101 as an association of strength 0.5 with item #1000
$command = $this->client->getCommand('PostPref', array(
    'userID' => 101,
    'itemID' => 1000,
    'value'  => (string)0.5,
));
$this->client->execute($command);

// Refresh the index
$command = $this->client->getCommand('Refresh');
$this->client->execute($command);

// Get a recommendation for user #101
$command = $this->client->getCommand('GetRecommendation', array(
    'userID' => 101,
));
$recommendation = $this->client->execute($command)->json();

Here we instantiate a Myrrix client hosted on the localhost on port 8080. We put into the model a preference of 0.5 between the user #101 and the item #1000. We then ask the model to refresh. Finally we get a recommendation for the user #101. The recommendation result is an array of item id with their estimated strength for the given user.

The library is pretty straight forward and help you leverage in a very simple way all the powerfulness of the Myrrix engine from PHP.

I also made a Symfony Bundle that helps you get the client from the dependency container, and offers a cleaner configuration process: https://github.com/michelsalib/BCCMyrrixBundle.

Don’t hesitate to get the code, install it and test it. I would be very happy to get contributions, feedbacks or feature requests.