blog single gear
Tutorials

100-day Challenge #055: Running Kanboard on Cloud Foundry

Translator’s note: This is the 13th article in the series “Cloud Foundry 100-day Challenge.” “#055” in the title means that it is the 55th in the original Japanese series (published on September 7,  2015).

Original Author: Kiyohide NAGAI


The 55th topic of “Cloud Foundry 100-Day Challenge” is the Kanboard, which employs the Kanban method and can be used for project management, similar to the topic we picked up in the previous article (Translator’s note: in Japanese) .

This application is limited in functions when compared to other project management applications discussed in earlier articles, but should suffice in many cases where you would like to perform simple project management tasks. This application is compatible with Heroku, a PaaS which Cloud Foundry is similar to. (We noticed this after we began to try running it.) So the deployment procedure is quite simple.

Basic Information

  1. Official site
    Kanboard
  2. Source code
    http://kanboard.net/downloads

 

Reference
http://kanboard.net/documentation/installation

The procedures are as follows:

  1. Retrieving source code
  2. Preparation
  3. Deploying application
  4. Checking application behavior

1. Retrieving source code

As always, we will download its source code from the official site in ZIP format.
For reference, the version at the time of this post was v1.0.17.

$ wget http://kanboard.net/kanboard-latest.zip
$ unzip kanboard-latest.zip
$ cd kanboard
$ ls
app  assets  ChangeLog  config.default.php  data  index.php  jsonrpc.php  kanboard  LICENSE  robots.txt  vendor

2. Preparation

2.1 Adding PHP extension module

We handle necessary procedures regarding each PHP extension module in accordance with the Installation requirements.
However, with SQLite, it has been mentioned in previous articles that information in database is lost when an application is rebooted, so today we will modify it to use MySQL instead.
Along with ‘mbstring’ and ‘gd’, we need to add ‘pdo’ and ‘pdo_mysql’ for MySQL.

$ mkdir .bp-config
$ vi .bp-config/options.json
$ cat .bp-config/options.json
{
    "PHP_EXTENSIONS": ["pdo","pdo_mysql","gd","mbstring"]
}

2.2 Preparing MySQL service

Let us speed through this section, as it is also similar to the last time (Translator’s note: in Japanese) .

$ cf push kanboard --no-start
$ cf create-service p-mysql  100mb kandb
$ cf bind-service kanboard kandb
$ cf env kanboard
Getting env variables for app kanboard in org k-nagai / space work as k-nagai...
OK

System-Provided:
{
 "VCAP_SERVICES": {
  "p-mysql": [
   {
    "credentials": {
     "hostname": "10.244.7.6",
     "jdbcUrl": "jdbc:mysql://10.244.7.6:3306/cf_b25edd98_54fe_41d2_bf5e_9883e4925973?user=Xe40DtPu0xNyIPRO\u0026password=u1vFRM49kw4zp1Wo",
     "name": "cf_b25edd98_54fe_41d2_bf5e_9883e4925973",
     "password": "u1vFRM49kw4zp1Wo",
     "port": 3306,
     "uri": "mysql://Xe40DtPu0xNyIPRO:u1vFRM49kw4zp1Wo@10.244.7.6:3306/cf_b25edd98_54fe_41d2_bf5e_9883e4925973?reconnect=true",
     "username": "Xe40DtPu0xNyIPRO"
    },
    "label": "p-mysql",
    "name": "kandb",
    "plan": "100mb",
    "tags": [
     "mysql"
    ]
   }
  ]
 }
}

:

2.3 Setting environment variables

You might guess from the procedures up to this point that the next step will be to “rename ‘config.default.php’ and edit the MySQL information”, but since the application has Heroku-compatiblity, we will utilize this feature to proceed.

The key here is the ‘uri’ information obtained from ‘cf env’, something we previously did not have the chance to use too much.
We set the obtained ‘uri’ to the environment variable called ‘DATABASE_URL’.

$ cf set-env kanboard DATABASE_URL "mysql://Xe40DtPu0xNyIPRO:u1vFRM49kw4zp1Wo@10.244.7.6:3306/cf_b25edd98_54fe_41d2_bf5e_9883e4925973?reconnect=true"

This completes our preparation.

3. Deploying application

Let’s go ahead to ‘cf push’.

$ cf push kanboard
:
requested state: started
instances: 1/1
usage: 256M x 1 instances
urls: kanboard.10.244.0.34.xip.io
last uploaded: Wed Aug 19 07:16:14 UTC 2015
stack: cflinuxfs2
buildpack: PHP
 
     state     since                    cpu    memory        disk      details   
#0   running   2015-08-19 04:16:33 PM   1.7%   31M of 256M   0 of 1G  

The application started up without a problem.

4. Checking application behavior

When we access ‘http://kanboard.10.244.0.34.xip.io’, we first get the login screen after a brief moment.
It seems that the initial database settings run in the background.

We first log in with the default ‘admin/admin’.

Let us choose ‘Settings’ from the menu, and set our language and time zone under ‘Application Settings’.

After this, you can play around with adding users, creating projects, task management, etc.

Finally, there is a point to note. This application, similar to the previous applications, does not care about file persistency.
Information stored in the database such as user or task information are safe, but attached files will disappear when the application is rebooted, so we should take care of them by ourselves. There are some applications out there that have solved this issue, so I would like to introduce them on the next occasion.

Extras: if you create ‘config.php’

A little extra information on what happens when you create ‘config.php’ in step 2.3.
If you do, variables get conflicted during the ‘cf push’ due to the processing by ‘app/common.php’, and the deployment will fail. It will be obvious when you see it, but there is a script that takes ‘DATABASE_URL’ apart and substitutes each variable, followed by a setting that reads the same variables from config.php. As such, if you absolutely must use ‘config.php’, it should work if you comment out the following section of ‘app/common.php’:

 if (getenv('DATABASE_URL')) {
 
     $dbopts = parse_url(getenv('DATABASE_URL'));
 
     define('DB_DRIVER', $dbopts['scheme']);
     define('DB_USERNAME', $dbopts["user"]);
     define('DB_PASSWORD', $dbopts["pass"]);
     define('DB_HOSTNAME', $dbopts["host"]);
     define('DB_PORT', isset($dbopts["port"]) ? $dbopts["port"] : null);
     define('DB_NAME', ltrim($dbopts["path"], '/'));
 }

Software Used in this Post