> Home > News Index

2014-10-05 - Running perl web apps in Flynn

Flynn is a new PaaS (Platform as a Service) project intended to manage a cluster of servers running applications inside containers. Applications are deployed using a simple 'git push' and behind the scenes the application is built in a container and the container is then started on one or more nodes within the cluster.

Current version is v20140817, classed as Pre-release. In other words, it's still bleeding edge.

I tried it out under a VMWare ESXi client, an LXC container and inside a Vagrant Virtualbox VM (all running Ubuntu 14.04 Trusty).

First, the two failures. Trying it in the LXC container failed utterly because the container wasn't able to itself run containers. I could have probably fixed that by messing with the LXC container configuration, but there are only so many hours in a day (and I use all of them already).

I couldn't get Flynn running under the ESXi client. I doubt it was an unfixable problem, i.e. there's nothing inherent in the ESXi client which would stop Flynn from working.

I did get it going under Vagrant Virtualbox, by following the steps listed under "Manual Ubuntu Deployment" very carefully(*). Those steps were (presented as a script):

#!/bin/bash
#
#  Install Flynn on this host

apt-get update
apt-get -y upgrade
apt-get -y install apt-transport-https curl patch

apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv BC79739C507A9B53BB1B0E7D820A5489998D827B
echo deb https://dl.flynn.io/ubuntu flynn main > /etc/apt/sources.list.d/flynn.list
apt-get update
apt-get -y install linux-image-extra-$(uname -r) flynn-host

if [ ! -f token ] ; then
        curl -k https://discovery.etcd.io/new > token

        patch <<EOF /etc/init/flynn-host.conf
--- a   2014-10-04 08:15:09.380249566 +0000
+++ b   2014-10-04 04:33:20.135872045 +0000
@@ -1,5 +1,7 @@
 description "Flynn layer 0"

+env ETCD_DISCOVERY=$(cat token)
+
 #start on (started libvirt-bin and started networking)
 respawn
 respawn limit 1000 60
EOF

fi

flynn-release download /etc/flynn/version.json
start flynn-host

Don't forget to install the correct linux-image-extra package, as I did - else you won't have aufs and Flynn will emit unhelpful errors. Don't forget to run the flynn-release command, as I did - else flynn-host will not be able to run anything and it will respawn forever by upstart.

In fact it's a good idea to change the respawn limit 1000 60 line to respawn limit 5 300 and add a line post-stop exec sleep 10 to ensure that if Flynn doesn't start up properly, it won't thrash your VM.

After this it's necessary to run flynn-bootstrap, and that must be done after setting up some wildcard DNS resources to point to your cluster host(s). Flynn's load-balancing (?) router uses the hostname in the HTTP request to distribute your traffic to the apps running in the containers listening on some ports other than 80 or 443.

When I did eventually get Flynn running, it more or less did what the sparse documentation indicated it should.

I was able to get a simple perl web app running in containers. An app is developed in a git repository and is deployed by pushing a branch to Flynn's git server. Flynn then builds the app into a container and deploys it accordingly. Building the app requires some machine-readable build and execution instructions. Documentation for doing this for perl was nonexistent so I had to figure it out.

Here's my application in its repository.

==> .buildpacks <==
https://github.com/miyagawa/heroku-buildpack-perl.git

==> cpanfile <==
requires 'Mojolicious';
requires 'Sys::Hostname';

==> app.psgi <==
#!/usr/bin/env perl
use Mojolicious::Lite;
use Sys::Hostname qw();

# Documentation browser under "/perldoc"
plugin 'PODRenderer';

get '/' => sub {
  my $c = shift;
  $c->stash('hostname', Sys::Hostname::hostname());
  $c->render('index');
};

app->start;
__DATA__

@@ index.html.ep
% layout 'default';
% title 'Welcome';
Welcome to the Mojolicious real-time web framework! Hello, world! <%= $hostname %>

@@ layouts/default.html.ep
<!DOCTYPE html>
<html>
  <head><title><%= title %></title></head>
  <body><%= content %></body>
</html>

==> Procfile <==
web: 'perl -Mlib=$PWD/local/lib/perl5 ./local/bin/starman --preload-app --port $PORT'

Did I mention there is no documentation for running a perl app?

Flynn apps can (must?) be defined in a Heroku buildpack compatible manner. The included flynn/slugbuilder component has some preset buildpacks, and one of the buildpacks allows additional buildpacks (such as the perl one) to be specified in a .buildpacks file. So that's what .buildpacks is for, to pull in Miyagawa's buildpack for a Perl/PSGI application.

The cpanfile says what perl modules need to be installed. I used Mojolicious and generated a sample application with a very small amount of customisation.

For Miyagawa's buildpack, the perl script has to be named app.psgi (that's how it detects if the buildpack should be used).

Finally the Procfile is a YAML file and it specifies how the command should be started to run in 'web' (flynn scale web=5 scales the application to 5 concurrent instances).

I could have omitted the Procfile, and Flynn would have started the application according to instructions in a .release file generated by the buildpack.

That's how far I got before something broke and I couldn't get Flynn working again. Bear in mind, Flynn is still bleeding edge but it shows some promise.

Thoughts

Next up I'll be testing Tsuru.