Neo Tux

So you have a Linux VM you use for development, because you want to mirror the production environment as closely as possible. You have many applications to deal with, they have to be running at the same time because they are nifty REST JSON web services.

You are very tired to remember which one you put on port 8081, and your configuration files slowly become a real mess. So you set up IP address aliases in for the network interface and decide to assign even host names – /etc/hosts is just fine – for each app.

Then, in such a setup, why would you still need to run them on ports higher than 1024? Wouldn’t be just great to type the application name in the browser address bar? Indeed it is, but it’s better to not run them as root, anyway.

The solution are Linux capabilities (see also here). The one that interests us is cap_net_bind_service: it gives a process the right to bind well-known ports (< 1024). If you use an interpreted language, of course you’ll have to add the capability to the interpreter itself. That’s why there’s development in the title of this article – you should not set this up on a production server, if you don’t know what you are doing.

One final quirk: if you happen to dlopen() shared objects that dynamically link towards libraries outside the canonical paths, you cannot load them via LD_LIBRARY_PATH (e.g. the SYBASE.sh) as it is ignored for setcap-ped processes. You should better move the library paths into an /etc/ld.so.conf.d snippet.

tl;dr

Assuming you are the latest and greatest rails developer, you should become root – or use sudo, as you wish – and

# YOU ARE ON YOUR DEVELOPMENT MACHINE
setcap cap_net_bind_service+ep `which ruby`

Profit:

thin start -a yourapp -p 80
>> Using rack adapter
>> Thin web server (v1.2.11 codename Bat-Shit Crazy)
>> Maximum connections set to 1024
>> Listening on yourapp:80, CTRL+C to stop
...