Deploy Mojolicious applications on shared hosting

Motivation

Recently I was working on a web application using the Perl Mojolicious framework.

I was able to deploy it on a Heroku free account, but with some limitations:

PostgreSQL database limited to 10’000 rows

no way to store logs (without an add-on)

no way to store cache files

limited number of dino

Research

So I checked what my actual hoster o2switch (a shared hosting for 5€/monthly) was providing and found they allowed to deploy NodeJS, Python, and Ruby web applications + provide Pg databases, with no additional cost along with this blog.

Nothing about Perl, even if Perl 5.16 is available within Terminal/SSH and as cgi scripting. I found it was due to the fact they rely on Phusion Passenger 5.7 under the hood for the 3 other languages.

So I decided to compare WSGI and PSGI protocols and found a lot of similarities.

Then I tried to design a middleware dedicated for PSGI but found difficult to pass headers and content from WSGI application to a PSGI middleware.

Solution

Then I rethought the glue as a proxy, so the WSGI application will just create a worker process that is responsible to serve the web app on a dedicated port, and the Transponder will connect to the worker on that port.

That’s how I have started the work on the WSGI Transponder available on Github.

It is easy to deploy, only two files to upload on your website.

This solution does not only target PSGI applications but anything that can start a web server.

Deploying Mojlicious

I have used cartonto maintain the web application dependencies, so it should just be as simple as installing cpanm , carton and start carton to build and install the dependencies.

The two first steps work well, but the last leads to a first error, a dependency requires an XS to be compiled, and unfortunately, o2switch denies access to /bin/gcc by default.

Hopefully, contacting the support has been successful as they respond and grant access really fast.

A last glitch

So, now running cartonhas installed almost all the dependencies but DBD::Pg.

In fact, DBD::Pg requires pg_configcommand to be available at build time.Digging on my shared instance, I found includes and libs paths. The version of Pg was given in phpPgAdmin.

I have hardcoded these pieces of information in a pg_config script that I made available in the PATH before launching the carton command again.