Tuesday, February 4, 2014

Deploy a Hello World PHP Application to Zend Server on IBM Bluemix

The previous post demonstrated how to deploy a trivial Node.js application to IBM Bluemix. There I also introduced the basics of manifest.yml file used by Bluemix and Cloud Foundry as a deployment descriptor. This post goes deeper into features available for creating reusable manifest.yml files and covers Cloud Foundry buildpacks used during deployment. By the end of the post you will have deployed a trivial Hello World application written in PHP to a Zend Server's PHP container running on IBM Bluemix.

Variables in manifest.yml


The post about deploying a Node.js application to Bluemix warned about a potential problem with having a single manifest.yml in use by multiple developers. The problem occurs in a situation where the deployment subtarget (hostname) of an application has a fixed value in the manifest. If two developers try to deploy their application to the same hostname, Bluemix rejects second and subsequent deployment attempts because of the conflict as to which of the two applications should run on the hostname, e.g. hello-world.ng.bluemix.net

The post suggested manually changing a postfix in the manifest.yml file in case if Bluemix rejects deployment attempts due to the same hostname error.  Of course, this approach is not acceptable in most cases, especially if one tries to automate the deployment process. One way to address this problem is to use features of bash[6] and sed[7] to introduce randomly generated numbers characters into the manifest.yml file. For example, you can create a manifest.yml.template file where the host parameter is specified as follows:

Then, prior to performing a push using the Cloud Foundry cf tool, you can execute the following sed command to generate a manifest.yml file where the string $RANDOM is replaced with a randomly generated number.


Use of random numbers in the application hostname makes the possibility of name collisions unlikely but introduces another problem: finding out the URL of an application after the deployment process completes. The cf tool has a command to help called cf routes that returns up to date information about active hostname URLs and corresponding applications.



Zend Server Buildpack



During the deployment process described in the previous post, the package.json[1] file provided a hint for Bluemix to use the Node.js runtime. Without this hint the application would have failed to stage because Bluemix would not know which runtime to prepare for the application.

Buildpacks are used by Cloud Foundry to prepare the environment for running an application (e.g. setting environment variables, copying settings files into the right places), compile binaries (if any) and launch the application in the runtime. A detailed explaination of buildpacks is outside the scope of this post and more detail is available from Cloud Foundry[2] and Heroku documentation[3]. It is important to note that some buildpacks, such as the one for Node.js, are built into Bluemix which means that the buildpack does not have to be specified explicitly to the cf push command.

Given enough time and effort one can create a custom buildpack for a runtime that is not built into Bluemix. Once the buildpack is available on the web via git, Bluemix can use git clone of the buildpack repository to copy the buildpack to the execution environment during the deployment process and launch an application in the custom runtime. The next section describes how to use a custom buildpack for a Zend Server, a PHP runtime to run a simple Hello World application on Bluemix


PHP Hello World Application



As with the post covering Node.js deployment, you may either use git to clone a repo for this application[4] or if you prefer, create a new directory and save the index.php and manifest.yml files shown below to the directory.

The Hello World application in index.php is very simple. The <?php prefix on line 1 instructs the PHP interpreter to process the code between the prefix and the closing ?>  bracket on line 3. The actual code on line 2 just prints "Hello World" to any HTTP request sent to the PHP container running the application.

The parameters in the manifest.yml are covered earlier in this post and in the previous post while a more detailed explanation is available from the Cloud Foundry documentation[5].

The following is a snippet of the application deployment session to Bluemix, starting with 
cf push hello-world-php command.



Note that due to variability of download speeds it may take a while to deploy the application. If you are seeing problems with timeout when deploying the application, try setting the CF_STARTUP_TIMEOUT and CF_STAGING_TIMEOUT to be at least 15 minutes.

References



[1] https://github.com/cosipov/minimal-hello-world-node-js/blob/master/package.json
[2] http://docs.cloudfoundry.com/docs/using/deploying-apps/buildpacks.html
[3] https://devcenter.heroku.com/articles/buildpacks
[4] https://github.com/cosipov/minimal-hello-world-php
[5] http://docs.cloudfoundry.com/docs/using/deploying-apps/manifest.html#attributes
[6] http://en.wikipedia.org/wiki/Bash_(Unix_shell)
[7] http://en.wikipedia.org/wiki/Sed