Composer Support for Azure App Service Web App via Site Extension

In a previous post I outlined how to enable deployment time dependency management with Wep App by hooking the deployment with Kudu. In this post, I will explain how I iterated on the techniques used  in that previous post, to enable Composer in Web App via a Site Extension which lowers the barrier to use Composer with Web App.

Cool, but what exactly is a Site Extension?

Site Extensions are a means of extending the Azure App Service platform. The best part about Site Extensions are that they can be created by anyone, it is as simple as creating a Website, WebJob or IIS Module, an applicationHost.xdt file (applicationHost.config Transform), and possibly some supporting files to help install or setup the Site Extension components. These components are then packaged with NuGet and uploaded to the Site Extension Gallery

More information is available on how to create a Site Extension is available in the Kudu Wiki.

Now, How do I use Composer in Web App?

To get started with Composer on Web App, you’ll need to install the Site Extension, luckily I wrote a post which explains how to enable a site extension. You’ll find Composer in the list of Site Extensions.

Creating a web site which uses Composer

Composer has a number of different ways that it can be leveraged, you can run it as a tool from the command line directly to have it build files or you can manually create a composer.json file. I’ll refer you to the documentation to figure out how you’d like to use it.

For my application, I crafted the composer.json file by hand using Packagist as a reference for my file dependencies. I wanted to create an application which lists files from a particular container in Azure Storage, this means I would require the Microsoft Azure SDK for PHP and it’s dependencies. Here is my composer.json file.

{
  "require": {
      "pear-pear.php.net/HTTP_Request2": "*",
      "pear-pear.php.net/Mail_Mime": "*",
      "pear-pear.php.net/Mail_mimeDecode": "*",
      "microsoft/windowsazure": "*"
  },          
  "repositories": [
      {
          "type": "pear",
          "url": "http://pear.php.net"
      }
  ],
  "minimum-stability": "dev"
}

The composer.json file should be placed in the root of the repository. The Composer Site Extension has the COMPOSER_VENDOR_DIR set to d:\home\site\vendor which is out of the public wwwroot directory so that the dependencies cannot be addressable publicly.

Now that we have our dependencies taken care of simply build a PHP application which requires the autoloader which is created for us by composer, then write our code. Here is my index.php file which iterates over items in my storage container.

<?php

require_once "../vendor/autoload.php";

use WindowsAzure\Common\ServicesBuilder;
use WindowsAzure\Common\ServiceException;

$blobRestProxy = ServicesBuilder::getInstance()->createBlobService(getEnv('CUSTOMCONNSTR_BlobConnectionString'));

try {
    // List blobs.
    $blob_list = $blobRestProxy->listBlobs(getenv('container'));
    $blobs = $blob_list->getBlobs();

	echo "<ul>";
    foreach($blobs as $blob)
    {
        echo "<li><a href=".$blob->getUrl().">".$blob->getName()."</a></li>";
    }
	echo "</ul>";
	
} catch(ServiceException $e){
    $code = $e->getCode();
    $error_message = $e->getMessage();
    echo $code.": ".$error_message."<br />";
}

Deploy! and Configure

Now we’re ready to deploy the application and configure a few of the settings to make the application come to life. Click the button below to deploy the application into your Microsoft Azure Subscription:

This Deploy to Azure button could be configured to set these App Settings automatically on deployment, If you see a azuredeploy.json file in the repository you can disregard the following steps. As I have found the time to make the Azure Resource Manager template to hydrate these values.

Add the following App Settings to the App Settings list in the Portal:

  • container – This is the name of the container in your storage account that you’d like to list the values of. This is referenced in the code above by the call to getenv(‘container’) which reads this value from an environment variable
  • DEPLOYMENT_SOURCE – Typically, I would add a .deployment file to the respository to change the project config setting to web as this will change the deployment directory and only deploy the items in the web folder. Due to how the Composer site extension is hooking the deployment, the .deployment file doesn’t work so this setting is needed to let Kudu know that the contents of web should be copied to the wwwroot directory

Add the following Connection String to the Connection Strings list in the Portal:

  • BlobConnectionString – This should contain the connection string for your azure storage account. Set the type to Custom.

There is an assumption here that you actually have a few items in the storage account. If you don’t upload a few now then refresh the website.

That’s it! You have successfully deployed a PHP application which uses composer!

New Windows Azure SDK for PHP Feature: RunPHP (on Windows)

If you are developing PHP on Windows for use on Windows Azure, there is a fancy new feature which may catch your attention. First things first, let’s run through the basics of installing the Windows Azure SDK for PHP in order to set up your environment to get ready for PHP development for Windows Azure.

This new feature is part of the Windows Azure PowerShell and Windows Azure Emulators components which is downloadable through the Web Platform Installer.

Install Windows Azure PowerShell and Windows Azure Emulators for PHP

  1. Open Web Platform Installer via the Windows Azure PowerShell and Windows Azure Emulators deep link.
  2. Click Run.

    image

  3. Accept UAC prompt.

    image

  4. Click Install.

    clip_image001

  5. Click I Accept.

    clip_image001[6]

  6. Go to the kitchen and grab a cup of coffee.

    clip_image001[9]

  7. Click Finish.

    image

How To: Use RunPHP to test a PHP Application on Windows

In order to understand how to use runphp, let’s quickly build a sample PHP application to show off the functionality of runphp.

Now that we have a simple application set up, let’s open a command prompt to use runphp. I will use Windows PowerShell to execute commands, in order to use runphp, PowerShell will need to be run as Administrator.

To run PowerShell as Administrator, right click on the PowerShell icon and select Run as Administrator.

Navigate to the path which contains your application, then execute the command runphp.

image

There are a number of things going on when executing RunPHP, let’s enumerate the high level steps:

  1. Copies an apphost.config file to the current directory
  2. Runs appcmd.exe from IIS Express
    1. Creates a new Website based on the current directory
    2. Configures a HTTP Handler to map *.php files to php-cgi.exe interpreter
  3. Starts IIS Express and binds the website to an open port.

To view and test your website, open a browser visit the localhost address with the appropriate port which the website was bound to during the runphp process.

http://localhost:8080

Once you finish testing, you can shut down IIS Express by opening the PowerShell window and pressing the ‘Q’ key.

Now that you’ve finishing testing your application on your local machine, you can deploy to Windows Azure Web Sites.

Windows Azure SDK for PHP – ‘PartitionKey’ property value must satisfy is_string.

When building out an application there are many factors you need to consider, these considerations boil down to functional and non-functional requirements that you as a developer or architect are set out to achieve. In many circumstances, if not all, we are accepting data as an input from a user or other medium, transforming or normalizing that data into something that will help fulfill other requirements of an application.

In order to fulfill scalability goals it may be necessary to find alternative means to traditional storage, something that was designed with scalability in mind. One such service is Windows Azure Table Storage which is defined as:

[Windows Azure Storage] Tables offer NoSQL capabilities for applications that require storage of large amounts of unstructured data. Tables are an ISO 27001 certified managed service which can auto scale to meet massive volume of up to 100 terabytes and throughput and accessible from virtually anywhere via REST and managed API’s.

The topic of Windows Azure Storage Abstractions and their scalability targets is some what out of scope of this post, however, keep in mind that it is important to understand the Windows Azure Storage Architecture and more specifically How to get the most out of Windows Azure [Storage] Tables.

Integer values for PartitionKey or RowKey with PHP

If you’ve done your research on designing for scale with Windows Azure Storage and you find that Integer values are what you need for your specific data model, keep in mind that PartitionKey and RowKey values are of type string.

While this doesn’t seem like a foreign concept you may find yourself in a situation where you have an error while attempting to use integers as strings while interacting with the Windows Azure SDK for PHP. The error you will receive is “PartitionKey [or RowKey] property value must satisfy is_string”. In my particular scenario I was loading my tables by iterating through an array of key/value pairs.

My array looked like this:

In which you may expect the key to be treated as a string, which isn’t the case. To understand the reasoning behind this, we’ll go right to the source.

The key can either be an integer or a string. The value can be of any type.

Additionally the following key casts will occur:

  • Strings containing valid integers will be cast to the integer type. E.g. the key "8" will actually be stored under 8. On the other hand "08" will not be cast, as it isn’t a valid decimal integer.
  • Floats are also cast to integers, which means that the fractional part will be truncated. E.g. the key 8.7 will actually be stored under 8.
  • Bools are cast to integers, too, i.e. the key true will actually be stored under 1 and the key false under 0.
  • Null will be cast to the empty string, i.e. the key null will actually be stored under "".
  • Arrays and objects can not be used as keys. Doing so will result in a warning: Illegal offset type.

According to the documentation, you’ll notice that “strings containing valid integers will be cast to integer type”, in order to ensure that the now converted integer is provided to the service proxy as a string, we need to call strval() on the key when providing it as a PartitionKey or RowKey. To provide an example of this consider the following:

Where addEntity() constructs an entity and inserts it into Windows Azure Table Storage.

Conclusion

In this post I clarified a potential issue that may arise when iterating over an array with key/value pairs to push entities into Windows Azure Table Storage.

Stay Cloudy My Friends…

Getting Started with PHP on Windows Azure Web Sites

Windows Azure | Flexible. Open. Rock Solid.

Windows Azure Web Sites (WAWS) is a highly scalable cloud environment build for speed. Windows Azure Web Sites brings down the barriers of Cloud Deployment allowing you do deploy what you want (Support for ASP.NET, PHP & Node.js),  how you want (FTP, Git, TFS, WebDeploy).

In this post I would like to highlight some simple optimizations for  running a PHP Web Site within the Windows Azure Web Sites environment.

Strap on your Tool Belt…

There’s nothing a developer likes more than some a few tools to make the job a little easier. Windows Azure has simplified the process of getting the right tools for the job, to take this one step further, we provide installers for our tools for use on Linux, Mac and/or Windows.

Develop using Windows Azure Services

Visit the PHP Developer Center to install the PHP SDK for Windows Azure.

Manage your Windows Azure Services

You can manage your Windows Azure services all from the comfort of your favorite Command-Line. Visit the Manage downloads page to Get the tools you need. Fast.

In addition to providing Command-Line tools, Windows Azure services can also be managed directly from the Windows Azure Management Portal. The new Windows Azure Management Portal has been completely redesigned in HTML5 which enables it to be used in a variety of devices including Windows Phone and iPad. For Guides on how to navigate the Management Portal specifically related to WAWS, visit the Web Sites page of the Manage Services section on WindowsAzure.com.

Now for Something You’ll Really Enjoy…

In a world that demands instant gratification, performance is paramount, your Web Site needs to be able to deliver in a time of need. Even thought Windows Azure Web Sites has no issues being performing it’s still crucial that we think about optimizing for the best possible result. Luckily the team which built Windows Azure Web Sites has already done an amazing job delivering an environment which follows the Best Practices for running PHP on IIS.

Learning more about the Windows Azure Web Sites Environment

To better understand what is enabled by default in the PHP runtime on Windows Azure Web Sites, create a file called info.php which contains the following:

All of the Server Configuration Information you will need to understand what is capable in Windows Azure Web Sites in the context of PHP.

Installed PHP Modules

php_mysql.dll MySQL Driver for PHP
php_mysqli.dll Improved MySQL Driver for PHP
php_mbstring.dll Multibyte String [Encoding]
php_gd2.dll Image Processing and Creation Library
php_gettext.dll Native Language Support (Globalization & Localization)
php_curl.dll Protocol Support
php_exif.dll Image Metadata
php_xmlrpc.dll Remote Procedure Call
php_openssl.dll SSL Support
php_soap.dll SOAP Protocol
php_pdo_mysql.dll PHP Data Objects for MySQL
php_pdo_sqlite.dll PHP Data Objects for SQLite
php_imap.dll Mail Server Support [IMAP, POP3, NNTP]
php_tidy.dll HTML Document Manipulation
php_wincache.dll Windows Cache [Caches: Opcode, Files, File Paths, User Caching and Session Handling]
php_sqlsrv.dll MS SQL Server Driver for PHP (includes Windows Azure SQL Database Support)
php_pdo_sqlsrv.dll PHP Data Objects for MS SQL Server

Some of those settings don’t suit my needs, what do I do now?

In the event that some of the settings in the php.ini don’t suit your needs DON’T PANIC.

Windows Azure Web Sites allows .user.ini files, which allow you to set certain php.ini configuration values.

One caveat to the .user.ini file is that it will not allow you to install additional modules.

If your application requires additional modules than the ones listed above, you would probably want to look at Windows Azure’s Virtual Machine or Cloud Service offerings.

Debugging PHP in Windows Azure Web Sites

Every developer will inevitably at some point need to debug some code, it’s just a fact of life. If you look at the output from phpinfo() you’ll notice that errors are logged, but not displayed in the browser, which would significantly slow down developer productivity. Not to worry, here is a .user.ini file which will help you with debugging your PHP applications.

Note: Remove the [debug] from the file name.

Important Setting for Accepting Content in Windows Azure Web Sites

When moving my blog to WordPress on Windows Azure Web Sites, I needed to import my BlogML export from BlogEngine.Net unfortunately for me the file size was greater than the default 2MB. Luckily, Brian Swan wrote a post on Configuring PHP in Windows Azure Web Sites with .user.ini files which outlines how to increase the upload_max_filesize to 10MB (I’ve decided that 12MB  is my preferred upload_max_filesize).

Optimize web.config Settings for PHP

If you take a look at this post by Maarten Balliauw on Tweaking Windows Azure Web Sites you will see the two files which provide IIS the base configuration applicationhost.config and webroot.config. Maarten was investigating how to turn on additional HTTP Verbs in Windows Azure Web Sites for a Custom WebDav server. Seeing how more and more applications are using REST, it seems fitting that we enable the majority of HTTP Verbs by default so our application can leverage them.

In addition to adding HTTP Verbs, limiting the list of Default Documents that IIS must rotate through will help optimize page load times. With these two optimizations I have started a web.config starting point for PHP applications on Windows Azure Web Sites.

Note: This post reflects the original state of this file, which is hosted on GitHub and  may change overtime.

Migrating from Apache to Windows Azure Web Sites

If you are currently running an application Apache Web Server and would like to migrate your application Windows Azure Web Sites it’s completely possible, it’s even possible to translate your .htaccess file content to IIS web.config, or if you have a Windows machine, you can use the IIS Rewrite tool to Import mod_rewrite rules into IIS (then copied from the xml view into your web.config file).