Way back when I began writing Rails applications, a simple
rails server command was usually sufficient for bringing my whole local development environment online. However, with the advent of background workers, module bundlers, transpilers, minifiers, and a number of other supporting actors, the job of firing up an application gradually became more complex over time.
This is, of course, old news. David Dollar released Foreman with the goal of making it simpler to run multi-process web applications locally way back in 2011. Since then, the Procfile was an overwhelmingly popular way to describe all of the different processes that an application depends on or is composed of, and Foreman remains a popular means of running Rails applications in development. It was my personal go-to process runner for Rails development until quite recently, when I fell under the sway of Overmind.
Zerg references aside, the Overmind I’m talking about here is a process manager that uses Procfiles like Foreman, but it includes a bunch of extra features and eliminates some of the trade-offs that relying on a process manager entailed. Since Overmind has already been written about in great detail by its author, I’ll just talk about the the two key features that convinced me to drop Foreman and join the swarm:
Controlling Individual Processes
Foreman doesn’t really give you the ability to stop or restart processes once your app is running. When I made a change to some low level piece of configuration that required a restart to take effect, I had little choice but to stop every process and start things back up with another
foreman start. If all I’m doing is changing my Webpack config, why should I have to restart my Rails server and Sidekiq workers?
Overmind gives you the ability to manage individual processes once it’s up and running. Being able to restart one process in your multiprocess application may seem like an insignificant improvement, but it’s really helped my workflow.
Imagine I’ve got a Procfile that looks like this:
I can start my app with
overmind start, and after that I can interact with either of those processes individually from another terminal tab without restarting the process manager:
Interacting with Processes Directly
Being able to start and stop individual processes is nice, but what really convinced me to use Overmind was its ability to drop me into an interactive session with any of the processes it’s managing. It accomplishes this feat by running each process in a Tmux session. That means each process is actually running in its own full-fledged terminal session, which you can connect to and interact with using
tmux or the
Starting an interactive session with a running process makes debugging applications so much easier for me. It lowers the difficulty of dropping a breakpoint into my code and stepping through it in either Pry or ByeBug. Instead of needing to drop out of Foreman and run
rails server in an interactive terminal, I can just run
overmind connect web when my app hits the breakpoint.
Imagine I’ve got a Rails application with a controller action that I want to debug. For the sake of this simplified example, let’s say my controller looks like this with the breakpoint dropped in:
In a separate terminal tab, I’ve started my app by running
overmind start. Then, in the recorded tab, I’m dropping into an interactive session with my
web process. Since the whole thing is a Tmux session, I can spawn a new split terminal and run a
curl command to make a request that hits the breakpoint. I can then jump back up to the debugger and do whatever investigation I need to do.
When I’m done debugging, I exit the Pry session and watch the cURL pane below spit out my output, complete with the additional string I pushed into the
@widgets array. I finish up by hitting Ctrl-b d, which is Tmux-ese for “detach from the session, but keep it running in the background.”
Overmind has a bunch of advantages over Foreman for developing multi-process web apps locally, many of which I haven’t even mentioned here. If that’s a thing you do, I highly recommend you check it out on GitHub!