Risoluzione dei Problemi di Permessi su Cartelle e Processi PM2 in Linux
Quando si utilizzano applicazioni Node.js gestite da PM2, su macchine in cui accedono più utenti, è possibile imbattersi, come è capitato a me, in problemi di permessi su file e cartelle. In particolare, può accadere che un processo avviato da un utente non riesca a scrivere su una directory, nonostante l’utente appartenga apparentemente al gruppo corretto.
A volte aggiungi un utente a un gruppo, imposti i permessi corretti sulle cartelle… ma l’app continua a dare EACCES: permission denied
. Perché? Perché PM2 (o il processo che lancia) non ha aggiornato i gruppi effettivi.
In questo articolo vediamo come diagnosticare questi problemi in modo chiaro usando una semplice app Node.js e quando è necessario riavviare PM2 o l’intero sistema.
Il Cuore del Problema
Aggiungi l’utente a un gruppo ➡️ Ma non basta
- Il kernel non aggiorna i gruppi effettivi di un processo già in esecuzione.
- PM2 eredita i gruppi al momento del lancio, e li mantiene finché il processo non viene riavviato.
- A volte, solo un riavvio della macchina garantisce la ripartenza pulita di tutti i processi, specie se PM2 parte come servizio systemd.
L’Applicazione di Test dei Permessi
Creiamo una piccola app Node.js che:
- Mostra l’utente attuale e i suoi gruppi
- Controlla i permessi su una directory
- Prova a scrivere un file di test
Sorgente applicazione di test
const os = require('os');
const fs = require('fs');
const util = require('util');
const exec = util.promisify(require('child_process').exec);
const targetFolder = '/percorso/della/cartella'; // <-- personalizza qui!
const testFile = `${targetFolder}/testfile.txt`;
(async () => {
console.log('=============================');
console.log('🧑💻 User & Group Info');
console.log('=============================');
console.log(`User: ${os.userInfo().username}`);
console.log(`UID : ${process.getuid()}`);
console.log(`GID : ${process.getgid()}`);
const { stdout: groups } = await exec('id');
console.log(`Groups: ${groups.trim()}`);
console.log('\n=============================');
console.log('📁 Folder Permissions');
console.log('=============================');
const folderStats = fs.statSync(targetFolder);
console.log(`Path : ${targetFolder}`);
console.log(`Owner UID : ${folderStats.uid}`);
console.log(`Owner GID : ${folderStats.gid}`);
console.log(`Permissions : ${folderStats.mode.toString(8)}`);
console.log('\n=============================');
console.log('📝 Test Write Access');
console.log('=============================');
try {
fs.writeFileSync(testFile, `Test scritto da ${os.userInfo().username} - ${new Date().toISOString()}\n`, { flag: 'a' });
console.log(`✅ Scrittura su ${testFile} OK`);
} catch (err) {
console.error(`❌ Non riesco a scrivere su ${testFile}`);
console.error(err.message);
}
console.log('\nFINE TEST');
})();
Salva questo test file (ad esempio index.js) su una cartella dalla quale puoi lanciare i seguenti comandi:
pm2 start index.js --name testpm2perm
pm2 logs testpm2perm
Io l’ho chiamata testpm2perm, tu fai come ti pare.
Con questo software riuscite a capire se ci sono dei path che vi sono preclusi e, soprattutto, con quale utente gira pm2.
Pertanto, potreste avere dei permessi insufficienti per manipolare i files di una cartella se lanciate il programma con pm2.
Una volta reimpostati i permessi e i gruppi degli utenti, in particolare all’utente che è dietro pm2, tali da consentirgli la manipolazione dei file, potreste essere costretti a riavviare il sistema, prima di riuscire a vedere il bug risolto e il vostro software funzionare.
Quando è Necessario il Reboot?
- PM2 viene gestito da systemd e i processi non vengono aggiornati correttamente
- Il gruppo è stato aggiunto, ma il processo parte troppo presto durante il boot
- I processi sono zombie di vecchie sessioni non aggiornate
Lo script esposto in questo articolo è stato scritto con intelligenza artificiale e mi ha aiutato a risolvere una problematica reale.
Questo articolo è solo una scusa per appuntarmi questa soluzione e, perché no, renderla disponibile agli altri.