Toadfarm on Base Debian: An absolutely minimal multi-tenant webserver


Here we create an absolutely minimal multi-tenant webserver, without even installing Apache or NginX. Although we can add either of those later, with our content running under them as reverse proxies, this tutorial lets you run one or more Mojolicious "apps" mounted under a single toadfarm startup script, saving you the "default perl memory" times the number of worker processes and apps.

We will b using Jan Henning Thorsen's Toadfarm:

Toadfarm is a module for configuring and starting your Mojolicious applications. You can either combine multiple applications in one script, or just use it as a init script.

First, perform a Debian Netinstall on a virtual machine or virtual host. The only modification to all the default selections is to enable only "Standard System Utilities" and disable desktop, database, mail, print, file, and web server. We will be building our own of all those!

Now boot up into that absolutely stock, base machine. For illustration, we will assume your username is gronk − change this as necessary. First let's install a few system packages (ssh for access; curl for installing Perlbrew et al; sudo for convenience; build-essential for GCC, Make, and the compiler tools; and the no-X version of emacs because I've been using it since 1980):

$ su
# apt-get install sudo ssh curl build-essential emacs-nox
# usermod -a -G sudo <em>gronk</em> # exit

Now we install our Perlbrew environment as the user:

$ \curl -L | bash
$ echo source ~/perl5/perlbrew/etc/bashrc >> ~/.bash_profile
$ perlbrew install 5.22.0 -j5

The -j5 means use five processes for the Make. Then:

$ perlbrew switch 5.22.0
$ perlbrew install-cpanm
$ curl -L |     perl - -M -n Mojolicious
$ cpanm Toadfarm

jhthorsen explains how this goes together:

You can't run individual apps inside toadfarm as different user, but you can start toadfarm as root and change to a different user.


This is true of Mojolicious generally ]( .

In particular, we create an Init script with a #! (hashbang) that points to our user's "brewed" Perl. From the documentation:

Remember that the hashbang can be anything, so if you have Toadfarm and Mojolicious running under


plenv ]( or Perlbrew you need to change the hashbang part…

So we change our Init script to start with:


Then in the Toadfarm script called by the Init script, which is started as root, we do the switch to our user (called some-www-user in the documentation, gronk here):

#/usr/bin/env perl
use Toadfarm -init;
# …
start [qw( http://*:80 https://*:443 )], user => "<em>gronk</em>", group => "<em>www</em>";

From the documentation:

Changing user has one implication: The workers will not use some-www-user's secondary groups. So if "some-www-user" is part of the "www" and "db" groups, then the process will only be run as "some-www-user" part of the "www" group.

See also the IRC log for 26 April 2014.

Fix: Perlbrew can't install 5.21.2


If you find that perlbrew is unable to install perl 5.21.0, and the build log shows the following message:

First let's make sure your kit is complete. Checking...
Looks good...

*** WHOA THERE!!! ***

This is an UNSTABLE DEVELOPMENT release.
The version of this perl5 distribution is 21, that is, odd,
(as opposed to even) and that signifies a development release.
If you want a maintenance release, you want an even-numbered version.

Do NOT install this into production use.
Data corruption and crashes are possible.

It is most seriously suggested that you do not continue any further
unless you want to help in developing and debugging Perl.

If you still want to build perl, you can answer 'y' now,
or pass -Dusedevel to Configure.

Do you really want to continue? [n]

Okay, bye.

This is a known and resolved issue and has been patched. The simplest way to make things work is to simply say:

$ <span style="text-decoration: underline;">perlbrew self-upgrade</span>
$ <span style="text-decoration: underline;">perlbrew install 5.21.2</span>   
  ## works now.