Tag Archives: debian

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

How to Install MariaDB on Debian 13 (Trixie) , Root Uses Password (Debian 12-style)

To install MariaDB on Debian 13 (Trixie), follow these steps (same rhythm as my Debian 12 guide, but updated for Debian 13).

Debian 13’s repo package is currently mariadb-server (1:11.8.3-0+deb13u1). (Debian Packages)

1. Update Package Index

Start by updating the package index to ensure your system has the latest information on available packages.

sudo apt update

(Optional but recommended)

sudo apt -y upgrade
sudo reboot

2. Install MariaDB Server

Use the following command to install the MariaDB server and client:

sudo apt install mariadb-server mariadb-client -y

3. Start and Enable MariaDB Service

Once installed, start the MariaDB service and enable it to start on boot.

sudo systemctl start mariadb
sudo systemctl enable mariadb

Check status:

sudo systemctl status mariadb --no-pager

4. Secure the Installation (force root password)

To improve the security of your MariaDB server, run the security script:

sudo mariadb-secure-installation
# legacy name (still common in tutorials)
sudo mysql_secure_installation
Code language: PHP (php)

MariaDB notes that from 10.4+, unix_socket auth is commonly applied by default, so many older tutorials are outdated. In our case, we want root password, so pay attention to the prompt. (MariaDB)

During this process, you’ll be asked to:

  1. Set a root password.
  2. Remove anonymous users.
  3. Disallow root login remotely.
  4. Remove test databases.
  5. Reload privilege tables.

Important (Debian 13 / modern MariaDB prompt):
If you see:

  • Switch to unix_socket authentication [Y/n]

Answer n (NO), because you want password-based root login. (MariaDB)

Then when asked to set root password, answer Y and set a strong password.

5. Test Root Login (Password)

Verify you can login using root + password:

mariadb -u root -p

If root is already using unix_socket (fix it)

If you accidentally selected unix_socket, you can switch root back to password auth.

Login locally (this still works if socket auth is enabled):

sudo mariadb

Then run:

ALTER USER 'root'@'localhost'
  IDENTIFIED BY 'YOUR_STRONG_PASSWORD';
FLUSH PRIVILEGES;
Code language: JavaScript (javascript)

Modern MariaDB root defaults can involve socket authentication, but ALTER USER is the supported way to change credentials/auth behavior. (MariaDB)

Exit:

exit;
Code language: PHP (php)

Test again:

mariadb -u root -p

6. (Optional) Configure MariaDB

You can edit the MariaDB configuration file for additional settings if needed. The main configuration file is located at:

sudo vi /etc/mysql/mariadb.conf.d/50-server.cnf

After making changes, restart MariaDB to apply them:

sudo systemctl restart mariadb

Your MariaDB server should now be up and running on Debian 13.

Debian 13, Make Your Server Stop “Hanging” Under Load with vm.swappiness=10

If you’ve ever had a small Debian server that technically is still alive, ping works, uptime is fine, but SSH becomes painfully slow and your apps feel like they’re moving through syrup, there’s a good chance you’ve met the quiet villain, disk swap.

Linux is incredibly smart about memory management, but on machines with limited RAM (1–4GB is the usual battlefield), it can sometimes start swapping earlier than you’d expect. And the moment that swapping becomes heavy, the server can feel like it’s frozen even if the CPU isn’t maxed out.

The fix often isn’t “add more swap” or “buy more RAM” (although those help). The fix is to teach the kernel a simple preference

Use RAM first. Use swap only when it’s really needed.

That preference is controlled by a kernel parameter called

vm.swappiness

What “swappiness” really means (in human terms)

Swappiness is a number that influences how aggressively the kernel moves memory pages out of RAM and into swap space.

  • Higher value > kernel is more willing to swap
  • Lower value > kernel tries harder to keep things in RAM

Most distros default to something around 60, which is generally fine for modern machines with plenty of RAM. But for small servers, especially those running databases, Node.js apps, Strapi, queue workers, or anything with bursts of memory usage, that default can be too eager.

The classic symptom looks like this

  • your app suddenly slows down
  • SSH input lags
  • “top” shows nothing dramatic
  • disk activity spikes
  • everything feels “stuck” until it recovers

That’s why a very common, practical baseline tweak is:

Set swappiness to 10.

It doesn’t disable swap. It simply lowers the priority of swap so your server stays responsive longer.

Before changing anything, check your current state

Start by confirming your current memory and swap situation:

free -h
swapon --show
cat /proc/sys/vm/swappiness

If you see swappiness is 60, you’re looking at the common default.

Set vm.swappiness=10 (immediate effect)

To apply it right now (until the next reboot)

sudo sysctl -w vm.swappiness=10

Then confirm

cat /proc/sys/vm/swappiness

At this point, Debian 13 will behave noticeably better under memory pressure: it will try harder to keep active application memory in RAM instead of pushing it out to disk.

Make it permanent on Debian 13

A reboot will reset the value unless you persist it. The clean Debian way is to add a sysctl drop-in

echo "vm.swappiness=10" | sudo tee /etc/sysctl.d/99-swappiness.conf
sudo sysctl --system
Code language: PHP (php)

Re-check

cat /proc/sys/vm/swappiness

Done. Debian will apply this automatically on future boots.

How to tell if it’s working

The best confirmation isn’t a number, it’s behavior. Your server should remain usable longer when traffic spikes.

If you want to watch swap activity live, install sysstat and use vmstat

sudo apt install -y sysstat
vmstat 1

Look at:

  • si = swap in
  • so = swap out

Ideally, those numbers stay at 0 most of the time, occasional swap usage is normal, constant swap in/out is where performance dies.

The important nuance for small memory: don’t remove swap blindly

When people feel swap pain, the first instinct is, “Okay, no swap at all.”

On small RAM machines, that can backfire.

Swap is still useful as a safety net. Without it, when memory runs out, Linux may trigger the OOM killer and terminate processes (sometimes the wrong one). So the best balance for most small servers is

  • Keep swap enabled
  • Lower swappiness so swap becomes “last resort”

That’s exactly what vm.swappiness=10 does.

If you truly want “no disk swap” but still want safety, the modern solution is zram (compressed swap stored in RAM). That’s a separate topic, but it’s worth it for tiny VPS nodes.

Suggested values (what I actually use in practice)

  • General small server (1–4GB RAM): 10
  • Database-heavy or latency-sensitive services: 1–10 (start with 10, then test)
  • If you still see heavy swap churn: consider zram, or add RAM

No one number is perfect, but 10 is a great baseline because it reduces swap pain without turning off the safety net.

Rollback (if you need to revert)

Temporary revert to a common default:

sudo sysctl -w vm.swappiness=60

Permanent revert:

sudo rm -f /etc/sysctl.d/99-swappiness.conf
sudo sysctl --system

Cheat sheet

# Check
free -h
swapon --show
cat /proc/sys/vm/swappiness

# Set now
sudo sysctl -w vm.swappiness=10

# Persist
echo "vm.swappiness=10" | sudo tee /etc/sysctl.d/99-swappiness.conf
sudo sysctl --system

# Observe swap activity
sudo apt install -y sysstat
vmstat 1
Code language: PHP (php)

Closing thoughts

On small-memory servers, performance issues often don’t come from CPU, they come from the kernel quietly shuffling memory pages onto disk. The machine is “up”, but the experience is awful.

vm.swappiness=10 is one of those small changes that turns a fragile VPS into a predictable one: fewer freezes, better responsiveness, less panic during spikes. It’s not magic, but it’s a solid baseline, especially if you run web apps and databases on limited RAM.

Choosing Between n and nvm, The Best Node.js Version Manager for You

When working with Node.js, managing different versions efficiently is essential. Whether you’re running apps on servers or juggling multiple projects locally, a version manager simplifies your workflow.

Two of the most popular tools for this job are n and nvm. Each has its strengths, and choosing the right one depends on your environment and use case.

What Are They?

  • n: A Node.js version manager designed for simplicity. It installs and manages Node.js system-wide, making it ideal for production servers or global development environments.
  • nvm: A per-user Node.js version manager that works at the shell level. It allows you to install multiple versions of Node.js in your user directory and switch between them seamlessly.

How to Install n

n is not typically available from the default Debian repositories. To install it, use the following manual method:

# Update APT and install required build tools
sudo apt update
sudo apt install -y curl build-essential

# Set up user-level environment for n
echo 'export N_PREFIX="$HOME/.n"' >> ~/.bashrc
echo 'export PATH="$N_PREFIX/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

# Make sure ~/.n/bin exists
mkdir -p ~/.n/bin

# Download and install n to local user path
curl -L https://raw.githubusercontent.com/tj/n/master/bin/n -o ~/n
chmod +x ~/n
mv ~/n ~/.n/bin/n

# Install the latest LTS version of Node.js
n lts

# Verify the installation
n --version
node -v
which node
Code language: PHP (php)

This will install the latest LTS version of Node.js and place the n tool in your global PATH.

Once n is installed, you can begin using it to manage Node.js versions system-wide.

Key Differences

Featuren (Simple & Fast)nvm (Project-Focused)
ScopeSystem-wide (global)Per-user (local)
Ease of UseSuper fast and minimalRequires shell integration
Best ForServers, global use, simplicityDevelopers working on many projects
Project .nvmrc SupportNot built-inYes (great for per-project version pinning)
SpeedVery fast version switchingSlightly slower due to shell dependency
DependenciesNoneRequires .bashrc/.zshrc setup
Multi-user SupportYes (all users share versions)No (each user installs their own)

Why Use n?

If you’re deploying Node.js apps on a server, managing containers, or just want to get things done quickly, n is a great choice. It doesn’t require any profile modification, and switching Node versions is instant.

n 12       # Installs and switches to Node.js v12
n lts      # Switch to the latest LTS version
n latest   # Install and use the latest available Node.js
n 18       # Install Node.js v18
Code language: PHP (php)

After installation, n keeps all installed versions available. To list them:

n
# You'll get an interactive list like:
#   o 12.22.12
#     14.21.3
#     16.20.2
#   o 18.17.1
# Use up/down arrows to choose a version to activate
Code language: PHP (php)

To remove older versions and free up space:

n prune

To re-use a specific version later:

n 14

To reinstall and recompile a specific version:

n reinstall 16.20.2
Code language: CSS (css)

To install a version without switching to it:

n add 14.21.3
Code language: CSS (css)

With n, you control your environment system-wide with minimal effort — no need to tweak shell profiles or source files every time.

Why Use nvm?

For local development, especially when working on multiple projects with different Node versions, nvm shines. It supports .nvmrc files, which makes team collaboration and version consistency easier.

nvm install 18  # Installs Node.js v18
nvm use         # Uses the version specified in .nvmrc
Code language: CSS (css)

Which One Should You Choose?

  • Use n if:
    • You need to manage Node.js globally (e.g., on a server or CI/CD system).
    • You prefer simplicity and speed.
    • You’re setting up Docker or system-wide environments.
  • Use nvm if:
    • You’re working across multiple Node.js projects.
    • You want to isolate Node.js versions per user or project.
    • You rely on .nvmrc for team collaboration.

Final Thoughts

Both n and nvm are excellent tools. If you’re looking for speed and ease of use, go with n. If you need per-project flexibility and development isolation, nvm is the better choice.

For developers or sysadmins who’ve had frustrating experiences with nvm, n can feel like a breath of fresh air, quick, reliable, and easy to maintain.

Choose the one that fits your workflow and enjoy smoother Node.js development.

How to Extract and Create .tar.gz Files on Linux (Debian, Ubuntu, etc.)

If you’re working with Linux systems, you’ll frequently encounter .tar.gz files. These are compressed archive files commonly used for packaging software, backups, and configuration bundles. In this guide, we’ll explain what a .tar.gz file is, how to extract it, and how to create one safely on Linux systems like Debian or Ubuntu.

What is a .tar.gz File?

A .tar.gz file is a combination of two formats:

  • .tar: Stands for Tape Archive. It combines multiple files and directories into one file, but does not compress them.
  • .gz: Stands for Gzip. It compresses the .tar file to save space.

This results in a compressed archive: filename.tar.gz. You may also see .tgz, which is a shorthand alias for .tar.gz.

How to Extract a .tar.gz File

You can extract a .tar.gz file using the tar command, which is pre-installed on most Linux distributions.

# Basic extraction
$ tar -xzvf archive.tar.gz
Code language: PHP (php)

Explanation:

  • -x: Extract
  • -z: Use gzip to decompress
  • -v: Verbose, shows files being extracted (optional)
  • -f: Filename of the archive

Extract to a Specific Directory

If you want to extract files into a particular folder:

$ tar -xzvf archive.tar.gz -C /path/to/destination/

Extract and Change Top-Level Folder Name

Sometimes, you may want to extract the contents but rename the top-level directory in the archive. One way to do this is:

# Step 1: Create a target directory
$ mkdir new-folder

# Step 2: Extract into it
$ tar -xzvf archive.tar.gz -C new-folder/
Code language: PHP (php)

Alternatively, to restructure or rename after extraction:

$ tar -xzvf archive.tar.gz
$ mv old-folder-name new-folder-name
Code language: JavaScript (javascript)

Use --transform to Rename Folder During Extraction

If you want to rename the top-level folder directly during extraction (e.g., from example.com.v2 to example.com):

$ tar --transform='s/^example\.com\.v2/example.com/' -xzvf archive.tar.gz
Code language: JavaScript (javascript)

Make sure to match the actual top-level folder name inside the archive. Use tar -tzf archive.tar.gz to preview the folder structure before extracting.

Permission Denied or Directory Errors?

If you see errors like Cannot mkdir: Permission denied or Cannot open: No such file or directory, it usually means:

  • You don’t have write permission to the destination directory
  • You’re trying to extract into a system-owned path like /var/www without sudo

Solution:

sudo tar -xzvf archive.tar.gz -C /desired/path/

Or extract it in your home directory:

tar -xzvf archive.tar.gz -C ~/myfolder/
Code language: JavaScript (javascript)

How to Create a .tar.gz File

To create a .tar.gz file (compress a folder or multiple files):

$ tar -czvf archive.tar.gz folder_or_files

Explanation:

  • -c: Create archive
  • -z: Compress with gzip
  • -v: Verbose (optional)
  • -f: Output filename

Example: Compress a folder

$ tar -czvf backup.tar.gz myproject/

Example: Compress multiple files

$ tar -czvf images.tar.gz photo1.jpg photo2.jpg photo3.jpg

Note: Compressing already-compressed files like .jpg, .mp4, or .zip often yields minimal size reduction. Expect 0–5% savings at best.

Rename Parent Directory When Compressing

If you want the archive to extract into a renamed top-level folder:

$ cp -r original-folder temp-folder-name
$ tar -czvf renamed-folder.tar.gz temp-folder-name
$ rm -rf temp-folder-name

This way, you control the name users will see when they extract the archive.

Alternative Methods

Step-by-Step: gunzip + tar

You can also extract the archive in two steps:

$ gunzip archive.tar.gz     # Results in archive.tar
$ tar -xvf archive.tar       # Extract the tar archive
Code language: PHP (php)

Using 7-Zip

If you’re working in a GUI environment or using 7-Zip from the terminal:

$ 7z x archive.tar.gz   # Step 1: Extracts .tar
$ 7z x archive.tar      # Step 2: Extracts contents
Code language: PHP (php)

Note: Install 7-Zip on Debian/Ubuntu via: sudo apt install p7zip-full

Conclusion

The .tar.gz format is widely used in Linux environments because it bundles and compresses files efficiently. Extracting and creating these files is straightforward using the built-in tar tool, or you can use 7z for more flexibility.

If you run into permission issues, always check your destination path and consider using sudo or extracting to a user-owned directory. You can also change the folder structure or top-level folder name during or after extraction and even while compressing.

a computer screen with a program running on it

Adjust The Log Rotation Settings on Debian 12 Bookworm to Save Space

To adjust the log rotation settings on Debian 12 Bookworm to save space, you can modify the configuration in /etc/logrotate.conf or add specific configurations in the /etc/logrotate.d/ directory for individual log files. Here’s a general approach to help reduce disk usage:

  1. Reduce Retention Time: Lower the number of retained log files by changing the rotate option.
   /var/log/*.log {
       weekly
       rotate 2       # Keeps only the last 2 rotations
       compress       # Compress old logs to save space
       delaycompress  # Delays compression for one rotation
       missingok
       notifempty
       create 640 root adm
   }Code language: JavaScript (javascript)
  1. Enable Compression: If not already enabled, ensure compress is included to compress old logs, saving significant space.
  2. Limit File Size: If logs grow quickly, you can rotate them based on size.
   size 50M          # Rotate logs when they reach 50 MBCode language: PHP (php)
  1. Remove Unnecessary Logs: If specific logs are not needed, you can disable rotation for those files.

After editing, apply the settings by running:

sudo logrotate -f /etc/logrotate.conf

To compress old logs on Debian 12, you can enable compression in the logrotate configuration. Here’s how to set it up:

  1. Edit the Main Logrotate Configuration:
    Open /etc/logrotate.conf in a text editor:
   sudo nano /etc/logrotate.conf
  1. Enable Compression:
    Ensure the compress option is included in the configuration to automatically compress old logs. You might also want to use delaycompress so that the most recent rotated file remains uncompressed, in case it needs quick access.
   compress        # Compresses logs after rotation
   delaycompress   # Delays compression until the next rotationCode language: PHP (php)
  1. Configure Log Rotation in Specific Files (Optional):
    If you want to set compression for specific log files, you can add these options within individual configuration files in /etc/logrotate.d/. For example:
   /var/log/syslog {
       weekly
       rotate 4
       compress
       delaycompress
       missingok
       notifempty
       create 640 root adm
   }Code language: JavaScript (javascript)
  1. Test the Configuration:
    After making these changes, test the configuration to make sure it works as expected:
   sudo logrotate -f /etc/logrotate.conf

This will compress rotated log files, helping to save disk space on your Debian 12 system.