I am a developer and a sysadmin – this qualifies me as a lazy person. I don’t want to do things more often than needed. If I can automate my sysadmin part of my life I am happy to do so. One thing about developing stuff with Mojolicious is to start the development server by hand. Sebastian (sri) did a fantastic job in writing morbo, the development server for Mojolicious. morbo is a very capable HTTP 1.1 compliant web server and it’s part of the Mojolicious distribution. The generic syntax to use the daemon with a Mojolicious::Lite application is:
$ morbo [options if needed] <scriptname>
Everytime you change the script, morbo will detect this and will reload the application. Best part of it, it will detect syntax errors and warn you about them. This is very helpful for me as it separates a few steps. First you develop the Mojolicious::Lite application, then you’ll save it, morbo does the syntax check for you and you see if things are broken from the code side, next you’ll test the web application with a browser and check if everything is working there. To run unit tests all the time is self explanatory.
So yes, I am a fan of it. Oh, there is something even nicer about it. morbo doesn’t only check the script for changes, it subscribes automatically to the lib and to the templates directory, too. If they don’t exist, morbo will just do the right thing. So once you’ve a basic Mojolicious::Lite application and decide to inflate it from one file to a directory structure your setup doesn’t need to be changed. That’s cool. Speaking from the sysadmin side of life: It’s a horror to track changes in your deployment configuration. If you are part of the development team you might find ways to deal with it. If you are a sysadmin which only cares for the platform you are doomed.
Here is the simple way I like to work with morbo in my MacOS X environment. I am doing my development stuff in a subfolder of my home directory. I’ve put the folder as a subfolder of my Library folder so I won’t see it all the time. Nothing is more annoying as millions of folders around! Please note: The Library folder is not visible by default, you might want to create the structure in your home directory, if you are uncomfortable with the Unix shell.
You can unhide the Library folder in your home directory by running
$ chflags nohidden ~/Library/
in the Terminal.app.
I’ve used perlbrew to install Perl version 5.14.1 in my home directory. This way I can install modules and play with them without messing around with the MacOS X system stuff. As I’ve said before – I like to keep things separated – call it sysadmin paranoia. Let’s create the basic structure.
$ mkdir -p ~/Library/Mojolicious/{external,external/repo,log}
$ mkdir -p ~/Library/Mojolicious/{static,templates}
$ cd Library/Mojolicious
$ mojo generate lite_app default.pl
Voila, we now have a basic directory structure and a standard Mojolicious::Lite application named default.pl. Let’s see what else do we have.
external
directory for external resources, I clone mojo from github into this directory. I use it as reference as well as for installations of the latest code of Mojolicious.
external/repo
directory for my personal git repositories which are Mojolicious related
log
log directory for Mojolicious (default setting)
static
directory for static resources such as images, css, js files
templates
template directory for Mojolicious applications (default setting)
Now that we have a basic structure and a basic setup we should look on the automatic startup of the morbo server and our just created default.pl Mojolicious::Lite application.
MacOS X uses a special daemon for launching services which is called launchd. The daemon is controlled by a command which is named launchctl. launchctl will be used to load a xml style description of the service into the daemon and start it. You can specify custom services and you’t have to be the user root to work with the daemon, that’s nice. So, let’s look into the xml service file for our morbo service.

launchd property file for morbo - the Moljolicous web server (see gist)
That’s an image, click to enlarge it. I’ve used it for better visibility, you can find the full source file in the following gist.
Here is a quick review of the important parts:
<key>Label</key>
<string>us.mojolicio.default</string>
Every application/service needs to have it’s own label. The label is used to identify the service at a later point. Use a dsl syntax to keep things sorted. My own applications will be named de.pkgbox.mojolicious.<name>.
<key>ProgramArguments</key>
<array>
<string>morbo</string>
<string>–listen</string>
<string>http://*:8080</string>
<string>/Users/rhaen/Library/Mojolicious/default.pl</string>
</array>
This is a little bit tricky. I don’t need to specify the full path to morbo as launchd will use my user environment to run the ProgrammArguments. However, I have to specify the full path to my Mojolicious::Lite application named default.pl. I am using some arguments to morbo to keep it more usuable for me but let’s work down the way. Usually you have to use a Program key and specify ProgramArguments as an array for more arguments. If you discard the Program key it will use the first element of the ProgramArguments as Program key. Simple.
I like to have morbo running on port 8080. Maybe during my development phase I want to run another Mojo application on the default port 3000. That’s just a good way to make sure that normal development doesn’t interfere with your basic environment.
Ok, here is the next part of the setup:
<key>RunAtLoad</key>
<true/>
<key>WorkingDirectory</key>
<string>/Users/rhaen/Library/Mojolicious</string>
<key>StandardErrorPath</key>
<string>/Users/rhaen/Library/Mojolicious/log/output.log</string>
<key>StandardOutPath</key>
<string>/Users/rhaen/Library/Mojolicious/log/output.log</string>
</dict>
RunAtLoad means that we want to start the morbo server right from the start. We don’t want to run it on demand neither we just want to register it, we want it running! The WorkingDirectory is an important setting. launchd will chdir to this directory before running the Program and the ProgramArguments. That’s needed to get the correct environment for Mojolicious for the log, static and templates directory. Last but not the least we use a StandardErrorsPath/StandardOutPath for some basic log files of the launchd daemon. Does something fail? Was there an error? Did morbo crash? We’ll find the information in this file!
Please note: There is an optional setting named KeepAlive which will try to restart the morbo server once it fails. This can be set, however, I would like to know when morbo crashes and why it crashes. That’s why I am not using this setting.
That was alot of stuff! Store all the information above in a file named “us.mojolicio.default.plist” and save it in the external directory of our basic structure. I like to keep the main copy there – just for separation, you know sysadmins paranoia.
In order to activate everything we need to run a few commands. First we need to place a symlink inside the ~/Library/LaunchAgent folder. After that we need to register aka load the file and we are done.
$ mkdir -p ~/Library/LaunchAgents
$ cd ~/Library/LaunchAgents
$ ln -s ~/Library/Mojolicious/external/us.mojolicio.default.plist .
$ launchctl load us.mojolicio.default.plist
Why do we use a symlink? Why don’t we just place the file in the correct place? The answer is simple. We kept everything Mojolicious related together. We can run git init inside the Mojolicious folder and have everything version controlled. One place – one repo, sysadmin paranoia…you know.
By loading the configuration file we informed launchd about a new service and launchd already took over. The new service has been started and the morbo server is serving default.pl at port 8080. Why don’t you fire up a web browser to check it?
Uninstalling everything
Got lost? Want to get rid of everything and start from scratch? That’s simple. First we need to unload the morbo service from launchd. Next we’ll remove the symlink and delete the Mojolicious folder. Voila – finished. Dear developers, that’s sysadmin style. Clean up after your play – dear sysadmins, start coding!
$ cd ~/Library/LaunchAgents/
$ launchctl unload us.mojolicio.default.plist
$ rm -rf ~/Library/LaunchAgents/us.mojolicio.default.plist
$ rm -rf ~/Library/Mojolicious
Make sure to leave some feedback!