Kibana 4 is a free web client for querying your log database. It’s what my team uses for reading through the logs of our midsize web apps and I highly recommend it: https://www.elastic.co/webinars/introduction-elk-stack

But in order to get Kibana running on Bluemix with basic authentication you have to work around a few Cloudfoundry quirks. This is mostly because Kibana 4 does not ship with an authentication method baked in. So unless you want your log data to be public, we have to setup nginx as a reverse proxy that forwards requests on to the Kibana node server after being authenticated.

Here’s how to do this on Bluemix:

Fork the static buildpack

Fork this repo: https://github.com/cloudfoundry/staticfile-buildpack

Take note of the new github url of your forked project as we’ll be using that in our manifest.yml file in a few steps. Go ahead and clone your new repo to your local machine so we can edit a file in the next step.

Edit the nginx.conf file

In your new local copy of your forked static buildpack repo edit conf/nginx.conf to look like the block below.

Why do we have to fork the whole buildpack just to override the nginx config? Wouldn’t it be easier to just provide a custom conf file and let the buildpack detect it and deploy it? Yes it would. And the buildpack claims to support this functionality, however after many failed attempts I decided that this feature must be bugged.

worker_processes 1;
daemon off;

error_log <%= ENV["APP_ROOT"] %>/nginx/logs/error.log;
events { worker_connections 1024; }

http {
  log_format cloudfoundry '$http_x_forwarded_for - $http_referer - [$time_local] "$request" $status $body_bytes_sent';
  access_log <%= ENV["APP_ROOT"] %>/nginx/logs/access.log cloudfoundry;
  default_type application/octet-stream;
  include mime.types;
  sendfile on;
  gzip on;
  tcp_nopush on;
  keepalive_timeout 30;

  server {
    listen <%= ENV["PORT"] %>;
    server_name localhost;

    <% if File.exists?(auth_file = File.join(ENV["APP_ROOT"], "nginx/conf/.htpasswd")) %>
    auth_basic "Restricted";                                #For Basic Auth
    auth_basic_user_file <%= auth_file %>;  #For Basic Auth
    <% end %>

    location / {
        proxy_pass http://127.0.0.1:5601;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

  }
}

You can see that main difference between the standard nginx.conf file and ours is that at the root of the project we redirect all requests to localhost at port 5601. That’s where Kibana is going to be running!

Initilize our Kibana project

Download Kibana 4 for 64 bit Linux (https://www.elastic.co/downloads/kibana) and extract the contents into your project directory. In the root of your project create manifest.yml file, here’s what mine looks like:

applications:
- disk_quota: 128M
  host: <your-host-name>
  name: <your-app-name>
  path: .
  domain: mybluemix.net
  instances: 1
  memory: 128M
  buildpack: https://github.com/<your-github-name>/staticfile-buildpack

Setup Kibana to run alongside nginx

In the root of your project, create a directory with the name .profile.d. One of the little advertised but extremely useful features of bluemix is the .profile.d directory. A directory in the root of your project with this name will have all bash scripts contained within executed just before the app begins to run.

We’re going to make use of this feature to start kibana. Create a bash script inside your newly created .profile.d directory with any name you like. I called mine init.sh.

echo "starting kibana as background process..."
./app/bin/kibana &

The “&” symbol at the end of the kibana command instructs that it should be started as a background process. This is imporant because otherwise Bluemix will look for this application to be running at the provisioned port number, not the port we are using, and will fail to start nginx. Incidently, you can find the port that Kibana uses by default (5601) by checking out config/kibana.yml.

Create a Staticfile.auth file

Create Staticfile.auth in the root of your project with your desired login credentials as the only contents of the file. The username and password should formatted like an .htaccess file (each line contains: username:md5-hashed-password).

This last step is really the whole reason we are using nginx as a gateway to our app. If we weren’t concerned with security of our application we could simply deploy this app with a “null” buildpack, for example this one: https://github.com/ryandotsmith/null-buildpack, and start kibana at the provisioned port (you would have to replace the config/kibana.yml port with a sed script in the .profile.d directory and the start command would simply be ./bin/kibana)

All that remains now is for you to cf push your app to Bluemix!