Procman: An alternative for running Procfile apps

Some time ago, we migrated our work application from Rails 6 to Rails 8 in one big jump and adopted several new features that came with this version. One of those was a Procfile that defined the necessary processes to run the application in local environments, which is executed when you run bin/dev. If you look at the code of this file, you will find the real responsible party for executing all these processes: foreman (unless you modified the original file).

The first problem we started encountering was that all process outputs were mixed into a single stream, making it take us a long time to realize that, for example, JavaScript compilation had failed, which is why we weren’t seeing the changes we were making locally.

The second and most important issue was that we couldn’t use a debugger the same way we used to. This happens because Foreman runs everything as subprocesses that are not inside an interactive terminal. To solve this quickly, we started avoiding launching the web server with Foreman while still running all other services, and in a new terminal, we would run bin/rails s, and everything worked as before again. But what if we want to put a debugger on a job executed by Sidekiq? Then we’d have to repeat the same process: skip it in bin/dev to execute Sidekiq in another terminal and be able to capture the interactive debugger terminal.

So, our problems combined with my interest in continuing to learn Rust and building terminal tools motivated me to create procman, a process manager for Procfile-defined processes in a TUI format using the best library for doing this: ratatui.

Procman fullscreen process

Unlike other alternatives for running applications with defined Procfiles (Foreman, Overmind, and others), with procman you can manage all processes in a single terminal without having to open new terminals to run something like overmind connect or perform unconventional solutions like the ones my team took. In procman, you can manage each process separately, whether starting or stopping the process, filtering or searching within logs, or obtaining an interactive shell to play around in.

I created the interface heavily inspired by btop, where every word of an action has a bolded letter indicating which key you should press to perform that action. Something very intuitive and easy to use, in my opinion. Of course, at the interface level, procman is much simpler now; there are no themes or global configurations. But it fulfills its purpose.

I think it’s worth mentioning that this isn’t just useful for Ruby on Rails applications as is my case. The Procfile is a Heroku definition, and applications in any other language that have at least one Procfile defined could use this tool to launch their processes in local environments.

My idea for the future is to continue polishing the tool less with new features and more with stability and robustness of the functionalities I’ve already added. Exploring ideas that bring the most value and listening to feedback (this would be the most important); for this, I invite you to try the tool, which is currently compiled for Linux and macOS, and you can install it using the following command:

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/a-chacon/procman/releases/download/v0.0.1/proc-man-installer.sh | sh

Or install it directly with Cargo:

cargo install proc-man

And yes, the name procman was already registered on crates.io. But don’t worry, because the executable will still be procman.

I invite you to leave any comments on the tool’s repository, and I hope you find it useful.

For Rails Apps

To use procman as a drop-in replacement for Foreman in your Rails application, replace the contents of your bin/dev script with the following. This script automatically checks if procman is installed and installs it via the official installer if missing:

#!/usr/bin/env sh

# Check if procman is installed; if not, install it automatically
if ! command -v procman >/dev/null 2>&1; then
  echo "procman not found. Installing..."
  curl --proto '=https' --tlsv1.2 -LsSf https://github.com/a-chacon/procman/releases/latest/download/proc-man-installer.sh | sh
  
  # Refresh shell path if needed (depending on shell and install location)
fi

# Default to port 3000 if not specified
export PORT="${PORT:-3000}"

# Start processes via procman
exec procman Procfile.dev "$@"

https://github.com/a-chacon/procman