Alister West

home is where your code is ...

Mojolicious Daemon deployment options.

Mojolicious hypnotoad or morbo deplyment with Daemon::Control

A wrapper script (bin/webapp.ctl) to crontrol my mojo webapp. I bundled a local copy of Mojolicious with my webapp via Carton.

#!/usr/bin/env perl
#
# webapp.ctl - Daemon::Control + local::lib + Mojolicious + Hypnotoad
#
use warnings;
use strict;

use Cwd qw/abs_path/;
use Daemon::Control;
use FindBin;
use local::lib "$FindBin::Bin/../local";

my $root = abs_path "$FindBin::Bin/..";
my $app = "$root/bin/example.com.pl";

## Production ##
#
# Notes:
# - fork(1) for hypnotoad to do its own process mangement
# - pid_file() must use same pid file mentioned in hypnotoad
# - hypnotoad needs to shell out - can't use with a coderef.
# - D:C needs Mojo >= v3.42 to work nicely with pid files.
#
my %opts = (
    directory    => $root,
    name         => "example.com",
    pid_file     => "$root/logs/webapp.pid",
    program      => "$root/bin/hypnotoad",
    program_args => ["$app"],
    fork         => 1, # let hypnotoad handle everything
);

## Development ##
if ($root =~ /alister/ or grep { /dev/ } @ARGV) {
    my %opts = (
        %opts,
        directory    => $root,
        name         => "example.com",
        pid_file     => "$root/logs/webapp.pid",
        program      => "$root/local/bin/morbo",
        program_args => [ "--listen", "http://*:8015" , $app ],
        stderr_file  => "$root/logs/perl_error_log",
        stdout_file  => "$root/logs/perl_error_log",
        fork         => 2, # D:C to handle pid/logs/etc..
    );
}

# warn "CMD: $opts{program} ". join " ", @{$opts{program_args}};
my $dc = Daemon::Control->new( \%opts );
$dc->run;


# etc/app.conf - perlish configuration
{   # ... 
    "hypnotoad" => {
        "listen"   => [ "http://*:8010" ],
        "pid_file" => "/var/home/alister/dev.example.com/logs/webapp.pid",
        "workers"  => 5
    },
};

Mojo::Server::Morbo + Apache2.2/mod_proxy

When you change a file you often get an error page thown. mod_proxy by default will cache this 503 for 60 secs. See "retry":http://httpd.apache.org/docs/2.2/mod/mod_proxy.html#proxypass [apache.org]

# Production setup (Hypnotoad)
# http://mojolicio.us/perldoc/Mojolicious/Guides/Cookbook#Apache2Fmod_proxy
ProxyPass / http://localhost:8080 keepalive=On

# Dev setup (Morbo)
# Fetch a fresh page from the backend even though previous request was an error.
ProxyPass / http://localhost:8080 keepalive=On retry=0


# Sometimes with an apache setup you want to change the url base
$self->hook( before_dispatch => sub {
    my $self = shift;
    my $uri = $self->req->env->{SCRIPT_URI};
    $self->req->url->base(Mojo::URL->new($uri)) if $uri;
});
By Alister West