On Foreman and Procfiles
Over the last few years I've amateurishly covered the entire stack from design to server administration, and on that tirade I've managed to break many rules.
Premature optimization? Check. Refactoring without reason? Check. Overengineering? Check.
I'm obsessive-compulsive about a few things. For example, I always fold chip bags into little squares before throwing them away. But that has nothing to do with anything. I'm a very detail-oriented person, but to a fault. If I find something interesting about a particular process, for instance, I will spend exorbitant amounts of time learning its ins and outs. Wasteful? That's a fair assumption.
But I'll spare you the rest of the details and talk about my find of the day, the Foreman gem and the
But don't you program in Python?
Shut your face, that mentality is so yesterday. I will prefer the Python implementation of a program as opposed to that of its rivals if and only if it is a more elegant solution. SASS and Compass proved that to me. Anybody remember CleverCSS? Yeah, thought so. Practicality beats purity.
Alright, class is in session. Let me flip this around and show you my
Procfile first, then explain what happens inside of it:
compass: compass watch static db: postgres -D /usr/local/var/postgres redis: redis-server /usr/local/etc/redis.conf web: python ranking/manage.py runserver
So what does it do? Instead of opening a tab in Terminal for each of those items or starting them as a daemon, it allows me to concatenate the operation into one simple command:
foreman start -f Procfile.dev
.dev? In my case, the sans-extension
Procfile in my project is for Heroku with production-only commands. If you run
foreman without the argument, it'll look for
Procfile by default. After you run that command you'll be greeted by this lovely sight:
14:14:37 compass.1 | started with pid 3115 14:14:37 db.1 | started with pid 3116 14:14:37 redis.1 | started with pid 3117 14:14:37 web.1 | started with pid 3118
Like what you see? Great! If you've gotten this far, you should've already installed the Foreman gem by now and created a Procfile. Now, there are a few gotchas when working with your services in Foreman, especially if you're using Homebrew, Redis and PostgreSQL:
- Foreman doesn't like daemons. If you throw a command into your
Procfilethat dameonizes the process, Foreman will start the process only to shut down entirely because it disappeared like it was supposed to.
- To that point, test the commands that Homebrew gives you when you run
brew info <formula>and see if it daemonizes. Here's a freebie: the PostgreSQL command that Homebrew gives you:
pg_ctl -D /usr/local/var/postgres -l /usr/local/var/postgres/server.log startWILL daemonize it. You're going to want the command posted above instead.
- If your program logs to
STDOUTit'll all be aggregated. But if you've ever run
redis-serverthrough Homebrew, it's VERBOSE. To regain your sanity, go into
/usr/local/etc/redis.confand change the
On a slightly related note, I love Homebrew. I just hate the way it instructs you to start processes. It's shit, especially if you're coming from a Linux development environment where
upstart lives to massage your feet and feed you grapes. Do yourself a favor and grab this script, throw it in your Homebrew's
bin/ and profit using
brew services start <formula>, even if you don't use Foreman in the end.
If you do a quick search on Foreman, you'll rightfully see a slew of Ruby-centric articles. However, the amazing thing about this gem is that all it does is manage processes, so you can throw anything in there, no matter what language you happen to be programming in. Over the weekend I've been working on moving a wiki of ours to PHPFog, for my local install I've thrown
mysql in a
Procfile and it all Just Works™. No more struggling to remember commands. No more forgetting to shut processes off.
There are lots of great things that people have been doing with
Procfiles, automatically running tests after saving files in Django or exporting it to
upstart if you're on Linux are just two examples.
So for once my obsessiveness has rewarded me with a streamlined development workflow, and I hope it'll do the same for you!