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

Add Comment

Leave a Reply

Your email address will not be published.Required fields are marked *

[…] just published a post about running Laravel on Bluemix, a PaaS from IBM. Check it out if […]



    I get the same issue as Mario:
    —–> Downloaded app package (484K)
    —–> Downloaded app buildpack cache (2.8M)
    Cloning into ‘/tmp/buildpacks/cf-buildpack-php’…
    Submodule ‘buildpack-packager’ (
    ackager.git) registered for path ‘buildpack-packager’
    Submodule ‘compile-extensions’ (
    ons.git) registered for path ‘compile-extensions’
    Cloning into ‘buildpack-packager’…
    Submodule path ‘buildpack-packager’: checked out ‘ca8c100eed590507625f076f858b33
    Cloning into ‘compile-extensions’…
    Submodule path ‘compile-extensions’: checked out ‘fc1e2c686aeff79ad1131136b2016a
    ——-> Buildpack version 1.0.2
    —–> Setting up runtime environment…
    – PHP 5.5.12
    – Apache 2.4.9
    – Nginx 1.4.6

    Server error, status code: 400, error code: 170004, message: App staging failed
    in the buildpack compile phase

    TIP: use ‘cf logs bsaytest2 –recent’ for more information



    I haven’t tried the database part yet but standard deployment worked. Thanks!



Unable to run php artisan migrate
I am getting below error –

SQLSTATE[HY000] [2002] No connection could be made because the target machine actively refused it.

migrate [–bench[=”…”]] [–database[=”…”]] [–force] [–path[=”…”]] [–pac
kage[=”…”]] [–pretend] [–seed]

I have made changes to database.php
‘driver’ => ‘mysql’,
‘host’ => $sqlCreds[‘hostname’],
‘database’ => $sqlCreds[‘name’],
‘username’ => $sqlCreds[‘username’],
‘password’ => $sqlCreds[‘password’],
‘charset’ => ‘utf8’,
‘collation’ => ‘utf8_unicode_ci’,
‘prefix’ => ”,



I get this error
—–> Installing PHP extensions:
Loading composer repositories with package information
– Installation request for laravel/framework v5.0.16 -> satisfiable by laravel/framework[v5.0.16].
– laravel/framework v5.0.16 requires ext-mbstring * -> the requested PHP extension mbstring is missing from your system.

Server error, status code: 400, error code: 170004, message: App staging failed in the buildpack compile phase



Note to OSX Users if you receive the following error after running `composer create-project laravel/laravel laravel-demo –prefer-dist`:

laravel/framework v5.0.2 requires ext-mcrypt * -> the requested PHP extension mcrypt is missing from your system.

this is due to the terminal pointing to the native PHP shipped with OSX. You should instead update your bash profile to include the actual path to your PHP. I installed MAMP and added this to my .bash_profile:

export PATH=/Applications/MAMP/bin/php/php5.5.18/bin:$PATH

You can use “which php” to determine which php your path is referencing.



Updated steps (4/10/15)

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

CREATE manifest.yml

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



NO PROCFILE! (because new buildpack)
NO COMPOSER.PHAR! (because new buildpack)

leave .gitignore alone
CREATE .cfignore

(change paths to account for htdocs)
REPLACE composer.json with

“name”: “laravel/laravel”,
“description”: “The Laravel Framework.”,
“keywords”: [“framework”, “laravel”],
“license”: “MIT”,
“type”: “project”,
“require”: {
“laravel/framework”: “5.0.*”
“require-dev”: {
“phpunit/phpunit”: “~4.0”,
“phpspec/phpspec”: “~2.1”
“autoload”: {
“classmap”: [
“psr-4”: {
“App\”: “htdocs/app/”
“autoload-dev”: {
“classmap”: [
“scripts”: {
“post-install-cmd”: [
“php htdocs/artisan clear-compiled”,
“php htdocs/artisan optimize”
“post-update-cmd”: [
“php htdocs/artisan clear-compiled”,
“php htdocs/artisan optimize”
“post-create-project-cmd”: [
“php -r “copy(‘.env.example’, ‘.env’);””,
“php htdocs/artisan key:generate”
“config”: {
“preferred-install”: “dist”

(configure build pack)
CREATE .bp-config/options.json

“COMPOSER_VENDOR_DIR”: “htdocs/vendor”,
“WEBDIR”: “htdocs/public”,
“PHP_EXTENSIONS”: [ “bz2”, “zlib”, “openssl”, “fpm”, “tokenizer”, “curl”, “mcrypt”, “mbstring”, “pdo”]

Change Directory to project root (where manifest.yml resides) run “cf push”



When I try deploying it with Laravel 4.2, I receive error in the process as stated below (gained from logs)
OUT PHP Warning: require(/tmp/staged/app/htdocs/bootstrap../vendor/autoload.php): failed to open stream: No such file or directory in /tmp/staged/app/htdocs/bootstrap/autoload.php on line 17
OUT PHP Fatal error: require(): Failed opening required ‘/tmp/staged/app/htdocs/bootstrap../vendor/autoload.php’ (include_path=’../lib/php:/tmp/staged/app/lib’) in /tmp/staged/app/htdocs/bootstrap/autoload.php on line



Hi, I’ve been having trouble to deploy my laravel app to bluemix using laravle 4.2 and 5.0.
This is the error in the blumix logs:
2015-05-01T16:52:49.71+0100 [STG/0] ERR [UnexpectedValueException]
2015-05-01T16:52:49.71+0100 [STG/0] ERR Could not parse version constraint ^1.2.2: Invalid version string “^1.2.2”
2015-05-01T16:52:49.71+0100 [STG/0] ERR install [–prefer-source] [–prefer-dist] [–dry-run] [–dev] [–no-dev] [–no-plugins] [–no-custom-installers] [–no-scripts] [–no-progress] [-v|vv|vvv|–verbose] [-o|–optimize-autoloader] [–ignore-platform-reqs] [packages1] … [packagesN]
2015-05-01T16:52:49.73+0100 [STG/0] OUT —–> Composer command failed
2015-05-01T16:52:49.73+0100 [STG/0] ERR Traceback (most recent call last):
2015-05-01T16:52:49.73+0100 [STG/0] ERR File “/tmp/buildpacks/php-buildpack/scripts/”, line 51, in
2015-05-01T16:52:49.73+0100 [STG/0] ERR .from_build_pack(‘lib/additional_commands’)
2015-05-01T16:52:49.73+0100 [STG/0] ERR File “/tmp/buildpacks/php-buildpack/lib/build_pack_utils/”, line 189, in extensions
2015-05-01T16:52:49.73+0100 [STG/0] ERR process_extension(path, ctx, ‘compile’, process, args=[self])
2015-05-01T16:52:49.73+0100 [STG/0] ERR File “/tmp/buildpacks/php-buildpack/lib/build_pack_utils/”, line 69, in process_extension
2015-05-01T16:52:49.73+0100 [STG/0] ERR success(getattr(extn, to_call)(*args))
2015-05-01T16:52:49.73+0100 [STG/0] ERR File “/tmp/buildpacks/php-buildpack/extensions/composer/”, line 359, in compile
2015-05-01T16:52:49.73+0100 [STG/0] ERR return composer.compile(install)
2015-05-01T16:52:49.73+0100 [STG/0] ERR File “/tmp/buildpacks/php-buildpack/lib/”, line 154, in compile
2015-05-01T16:52:49.73+0100 [STG/0] ERR self._compile(install)
2015-05-01T16:52:49.73+0100 [STG/0] ERR File “/tmp/buildpacks/php-buildpack/extensions/composer/”, line 162, in _compile
2015-05-01T16:52:49.73+0100 [STG/0] ERR
2015-05-01T16:52:49.73+0100 [STG/0] ERR File “/tmp/buildpacks/php-buildpack/extensions/composer/”, line 244, in run
2015-05-01T16:52:49.73+0100 [STG/0] ERR *self._ctx[‘COMPOSER_INSTALL_OPTIONS’])
2015-05-01T16:52:49.73+0100 [STG/0] ERR File “/tmp/buildpacks/php-buildpack/extensions/composer/”, line 289, in run
2015-05-01T16:52:49.73+0100 [STG/0] ERR shell=True)
2015-05-01T16:52:49.73+0100 [STG/0] ERR File “/tmp/buildpacks/php-buildpack/lib/build_pack_utils/”, line 109, in stream_output
2015-05-01T16:52:49.73+0100 [STG/0] ERR raise CalledProcessError(retcode, cmd)
2015-05-01T16:52:49.73+0100 [STG/0] ERR build_pack_utils.runner.CalledProcessError: Command ‘<open file '’, mode ‘w’ at 0x28b9420>’ returned non-zero exit status 1
2015-05-01T16:52:49.76+0100 [STG/0] OUT Staging failed: Buildpack compilation step failed
2015-05-01T16:52:50.02+0100 [API/3] ERR Encountered error: App staging failed in the buildpack compile phase

This is where it fails in the composer.lock file:
“require”: {
“nikic/php-parser”: “^1.2.2”,
“php”: “>=5.3.3”,
“symfony/console”: “~2.1”,
“symfony/filesystem”: “~2.1”,
“symfony/finder”: “~2.1”

That ^1.2.2 is what it’s complaining about. Any suggestions on how to fix this? Thanks in advance.



Anyone receiving errors due to Invalid version string “^

In your manifest.yml use this:

instead of

This will update your version of composer during the deploy, allowing the push to succeed.



I can’t figure out why i should create htdocs folder and move files. In my case(laravel 5 default app) all work perfectly without this step.


Giulio Prina Ricotti

Hi. Nice tutorial. Working fine.
My only problem is that trying to change the app namespace (or calling some generators I get a

The problem arises here in

if (realpath(app_path()) == realpath(base_path().’/’.$pathChoice)) {

as base_path already contains htdocs/ somehow, and pathChoice is “htdocs/app” (as defined in psr-4) real_path() returns /htdocs/htdocs/app which doesn’t exists clearly.

Has anyone managed to fix this?


Fernando Cisneros

In case you’re having an error of [SymfonyComponentDebugExceptionFatalErrorException] Class ‘yourclass’ not found when using php htdocs/artisan migrate:rollback or php artisan migrate:rollback, try editing the composer.json file with:
“config”: {
“preferred-install”: “dist”,
“vendor-dir”: “htdocs/vendor”

You only have to add the key “vendor-dir” with the new vendor-dir path to the config section.


Fernando Cisneros

A better config file for the cloud foundry php buildpack(with NGINX and a few more php extensions).
Edit the file bp-config/options.json with the following content:
“COMPOSER_VENDOR_DIR”: “htdocs/vendor”,
“WEBDIR”: “htdocs/public”,
“WEB_SERVER”: “nginx”,
“PHP_EXTENSIONS”: [ “bz2”, “zlib”, “openssl”, “fpm”, “tokenizer”, “curl”, “mcrypt”, “mbstring”, “pdo”,”mysql”,”mysqli”,”mysqlnd”,”pdo_mysql”,”apcu”,”mailparse”,”pdo_sqlite”,”Phar”,”shmop”]


Percy Mamedy

I don’t understand how can i handle .env file on bluemix. I cannot do a cf push with my .env beause it is configured for my localhost.

How can i handle this issue?


Henrique Dias

Step by step way to deploy Laravel 5.1 + MySQL in Bluemix



Hi! Great tutorial!
One Quick Question, How can I use the add git? It seems its not working when I tried to clicked it.

or is there any other way to modify code not just cf push.



John Knutson

I have a PHP/Laravel app that works locally, but I’m having a problem seeding the mysql (ClearDB) database on Bluemix. If I just have:
“post-install-cmd”: [
“php htdocs/artisan clear-compiled”,
“php htdocs/artisan optimize”,
“php htdocs/artisan migrate –force”
it creates the tables, but when I add:
“php htdocs/artisan migrate:refresh –seed”
“php htdocs/artisan migrate –seed”

I just get:

* Application In Production! *
Command Cancelled!

I’ve tried numerous combinations – all fail the same way. How can I fix this or get better diagnostics?




With Laravel 5.2, PHP 5.5.9 and above is required.

Use in manifest.yml


John Knutson

@Fernando Cisneros : In one of your comments above, you show “apcu” as an extension of PHP 5.5. Which buildpack did you find that in? I’m using I’m using php-buildpack#v4.3.2 and it isn’t in that.



I tried all the above steps but my app is not deployed on cloud. can any one specify clear steps to upload laravel 5.2.* on bluemix server



Is there a How-To Guide for using Yii2 Framework and Bluemix?

More How-tos Stories

A hybrid Cordova mobile app with Push and Analytics in minutes

As promised while introducing "Tutorials to get your mobile development up and running", we are continuing our efforts to add more mobile solution tutorials. After quickly scaffolding a native iOS-Swift and Android mobile app with Push and Analytics, it's time to bring in the hybrid mobile app development flavor to the game with Cordova - Apache Cordova is an open-source mobile development framework. It allows you to use standard web technologies - HTML5, CSS3, and JavaScript for cross-platform development.

Continue reading

Use your own branded UI for user sign-in with App ID

With IBM Cloud App ID’s Cloud Directory feature, you can create a user registry, and add sign-up and email/password sign-in to your mobile or web app. Cloud Directory comes with a pre-built sign-in widget that you can use, or if you prefer to use your own branding, you can replace it with your own custom UI. This blog will show you how to use Cloud Directory APIs and add your own custom sign-in screen to an Android application. You can find the Android Cloud Land App on GitHub.

Continue reading

For Performant Swift Serverless actions…

While coding and drafting “Mobile app with a Serverless Backend”, We came up with an idea to use Swift on the server-side for the iOS app (it’s an interesting use case).So, that it will cater the full stack swift developers out there. The same is true for the Android version of the app as well.

Continue reading