— my toolbox is filled with perl, javascript, css and html


How to deploy #Mojolicious apps on @DigitalOcean

Sunday, March 09, 2014


Mojolicious is truly a modern web framework. It keeps up to date with the HTTP, HTML, WebSockets and JSON specifications so you don’t have to worry about doing that right. It’s a framework where you implement the core business logic, while everything else Just Works (tm).

DigitalOcean is “cloud hosting, built for developers”. It’s relatively new, but the user base has grown rapidly. I think the reason is that the pricing plan is understandable and affordable, and the setup is extremely simple.


You need to know basic shell and/or have an interest in seeing how easy it is to deploy a Perl based web application.

The application

I’ve chosen Timer as the example application, since it’s quite simple but still has the amount of dependencies to put it in a “real app” category. It also doesn’t require a database, which makes it more Perl focused.

Step 1: Setup DigitalOcean

You need to create an account and a droplet on DigitalOcean.

Follow the “How To Create Your First DigitalOcean Droplet Virtual Server” instructions if you need guidance.

Notes about the how to:

Step 2: Install dependencies

So now you have set up DigitalOcean and you are logged in as “root”.

Next we will install dependencies using “apt-get”.

$ apt-get install make gcc cpanminus rubygems git-core libio-socket-ssl-perl libio-socket-ip-perl libev-perl

Step 3: Add a user

We don’t want to run the “Timer” application as “root” for security reasons, so we need to add a user with the username “bender”.

$ adduser bender
$ usermod -a -G sudo bender

NOTE! Choose a safe password!

NOTE! We are adding the user to the “sudo” group for convenience. You might want to remove it from that group later to increase security.

Step 3: Download and start the application

Now that all the basic prerequisites are in place, you can install the “Timer” application as the user “bender”.

# Become "bender" if you are still "root"
$ su - bender

# Download the application
$ git clone https://github.com/jhthorsen/timer.git

# Enter the cloned repository and install Timer dependencies
$ cd timer
$ cpanm -n --sudo --installdeps .

# Start the application
$ hypnotoad script/timer

Hypnotoad is a full featured, UNIX optimized web server written in Perl. This means that after you have run the “hypnotoad” command, you can access your application on http://$DROPLET_IP:8080/. The $DROPLET_IP is the same IP that you logged into after you set up the Droplet.

Step 4: Listen to port 80, instead of 8080

We will now set up firewall rules using ufw. This will make the server more secure but also allow us to access the “Timer” application on the standard port 80.

If you are still the “bender” user, you need to run “exit” to become “root”. When you are “root”, run the commands below to set up ufw.

NOTE! It is very important that you include the “ufw allow ssh” line, or else you will be locked out of your own droplet. If that happens, you need to start a console from web, by logging into DigitalOcean.

# basic firewall rules: Deny everything except HTTP and SSH traffic
$ ufw default deny incoming
$ ufw default allow outgoing
$ ufw allow ssh
$ ufw allow 80/tcp
$ ufw allow 8080/tcp

# forward traffic from port 80 to 8080
$ cat <<FIREWALL_RULES >> /etc/ufw/before.rules
-A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
-A OUTPUT -o lo -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080

# start the firewall
$ ufw enable

Step 5: Autostart the application when the server boots

If you restart the server now, the Timer application will not start. You can autostart the server by adding a command to “/etc/rc.local”, right before “exit 0” or somewhere before the end of the file.

/usr/bin/sudo -u bender hypnotoad /home/bender/timer/script/timer

You are done

As you can see from this tutorial, it’s not hard or expensive to get your Perl based web application up and running in the cloud.

Got questions or feedback? Contact me on twitter, IRC or drop me an email.

Questions and answers

blog comments powered by Disqus