Harness the Combinatoric Power of Command-Line Tools and Utilities

../Tutorials

Run Multiple Processes With Foreman

Bash tools Node.js

Published May 26, 2024

If you have to run a database server, a web server, a background job process, or other processes simultaneously, you know managing these processes during development is challenging. Each process needs its own terminal window, which means you’re opening a new window, switching to your project folder, and switching to the project directory.

Foreman is a tool that helps you manage multiple processes. Instead of juggling multiple windows, you specify all your services in a small configuration file that lives with your project, and the tool runs the services for you. Foreman was originally implemented in Ruby, but there are implementations available in Node.js, Python, and Go. In this tutorial, you’ll use the Node.js version of Foreman, which you can install globally and will let you run services written in any programming language, just like the Ruby implementation.

What You Need

  • Node.js installed on your computer, which you can do by following the Install Node.js tutorial.

Install Foreman

Installing Foreman globally lets you run it from any directory. You could install Foreman as a developer dependency in your Node.js project, but installing it globally lets you use Foreman on projects in other languages.

Open your terminal and run the following command to install this globally on your system:

npm install -g foreman

To see how Foreman works, you’ll need a couple of services you can run.

Create Services

For this demonstration, you’ll create two services: a tiny web server and a service that periodically prints a message to the console.

Create a new directory to hold the services.

mkdir foreman-demo

Switch to the directory:

cd foreman-demo

Create a file named web_server.js and add the following code that defines a basic web server running on port 4000:

const http = require('http');

const server = http.createServer((req, res) => {
  const date = new Date();
  console.log(`[${date.toISOString()}] ${req.method} ${req.url}`);

  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello, world!');
});

const PORT = 4000
server.listen(PORT, () => {
  console.log(`Server running on http://localhost:${PORT}`);
});

This code creates a web server that responds with “Hello, world!” when you access the root URL. It also logs the time and request method during the request.

Create another file called worker.js and add the following code to create a service that logs the current time to the console every second:

console.log("Worker started at " + new Date().toLocaleTimeString());
setInterval(() => {
  console.log("Worker running at " + new Date().toLocaleTimeString());
}, 10000);

With the two services defined, you can now tell Foreman how to run them. You do this by creating a Procfile, which tells Foreman the commands to run and what to call each command.

Create a file called Procfile, with no file extension, in the root of your project directory and add the following code:

web: node web_server.js
worker: node worker.js

This file tells Foreman how to start your web server and background worker processes. Each entry in the file has a label, followed by the command to execute. When the processes run, the output for each process is prefixed with these labels.

With the services defined, you can use Foreman to run them.

Run Processes with Foreman

The Node.js version of Foreman has an executable called nf, short for node-foreman. Run both processes with Foreman using the following command:

nf start

This command starts both the web server and the worker. The terminal will display logs from both processes:

5:03:51 PM web.1    |  Server running on http://localhost:4000
5:03:51 PM worker.1 |  Worker started at 5:03:51 PM
5:04:01 PM worker.1 |  Worker running at 5:04:01 PM

Open your web browser and go to http://localhost:4000. You’ll see “Hello, world!” displayed.

The log in your terminal shows the message from the web server and continues to show the worker’s log messages printing every ten seconds.

5:04:41 PM worker.1 |  Worker running at 5:04:41 PM
5:04:43 PM web.1    |  [2024-04-28T22:04:43.330Z] GET /
5:04:43 PM web.1    |  [2024-04-28T22:04:43.549Z] GET /favicon.ico
5:04:51 PM worker.1 |  Worker running at 5:04:51 PM

To stop all of the processes, press Ctrl+c.

Conclusion

Using Foreman lets you manage multiple processes without running multiple terminal windows. It’s particularly useful in development environments to mimic production setups where multiple services need to run simultaneously. This tutorial demonstrated a basic setup, but Foreman can handle much more complex configurations as needed.

You’ve installed this globally on your system, so you can use it in projects in other languages as well. You can also install a different implementation of Foreman on your system, as it will be compatible with the Profile you created.