How-tos

From Workshop to Production – Migrating PHP app to Bluemix

Share this post:

A new Bluemix user, Mukul recently attended a workshop in Dublin. He was so inspired that he immediately set out to migrate a PHP application to Bluemix, a process that he documented in his own blog. Appreciating his enthusiasm and the work he put into documenting his experience, I agreed to repost his entry in the Bluemix blog. —Marvin

Mukul’s Experience

Yesterday I attended a workshop at IBM in Dublin on how to use Bluemix to create and launch web and mobile applications. I took the opportunity to migrate one of my web applications from one on shared hosting to Bluemix. Whether my method was a prescribed one or not, it definitely seemed like an obvious one.

The application I was porting was a PHP application currently running on a LAMP stack. The application runtime depended on Yii, jQuery and D3.js frameworks and MySQL DB. For deploying the application, I was just required to place the source code and script files in the PHP web folder and create the data-model in the DB. I understand JSP applications are much easier to deploy because one is dealing with only a couple of .WAR files.

This was my plan:

  • Create a Bluemix PHP app
  • Install Cloud Foundry CLI (Command Line Interface)
  • Start a MySQL database service and link it to the PHP engine
  • Modify app configuration with the Instantiating Credentials
  • Create app specific data model in the database
  • Load the application source code to its web folder
  • Test run the app

Setting the stage

I could access my Bluemix account by using the link bluemix.net and by selecting the Log-in link. I had earlier signed up so I was ready with my log in credentials. An IBM id can be obtained for free by following the “Sign up” link on the same page. Bluemix services that come with a new IBM id, have certain threshold levels up to which they are free. As I logged on, I landed on the dashboard or the console page.

The left side column menu shows the applications and services currently running on my account. I had one CF (Cloud Foundry) app running along with MySQL service. Take no notice of those, because I am going to show you how to create them. I did not need a container or virtual machine for the services I needed. I just wanted a PHP engine and a database, which come ready-made. If you need something out-of-the-world then you might have to kick-off a virtual machine and take care of installing components one by one.

Create a Bluemix PHP app

In order to create an app, I picked the option CREATE AN APP above. In the next screen below, I selected the type of app. You will notice that this bit works like a typical “Setup-Wizard”:

This time I picked WEB.

As you can see now, I had several choices in terms of programming language and framework. I picked PHP. A few months back, there were only a few options. I definitely remember that PHP was not there. Good that IBM is including more popular choices.

I guess I could have selected the “I Have Code Already” option and might had to figure out a way to associate the language-framework with the code. I would take that up some other time. For now, I just pressed CONTINUE.

How about a nice name for the app? I picked “Tallyho” because that is what I call my app (Check out tallyho.in). Hang on, I already had an app called “Tallyho”, Bluemix would not allow another one with the same name. So I added an extra “o” to it – “Tallyhoo”.

As I continued, I found my application running. Bluemix had started the PHP engine with a piece of starter code, which could be accessed by following the little link on the top. This was where I needed to make a decision – whether to load the source code from my computer file-system or link this app with my GitHub account. In order to keep things simpler, I decided to go with loading the source code from my computer (covered in the next section).

Install Cloud Foundry CLI (Command Line Interface)

Bluemix offers services to load and manage application source code and related DevOps services. Currently Bluemix DevOps offerings come bundled at hub.jazz.net which allows workflow process for automated testing and deployment linked with its own source code management, project planning and tracking features. I decided to skip those and take a shortcut – Cloud Foundry CLI.

Well, I was not being entirely truthful on why I chose to upload source code from my computer. I started with the GIT option but I messed it up in no time. I intended to link the new app with my GitHub or BitBucket repository. I accidentally ended up with a new repository created and linked under Bluemix DevOps. I had a new problem of how to move code from my existing GitHub to this freshly created Bluemix repository. This was exactly when I decided to give up on GIT option for now, and fell back on the CF CLI option, which allowed me to upload the source code using simple CF (Cloud Foundry) commands. Selecting this option made me download and install the CLI on your computer. The installation was straight-forward and I will not spend any time on bring that up here. Once installed, I could run CF commands from within a Windows Command Prompt.

Lets switch back to the dashboard view to check out the new PHP app.

And there my app was running. Tallyhooooo…

With a little fiddling around I found that the little cog on the right-top of each of the app widget, there were options to manage the app. Clicking the centre of the widget opens up the detail view.

Left menu changes to help you with more. The centre panel has the PHP engine stats. Right viewlet has the health stats and the activity log. Little above is a way to add GIT for this app. A word of caution, Bluemix assumes that you might want to store the code that you are going develop in a GIT repository and it will create one in IBM’s GIT service, IBM DevOps Services. If you already have your code stored in GitHub or BitBucket then you’ll have to take extra steps to migrate it. I will figure out how to link your current repositories to your apps and post another blog.

Here is your opportunity to see what the starter app really looks like. Select the little blue link on top which says – Routes: tallyhoo.mybluemix.net. And viola!! I could see the app running… (not a very good one though).

Before I replaced the starter app with my own, it was necessary to get the database service ready.

Start a MySQL database service and link it to the PHP engine

Back to Bluemix app details view, selected the option “ADD A SERVICE OR API”. MySQL, along with several other data management or analytical services come bundled with Bluemix. The service selection view opened up with a bunch of, very tempting, Watson services.

As you can see from the categories listed on the left, Watson was just one of them. You’ll want to explore all of them at your leisure, but for now, let me jump to “Data Management”. There you go.

There were NoSQL DBs – Cloudant, Mongo, Redis; relational DB – MySQL, ClearDB, SQL Database. I picked ClearDB MySQL. Why not “mysql”? No reason. It might just do the same thing but I guess, I did not like the logo. And of course, it also said that it was “Experimental”. I was not particularly feeling adventurous.

I checked the price plan then hit CREATE. Moments later, a “Restage Application?” confirmation dialog was displayed. What’s this? I did not get this earlier! I wasn’t sure of that but I proceeded anyway. Just like the PHP app, MySQL service appeared on my console page with an ability to control the service with the little cog on the right-top corner of the widget.

In order to prepare the DB with the app related model and initial data, We would need to get its “Instantiating Credentials” first. This could be obtained by following the “Show Credential” link on the MySQL service widget.

“Instantiating Credentials” contained the “hostname”, “username”, “password” and “name”(database name). The credentials for my database service is shown here:

{
"cleardb": [{
"name": "ClearDB MySQL Database-8n",
"label": "cleardb",
"plan": "spark",
"credentials": {
"jdbcUrl": "jdbc:mysql://b3bcaaa59b1c18:49d9dc8f@us-cdbr-iron-east-02.cleardb.net:3306/ad_5d22676f798e087",
"uri": "mysql://b3bcaaa59b1c18:49d9dc8f@us-cdbr-iron-east-02.cleardb.net:3306/ad_5d22676f798e087?reconnect=true",
"name": "ad_5d22676f798e087",
"hostname": "us-cdbr-iron-east-02.cleardb.net",
"port": "3306",
"username": "b3bcaaa59b1c18",
"password": "49d9dc8f"
}
}]
}

The above information was required by my PHP code to connect to the database in the runtime. I also had to use it to establish a command line interface with the database server to create my application data-model (covered in the next 2 sections).

Modify app configuration with the Instantiating Credentials

Now that I had the necessary information for me to update my PHP configuration, I made the changes as shown here:

'db'=>array(
'connectionString' => 'us-cdbr-iron-east-02.cleardb.net;dbname=ad_5d22676f798e087',
'emulatePrepare' => true,
'username' => 'b3bcaaa59b1c18',
'password' => '49d9dc8f',
'charset' => 'utf8',
'tablePrefix' => '',
),

It is not necessary for you to know the source code location where this change is made. In Yii 1.1 framework, I had to update config/main.php. Other PHP frameworks would have similar provisions.

Create app specific data-model in the DB

I used the same database information used in the previous section to make a connection to the DB. I used a command prompt session with the following set of commands-

c:\wamp\www\bm_tallyho>c:\wamp\bin\mysql\mysql5.6.12\bin\mysql.exe -h us-cdbr-iron-east-02.cleardb.net -u b3bcaaa59b1c18 -p
Enter password: ********

Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 5388469
Server version: 5.5.42-log MySQL Community Server (GPL)

Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help.
Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| ad_5d22676f798e087 |
+--------------------+
2 rows in set (0.13 sec)

mysql> use ad_5d22676f798e087
Database changed
mysql> show tables;
Empty set (0.12 sec)

mysql>


I found my database and set the context of it. Now I was ready to create the data-model. On the MySQL command interface, it was enough for me to use the “source” command with the data-model file name. Unfortunately it did not go well. Command failed and MySQL is not very good in pointing out the reason. I had to fall back on a more laborious method of copying and pasting the SQL commands. Luckily I had only about 15 tables and around as many indexes (indices) and constraints. It was possible to use one of the fancy tools like MySQL (Oracle) MySQLWorkbench but I just wanted to be done with it. This is where I wished Bluemix had provided some quick way to load .SQL source file. Well, at least now I had my DB ready.

Load the application source code to its web folder

Now I was ready to move my source code, which I was tried and tested on my local WAMP (Windows version of LAMP). I would take a moment to show you the destination on Bluemix where the code should go.

Select “Back to Dashboard” and select Tallyhoo app. And select “Files and Logs” from the left column menu.


At this moment, you can see only the starter code provided by Bluemix. Once I had successfully moved by application, I should be able to see my code over here.

In the CF CLI, I changed directory to the web application root. Typically in a WAMP scenario the application root is at \www\ (/var/www/ on Ubuntu). I established a session with Bluemix using CF commands shown here –

Microsoft Windows [Version 6.3.9600]
(c) 2013 Microsoft Corporation. All rights reserved.

C:\Users\mukulbiswas>cd \wamp\www\apps
C:\wamp\www\apps>
C:\wamp\www\apps>cf api https://api.ng.bluemix.net
C:\wamp\www\apps>cf login -u mukul.biswas.ie@ieee.org -o mukul.biswas.ie@ieee.org -s dev


This was where I was required to type the password, on prompt. Note that my username as well as my Bluemix organization went by the same identifier, which was my email ID. Hence the user and the organization directives, -u and -o respectively, carried the same identifier. The directive -s stood for “space”. As of now I had only one default space called dev. In a more formal computation landscape, one would have separate spaces for the development, the testing and the production. The following CF command started the transfer of the source files along with the folder structure: C:\wamp\www\apps>cf push Tallyhoo

I faced a peculiar situation here. At the web-root folder level, I had 3 folders required for my application to run – tallyho, Yii/PHP application framework and D3.js graphics micro-framework. It was important that at the destination folder, they appear as siblings. I had not figured out how to do that. To keep the affairs simple, I bundled them together before pushing them as one. This helped me push the source code and the framework folders in a single CF command. Something I learnt just about then that everytime I performed a new cf push, the earlier content would simply be replaced by the new one. As if incremental updates were totally out of question. IBM (or Cloud Foundry aficionados) may raise objections on my previous statement but hey, if this was possible then no one made it easy for me to figure out. All I wished was a simple FTP feature to make incremental uploads.

A lot happened between the push command and the source code finding their destination.

c:\wamp\www\bm_tallyho>cf push Tallyhoo
Using manifest file c:\wamp\www\bm_tallyho\manifest.yml

Updating app Tallyhoo in org mukul.biswas.ie@ieee.org / space dev as mukul.biswas.ie@ieee.org...
OK

Using route tallyho.mybluemix.net
Binding tallyho.mybluemix.net to Tallyhoo...
OK

Uploading Tallyhoo...
Uploading app files from: c:\wamp\www\bm_tallyho
Uploading 19.7M, 2909 files
Done uploading
OK

...snip...

Showing health and status for app Tallyhoo in org mukul.biswas.ie@ieee.org / space dev as mukul.biswas.ie@ieee.org...
OK

requested state: started
instances: 1/1
usage: 128M x 1 instances
urls: tallyho.mybluemix.net, tallyhoo.mybluemix.net
last uploaded: Fri Mar 13 08:48:20 GMT 2015

state since cpu memory disk details
#0 running 2015-03-13 08:52:38 AM 0.0% 68.4M of 128M 245.6M of 1G


I should add that I always use Administrator: Command Prompt on Windows, which you can get from the context menu on the window start menu (left bottom of your screen). On Ubuntu, you might have to use sudo prefix.

You can see from the above screen dump that it took a number of attempts before the app started running. It was time to verify if my source code landed safely. I went back to the app details page and refreshed it to see the uploaded files.


And hey, I could see my code.

Test run the app

In order to test run the app, I had to use the link shown on the console page (http://tallyhoo.bluemix.net).

Interestingly, some few of the CSS styles were not working, which I’ll go back and debug later. This view of my app pulled data from the database, which seemed to be working alright.

I opened another view of my app to check if D3.js graphic was working fine.
Well, it was!

Conclusion

This brings me to the very end. For a first-time user, the whole exercise went fairly smoothly. Signing in and general navigation was fairly intuitive. Creation of the PHP app was very simple. So was the creation of the database service. Finding DB instantiating credentials and applying them to my PHP code was mostly easy because of my familiarity to MySQL and PHP/Yii. Though I was able to use Cloud Foundry commands to upload source code but I am still not sure I can use in a not-so-straight-forward-scenario (I hate it when I am force to learn something new). Finally I was able to migrate the entire app and test run it within 5-6 hours time.

The app is still running on the URL shown in the picture. Check it out yourself. I would definitely ask you guys to try this at home.

Marvin: Thanks Mukul! We can’t wait to see what you build next, and we’ll keep working to iron out some of the wrinkles you encountered!

More stories
May 1, 2019

Two Tutorials: Plan, Create, and Update Deployment Environments with Terraform

Multiple environments are pretty common in a project when building a solution. They support the different phases of the development cycle and the slight differences between the environments, like capacity, networking, credentials, and log verbosity. These two tutorials will show you how to manage the environments with Terraform.

Continue reading

April 29, 2019

Transforming Customer Experiences with AI Services (Part 1)

This is an experience from a recent customer engagement on transcribing customer conversations using IBM Watson AI services.

Continue reading

April 26, 2019

Analyze Logs and Monitor the Health of a Kubernetes Application with LogDNA and Sysdig

This post is an excerpt from a tutorial that shows how the IBM Log Analysis with LogDNA service can be used to configure and access logs of a Kubernetes application that is deployed on IBM Cloud.

Continue reading