Hateburo: kazeburo hatenablog

SRE / 運用系小姑 / Goを書くPerl Monger

Run any Perl applications on Heroku

I made a simple heroku-buildpack for perl. With using this buildpack you can run any perl application from Procfile.

github: https://github.com/kazeburo/heroku-buildpack-perl-procfile

Sample and Usage

This sample runs a PSGI server and a worker in 1 Dyno (It's free).

$ ls
cpanfile
Procfile
server.pl
lib/

$ cat cpanfile
requires 'HTTP::Tiny','0.043';
requires 'Getopt::Long';
requires 'Proclet';
requires 'Plack';
requires 'Starlet';

$ cat Procfile
web: ./server.pl --port $PORT

$ heroku create yourappname --buildpack https://github.com/kazeburo/heroku-buildpack-perl-procfile.git

$ git push heroku master
...
-----> Heroku receiving push
-----> Fetching custom buildpack
-----> Perl/Procfile app detected
-----> Installing dependencies

And server.pl

#!/usr/bin/env perl

use strict;
use warnings;
use FindBin;
use lib "$FindBin::Bin/lib";
use Proclet;
use Plack::Loader;
use Getopt::Long;
use HTTP::Tiny;

my $port = 5000;
Getopt::Long::Configure ("no_ignore_case");
GetOptions(
    "p|port=s" => \$port,
);

$proclet->service(
    tag => 'worker',
    code => sub {
        my $worker = MyWorker->new;
        $worker->run
    },
);

my $app = MyWeb->to_psgi;
$proclet->service(
    code => sub {
        my $loader = Plack::Loader->load(
            'Starlet',
            port => $port,
            host => 0,
            max_workers => 5,
        );
        $loader->run($app);
    },
    tag => 'web',
);

$proclet->run;

In some cases, adding a worker to access the Web server periodically might be good.

$proclet->service(
    every => '*/30 * * * *',
    tag => 'ping',
    code => sub {
        my $ua = HTTP::Tiny->new;
        $ua->get("http://${yourservicename}.herokuapp.com/");
    }
);

Proclet is minimalistic Supervisor. it also supports cron like jobs. it's very useful!

At the last, don't forget to add exec permission to server.pl

chmod +x server.pl