Install Node.js 24 & PM2 on Debian 13, Including Log Rotation

If you’re running Debian 13 for a production server, Node.js 24 + PM2 is a practical setup, simple deployment, easy process management, and predictable restarts.

Below is a production-friendly installation guide, including PM2 log rotation.

1. Install Node.js 24 (via NodeSource)

Update packages and install prerequisites:

sudo apt update
sudo apt install -y ca-certificates curl gnupg

Add the NodeSource GPG key:

curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key \
  | sudo gpg --dearmor -o /usr/share/keyrings/nodesource.gpg
Code language: JavaScript (javascript)

Add the Node.js 24 repository:

echo "deb [signed-by=/usr/share/keyrings/nodesource.gpg] https://deb.nodesource.com/node_24.x nodistro main" \
  | sudo tee /etc/apt/sources.list.d/nodesource.list
Code language: PHP (php)

Install Node.js:

sudo apt update
sudo apt install -y nodejs

Verify:

node -v
npm -v

2. (Optional) Install Build Tools

Some npm packages (native modules) require compilation

sudo apt install -y build-essential python3 make g++

3) Install PM2

Install PM2 globally

sudo npm install -g pm2

Verify:

pm2 -v

4. Run Your App with PM2

If your app uses npm start

cd /var/www/myapp
pm2 start npm --name "myapp" -- start
Code language: JavaScript (javascript)

Check status

pm2 status

View logs:

pm2 logs myapp

5) Install PM2 Log Rotation (pm2-logrotate)

This prevents logs from growing endlessly and filling up disk space.

Install the module, donot use ‘sudo’, because it will install and run under roor, not current user

pm2 install pm2-logrotate

Confirm it’s installed

pm2 status
pm2 show pm2-logrotate

pm2 conf pm2-logrotate

6. Recommended Log Rotation Settings (Production-Friendly)

Example: rotate when logs reach 50MB, keep 14 files, compress old logs.

pm2 set pm2-logrotate:max_size 50M
pm2 set pm2-logrotate:retain 14
pm2 set pm2-logrotate:compress true
pm2 set pm2-logrotate:dateFormat YYYY-MM-DD
pm2 set pm2-logrotate:workerInterval 30
Code language: JavaScript (javascript)

Optional: rotate on a schedule (cron). Example: rotate daily at midnight

pm2 set pm2-logrotate:rotateInterval '0 0 * * *'
Code language: JavaScript (javascript)

Restart processes to keep everything clean:

pm2 save
pm2 restart all

7) Where PM2 Stores Logs

By default, PM2 logs live here:

~/.pm2/logs/
Code language: JavaScript (javascript)

Quick check

ls -lah ~/.pm2/logs/
Code language: JavaScript (javascript)

8) Uninstall Log Rotation (If Needed)

pm2 uninstall pm2-logrotate

Debugging Slow Debian 13 on WSL, When a Single Ping Tells the Whole Story

Sometimes the simplest command reveals the truth hiding beneath the surface. My Debian 13 environment inside WSL had been unusually slow for days.

Not broken, not throwing warnings, but hanging on apt update long enough for me to lose patience.

“Reading package lists…” would freeze, repository connections took forever, and every small task felt like it was wading through molasses.

I suspected DNS, but I’ve learned not to blame DNS until I see the evidence myself. So I reached for the most basic diagnostic tool,

ping.

I started with Cloudflare’s 1.1.1.1 to see if the outbound path was clean.

PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data.
64 bytes from 1.1.1.1: time=39.1 ms
64 bytes from 1.1.1.1: time=27.7 ms
64 bytes from 1.1.1.1: time=34.9 ms
Code language: JavaScript (javascript)

Stable, no packet loss, nothing suspicious. Then I pinged the Debian Fastly mirror.

PING debian.map.fastlydns.net (***) 56(84) bytes of data.
64 bytes from ***: time=19.1 ms
64 bytes from ***: time=16.4 ms
64 bytes from ***: time=486 ms
Code language: JavaScript (javascript)

The story appears in the third packet, almost half a second of delay. That single blip told me everything that apt had been screaming silently.

The network inside the office wasn’t clean. Something,congestion, traffic shaping, SSL inspection, policy based routing, was introducing inconsistent latency.

For regular browsing nobody would notice, but package managers certainly do.

At this point the problem wasn’t Debian and it wasn’t WSL. It was the inconsistent outbound path to public mirrors.

But inconsistency doesn’t mean helplessness.

There are ways to minimize the damage, and that’s when I started adjusting the environment rather than fighting the network.

The first fix was preventing WSL from overwriting /etc/resolv.conf every time it starts.

WSL loves injecting Windows DNS resolvers, and in many corporate networks, those DNS servers are either filtered or slow.

Inside Debian I created

sudo nano /etc/wsl.conf

And added

[network]
generateResolvConf = false
Code language: JavaScript (javascript)

After shutting down WSL from Windows:

wsl --shutdown

I created my own resolver file:

sudo rm -f /etc/resolv.conf
sudo nano /etc/resolv.conf

And set Cloudflare manually:

nameserver 1.1.1.1
nameserver 1.0.0.1
options edns0
Code language: CSS (css)

Then I locked it so nothing, neither WSL nor a package, could silently revert it

sudo chattr +i /etc/resolv.conf

With DNS fixed, I turned my attention to the next silent culprit, IPv6.

Corporate networks often broadcast IPv6 routes that don’t actually work.

apt tries IPv6 first, fails silently, and gives the illusion of “stuck on reading headers.”

So I forced apt to use IPv4.

echo 'Acquire::ForceIPv4 "true";' | sudo tee /etc/apt/apt.conf.d/99force-ipv4
Code language: PHP (php)

After that, everything felt lighter. apt update flowed more smoothly, package installation no longer paused, and general network activity inside WSL became more predictable.

It didn’t magically bypass corporate constraints, but it turned an unusable system into a functional, stable environment.

What I love about this kind of debugging is how honest the system is if you listen carefully.

A single half-second ping spike can explain hours of inconsistent performance.

A resolver file quietly replaced by WSL can sabotage an entire session. An unused IPv6 route can stall apt without ever throwing an error.

All the clues were there, I just had to slow down enough to read them.

If you ever face slow Debian or Ubuntu inside WSL, especially in an office network, start simple.

Ping external DNS.

Ping your mirrors.

ook for jitter.

Then fix DNS, force IPv4, and regain control of /etc/resolv.conf.

Most of the time, the solution isn’t about changing Linux, it’s about understanding the path it must travel to reach the outside world.

And sometimes, truly, one ping is all you need to see the full picture.