From 029947c0b275b6e7ff9504b5c2a662970ecde838 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 1 Feb 2026 01:16:30 +0200 Subject: [PATCH] Fix npm cache permissions for web upgrades --- .../Commands/Jabali/UpgradeCommand.php | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/app/Console/Commands/Jabali/UpgradeCommand.php b/app/Console/Commands/Jabali/UpgradeCommand.php index b8ef3d0..2e323f7 100644 --- a/app/Console/Commands/Jabali/UpgradeCommand.php +++ b/app/Console/Commands/Jabali/UpgradeCommand.php @@ -184,6 +184,7 @@ class UpgradeCommand extends Command if ($shouldRunNpm) { try { $this->ensureCommandAvailable('npm'); + $this->ensureNpmCacheDirectory(); $npmInstall = File::exists($this->basePath.'/package-lock.json') ? 'npm ci' : 'npm install'; $installResult = $this->executeCommand($npmInstall, 1200); if ($installResult['exitCode'] !== 0) { @@ -362,6 +363,7 @@ class UpgradeCommand extends Command return [ 'PATH' => $path, 'COMPOSER_ALLOW_SUPERUSER' => '1', + 'NPM_CONFIG_CACHE' => $this->getNpmCacheDir(), ]; } @@ -423,6 +425,7 @@ class UpgradeCommand extends Command $paths = [ $this->basePath.'/database', $this->basePath.'/storage', + $this->getNpmCacheDir(), $this->basePath.'/bootstrap/cache', ]; @@ -436,6 +439,24 @@ class UpgradeCommand extends Command ]; } + protected function ensureNpmCacheDirectory(): void + { + $cacheDir = $this->getNpmCacheDir(); + if (! File::exists($cacheDir)) { + File::ensureDirectoryExists($cacheDir); + } + + if ($this->isRunningAsRoot() && $this->userExists('www-data')) { + $this->executeCommand('chgrp -R www-data '.escapeshellarg($cacheDir)); + $this->executeCommand('chmod -R g+rwX '.escapeshellarg($cacheDir)); + } + } + + protected function getNpmCacheDir(): string + { + return $this->basePath.'/storage/npm-cache'; + } + protected function commandExists(string $command): bool { $result = $this->executeCommand("command -v {$command}");