procman 0.2.0

A foreman-like process supervisor
procman-0.2.0 is not a library.

procman

crates.io

A foreman-like process supervisor written in Rust. Reads a Procfile, spawns all listed commands, multiplexes their output with name prefixes, and tears everything down cleanly when any child exits or a signal arrives.

Usage

cargo install --path .
procman [OPTIONS] [PROCFILE]

Defaults to Procfile in the current directory if no path is given.

Server mode

Run procman with a named FIFO to accept new process commands at runtime:

procman --server /tmp/procman.fifo

Client mode

Send a command to a running procman server:

procman --client /tmp/procman.fifo "redis-server --port 6380"

The server parses the command line using the same rules as Procfile entries (including environment variable substitution) and spawns it into the existing process group.

An advisory flock on the Procfile prevents multiple instances from managing the same file simultaneously.

Procfile Format

# Global environment variables (before any command lines)
DATABASE_URL=postgres://localhost/myapp
PORT=3000

# Commands — one per line
web serve --port $PORT
worker process-jobs --db $DATABASE_URL
  • Lines starting with # are comments.
  • Trailing \ joins continuation lines.
  • KEY=value lines before the first command set global environment variables.
  • Inline KEY=value tokens at the start of a command line set per-command env vars. Values may be quoted: FOO="hello world" myprogram.
  • $VAR references are substituted from the merged environment (inherited + global + inline). Undefined variables are a hard error — nothing is spawned.
  • Process names are derived from the program basename. Duplicates get .1, .2 suffixes.
  • Note: Unlike a POSIX shell, inline env vars are passed to the child process and substituted into the command line. FOO="abc" echo $FOO will print abc, whereas a shell would expand $FOO before the assignment takes effect and print an empty line.

Behavior

  • All children share a process group.
  • stderr is merged into stdout per-process.
  • Output is prefixed with the process name, right-aligned and padded.
  • Per-process logs are written to ./logs/<name>.log.
  • On SIGINT or SIGTERM, all children receive SIGTERM. After a 2-second grace period, remaining processes are sent SIGKILL.
  • procman exits with the first child's exit code.

License

MIT