Use PM2 to monitor Golang programs

A-yon
2 min readOct 5, 2023

--

I’m a long-time Node.js developer, and I love using PM2 to deploy and monitor my applications.

However, in recent months, I have had an opportunity to learn and practice Golang. It’s always a joy to learn and code in different languages, it gives me many thoughts and ideas on how to improve the design of Node.js programs too.

After a few days of learning the principles and having a prototype of the new application, I came to the place of searching for something like PM2 in the Golang ecosystem in order to better deploy and monitor the application. But with no satisfactory results. All the tools I found in Golang’s ecosystem are poorly designed compared to PM2.

Then I recall my experience of deploying Python programs via PM2, although PM2 is primarily designed for Node.js applications, it can be used for other languages with interpreters too. But what about Golang?

After giving a little thought to the way of running the program with source code: go run main.go , is a lot like an interpreter, so I decided to try it out. This is the config I used to start the Golang application in PM2:

// ecosystem.config.js
exports.apps = [
{
name: "try-go",
script: "main.go",
interpreter: "go",
interpreter_args: "run",
watch: "*.go", // auto-restart the application once the source code is changed
}
];

And it worked, all the features of PM2, such as ls, info, log, monit are working well as expected.

I did not stop here, in production, we don’t run the source code, we run the compiled program instead, which is an individual executable file, could it be run via PM2?

After trying many steps and searching some discussions on the internet, I found out that there is a hidden setting in the ecosystem.config.js file, that is we can set the value of the interpreter as none, to instruct PM2 that the program doesn’t rely on an interpreter, it can run on its own. So this is the updated version of config for production deployment:

// ecosystem.config.js
exports.apps = [
{
name: "try-go",
script: "main",
interpreter: "none", // instruct PM2 that the "script" doesn't rely on an interpreter
}
];

Again, the application and all the PM2 features are working well.

It is always good to have knowledge across different languages, we can use the tools interchangeably if we know of them.

Below is a small gRPC startup package I wrote in and for Node.js and Golang that used this technique in public, check it out if you’re interested.

PS: with this technique, PM2 can run and monitor any program written in any language.

--

--

A-yon

Full-stack developer, love building tools, believe in Buddhism. https://ayon.li