Getting Started with Laravel on BlueMix

Share this post:

**Updated 4/10/15 for Laravel 5 **
Few web developers like to spend a lot of time configuring systems and servers, and any PHP developer knows how much of a pain this can be. Luckily, there are services out there that take all this grunt work out of creating web applications, such as IBM Bluemix. In this tutorial, we’ll create a basic Laravel app, deploy it on Bluemix, and bind it to a database. By the end of our tutorial, our web app will provide a very basic way to write or delete public notes. You can view a running demo here.


You should have Composer and PHP 5.5 (although PHP 5.4 should be fine) installed globally on your local machine. You should also have basic command line knowledge. It will help to have at least a minimal understanding of PHP and the Laravel framework, but even if you don’t, you’ll still be able to follow this tutorial.

Creating, Configuring, and Deploying a Laravel App to Bluemix

Open up a command-line prompt and navigate to the directory that you want your project’s root directory to reside in. Run this command to have Composer grab most of the base files you’ll need:

composer create-project laravel/laravel laravel-demo --prefer-dist

Creating a manifest

Move to the newly created root directory of your Laravel project and create a new file called manifest.yml. This stores the config options that the Bluemix command line program uses when we upload our file to Bluemix. Your file should look similar to this:

- name: your-app-name-here
  memory: 128M

A quick explanation of our settings:

  • name: this sets our app name on Bluemix. You should choose a unique name that hasn’t been used by anyone else.
  • memory: our demo app will be quite simple, so we’ll only request 128MB of memory.
  • buildpack: this one is important! Since Bluemix doesn’t have an automatic system to handle PHP or Laravel apps, we have to specify what should happen when we upload one of these kinds of projects. Luckily, there’s already a good buildpack built, so we don’t have to make our own.
  • env: We want to make sure our app has plenty of time to deploy and start, so we’ll set two environment variables to (arbitrarily) give it a max of 15 minutes. This should be way more than enough for our simple app. If you have a complex application with many Composer dependencies, deploying will probably take a little, so we’ll just make sure we don’t have to worry about timeouts. We could also set other environment variables here if needed.

You can see more detailed documentation on the manifest.yml as well.

Setting up your project file structure

Change directories into the laravel-demo (application root) folder. Create a htdocs folder.
Move all generated project files into this newly created htdocs folder with the exception of these four files:

  • .gitignore
  • composer.json
  • composer.lock
  • manifest.yml

Your file structure should now look similar to this:

Choosing which Files get Sent to Bluemix

Create a new file in your project root called .cfignore.
Edit .cfignore by entering in the following:


when we push to Bluemix, .cfignore is used to determine what files and folders should NOT be uploaded. For example, we ignore any composer-installed libraries in htdocs/vendor/ because they’ll be installed automatically in Bluemix by the php buildpack when we deploy.

Next, we must update the composer.json file to reflect the new htdocs file paths. Take note of the htdocs modifications shown below. Your updated composer.json should look similar to this:

cf appscomposer_json_mods

Finally, we must provide some customized entries for the cloud foundry php buildpack to understand things like where our vendor folder is being generated, what the document root url folder should be and what PHP extensions are useful for Laravel – to name a few.

Create a new folder in the root of our application named .bp-config. Change directories into this folder and create a new filed named options.json. Within this file, include the following json snippet:

{<br />     "PHP_VERSION": "{PHP_55_LATEST}",<br />     "COMPOSER_VENDOR_DIR": "htdocs/vendor",<br />     "WEBDIR": "htdocs/public",<br />     "PHP_EXTENSIONS": [ "bz2", "zlib", "openssl", "fpm", "tokenizer", "curl", "mcrypt", "mbstring", "pdo"]<br />}

In summary, we’ve …

  • Added two new files to the root folder of our application: manifest.yml and .cfignore.
  • Added one new folder to the root folder of our application: .bp-config and inserted within it a new file named options.json
  • Moved most of our project files into a directory named htdocs
  • Modified the composer.json to reflect the modified file structure

Deploying to Bluemix

We’re ready to deploy to Bluemix! If you haven’t deployed anything to Bluemix before, create a Bluemix account and follow the first three steps here to install the command line tool, connect to Bluemix, and log in. Finally, just run this command from your application root to push and deploy your app on Bluemix!

cf push

Once you see the message that your app has started (don’t worry if some of the actions take a little while to run during the first deploy) navigate to Your app is now running! You’ll see something like this:

Working with a Database

It’s been easy so far to get our site up and running – basically just a few configuration tweaks and changes are all we’ve done. However, without some sort of a datastore, we’ll have severely limited capabilities – including no way to permanently store notes like we want to. On a more classical sever setup, we could perhaps write data to a file on disk. However, this approach leads to scalability issues. Also, Bluemix VM instances, to make scaling as easy as possible, use an ephemeral filesystem which isn’t appropriate for storing permanent data. Instead let’s setup a MySQL database, which will work well with Bluemix and integrate nicely with Laravel. We’ll create a single table called notes to store our messages in. In a future tutorial we might look at setting up an alternative datastore, such as Redis.

Binding the MySQL Service

Navigate to, go to your dashboard, and select your new project. In the overview screen for the app, click ‘Add a Service’. We’ll use the ClearDB MySQL service. After a moment of processing, it should appear as a service in your app overview.


When we bind a service to our app, the service typically adds configuration values to a JSON-formatted environment variable named VCAP_SERVICES. If you click the ‘Quick Docs’ button on the ClearDB service on Bluemix, you can see the relevant part of the JSON value. We need to configure Laravel to read these values and use them to connect to the database. At the top of app/config/database.php let’s add a few lines to grab the values pertaining to our database:

<!--?php <!--mep-nl---->
$services = json_decode(getenv('VCAP_SERVICES'), true);
$sqlCreds = $services['cleardb'][0]['credentials'];

return array(

Then we have to use them in the configuration settings below:

    'connections' => array(

        'sqlite' => array(
            'driver'   => 'sqlite',
            'database' => __DIR__.'/../database/production.sqlite',
            'prefix'   => '',

        'mysql' => array(
            'driver'    => 'mysql',
            'host'      => $sqlCreds['hostname'],
            'database'  => $sqlCreds['name'],
            'username'  => $sqlCreds['username'],
            'password'  => $sqlCreds['password'],
            'charset'   => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix'    => '',

        'pgsql' => array(
            'driver'   => 'pgsql',
            'host'     => 'localhost',

Creating the Notes Table

After configuring Laravel to connect to our database, we’ll generate a database migration to create a new database table. Run from the command line:

php htdocs/artisan migrate:make create_notes_table

Open up the newly created migration file and add a few lines of code to create a database table:

<!--?php <!--mep-nl---->
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateNotesTable extends Migration {

     * Run the migrations.
     * @return void
    public function up()
        Schema::create('notes', function($table)

     * Reverse the migrations.
     * @return void
    public function down()


Basic Note Functionality

This isn’t a Laravel tutorial, so we’ll quite quickly run through the steps to set up some basic operations on our data. Create a app/models/Note.php with the following contents:

<!--?php <!--mep-nl---->
class Note extends Eloquent {
    public $timestamps = false;


Generate a controller with the following command:

php htdocs/artisan controller:make NoteController --only=store,index,destroy

Then add some basic code to the new file found at app/controllers/NoteController to let us view, create, and delete notes:

<!--?php <!--mep-nl---->
class NoteController extends \BaseController {
     * Display a listing of the resource.
     * @return Response
    public function index()
        return View::make('notes.index')->with('notes', Note::all());

     * Store a newly created resource in storage.
     * @return Response
    public function store()
        $note = new Note;
        $note->content = Input::get('content');
        return Redirect::action('NoteController@index');

     * Remove the specified resource from storage.
     * @param  int  $id
     * @return Response
    public function destroy($id)
        return Redirect::action('NoteController@index');


Add routes for these actions in app/routes.php:

| Application Routes
| Here is where you can register all of the routes for an application.
| It's a breeze. Simply tell Laravel the URIs it should respond to
| and give it the Closure to execute when that URI is requested.

Route::get('/', function()
    return View::make('hello');

Route::resource('/notes', 'NoteController', ['only' => ['index', 'store', 'destroy']]);

And make a view for our page at app/views/notes/index.php:



# Note Delete
id ?> content ?>


<br />

Making Bluemix Run Database Migrations

We have one final challenge: getting Bluemix to migrate our database. Unfortunately, there’s no current way to access a shell prompt on Bluemix and run the database migration. We could connect directly to our database, but then we’d have to craft our SQL by hand and would lose all the advantages of having database migrations. Instead, let’s set it up so that on a push to Bluemix, any new migrations are run automatically. Luckily, with our buildpack and Composer, this is easy. In composer.json, there’s a configuration option with commands that Composer will run after it installs dependencies. Since Composer installs dependencies on every deploy, we can just tack on a command to migrate the database afterwards:

    "scripts": {
        "post-install-cmd": [
            "php htdocs/artisan clear-compiled",
            "php htdocs/artisan optimize",
            "php htdocs/artisan migrate --force"
        "post-update-cmd": [
            "php htdocs/artisan clear-compiled",
            "php htdocs/artisan optimize"
        "post-create-project-cmd": [
            "php htdocs/artisan key:generate"

Run cf push again, and your application will be pushed to Bluemix, the proper database tables generated, and your application deployed! Go to and you should see something like this:

<a href="/blogs/bluemix/wp-content/uploads/2014/06/LaravelFinishedNewScreenshot.png"><img src="/blogs/bluemix/wp-content/uploads/2014/06/LaravelFinishedNewScreenshot.png" alt="LaravelFinishedNewScreenshot" width="497" height="316" class="aligncenter size-full wp-image-2667" /></a>

And we’re finished! Overall, a pretty easy process to get a Laravel app up and running on Bluemix and connect to a database. It’s a little bit of a pain that we don’t have any direct command line access on Bluemix to run database migrations by hand, but as this article illustrates, we have an easy workaround. Just be careful not to push any destructive migrations by accident. Still, that small issue is easily outweighed by all the other tedious work we can skip by using Bluemix.

IBM jStart Team, IBM Emerging Technologies

More stories

Create Dynamic Rules for Access Groups

Users or admins can now dynamically create access rules on the IBM Cloud Platform based on identity information shared from their Enterprise Identity Provider.

Continue reading

Configuring IBM Cloud App ID From the Toolchain

Learn how to configure the IBM Cloud App ID from a toolchain as part of continuous delivery process. This post gives some background and the script we use.

Continue reading

Part III: Wimbledon Facebook Bot on IBM Cloud

Delivering at scale: In the final part of the series, we discuss integrations with on-site systems at the All England Club and how we used Multi-Region within IBM Cloud to ensure scale and availability.

Continue reading