- Introduce `cache-configuration.md` for detailed instructions on cache setup, permission troubleshooting, and best practices. - Add `cache-permissions-quick-fix.md` for concise resolutions to common permission errors. - Include a detailed `FILECACHE_PERMISSION_FIX_PLAN.md` outlining solutions for permission-related issues. - Enhance `docker-entrypoint.sh` with permission fixes for multi-user caches. - Update `Makefile` with cache clear commands for local and staging environments. - Improve `FileCache` for graceful degradation on permission errors, ensuring reliability under multi-user scenarios.
6.6 KiB
FileCache Permission Problem - L?sungsplan
Problem-Analyse
Fehler
PHP Fatal error: Uncaught App\Framework\Filesystem\Exceptions\FilePermissionException [FS007]:
Permission denied for delete on file: var/www/html/storage/cache/8993618a07a0f5ee371a4d3b029abf09_1762296020.cache.php
(File is not writable)
Root Cause
-
Bug in
FileStorage::delete()(Zeile 222):- Die Methode pr?ft
is_writable($resolvedPath)auf die Datei selbst - FALSCH: F?r das L?schen einer Datei braucht man nur Schreibrechte im Verzeichnis, nicht auf der Datei selbst!
- Unix-Regel:
unlink()ben?tigt nur Schreibrechte im Parent-Verzeichnis
- Die Methode pr?ft
-
Cache-Dateien werden mit 0644 erstellt:
- Owner:
rw-(read-write) - Group:
r--(read-only) - Others:
r--(read-only) - Problem: Wenn verschiedene Prozesse/User Dateien erstellen, k?nnen sie Dateien des anderen nicht l?schen (Owner-Mismatch)
- Owner:
-
Staging-Server Infrastruktur:
- M?glicherweise werden Cache-Dateien von verschiedenen Usern/Prozessen erstellt
- PHP-Prozess l?uft als anderer User als der, der die Dateien erstellt hat
L?sungsplan
L?sung 1: Bug-Fix in FileStorage::delete() (H?CHSTE PRIORIT?T)
Problem: Falsche Pr?fung - Datei muss nicht beschreibbar sein zum L?schen
Fix: Entferne is_writable() Pr?fung auf die Datei selbst
public function delete(string $path): void
{
$resolvedPath = $this->resolvePath($path);
// ... existing validation ...
if (! is_file($resolvedPath)) {
throw new FileNotFoundException($path);
}
// Pr?fe Directory-Permissions (DAS IST WICHTIG!)
$dir = dirname($resolvedPath);
if (! is_writable($dir)) {
throw FilePermissionException::delete($path, 'Directory is not writable: ' . $dir);
}
// ENTFERNT: Pr?fe File-Permissions
// F?r unlink() braucht man nur Verzeichnis-Rechte!
// if (! is_writable($resolvedPath)) {
// throw FilePermissionException::delete($path, 'File is not writable');
// }
if (! @unlink($resolvedPath)) {
$error = error_get_last();
if ($error && str_contains($error['message'], 'Permission denied')) {
throw FilePermissionException::delete($path, $error['message']);
}
throw new FileDeleteException($path);
}
// ... logging ...
}
Warum: Unix unlink() ben?tigt nur Schreibrechte im Parent-Verzeichnis, nicht auf der Datei selbst.
L?sung 2: Graceful Degradation in FileCache (HOHE PRIORIT?T)
Problem: FileCache wirft Fatal Error bei Permission-Exceptions
Fix: Catch FilePermissionException in FileCache-Methoden
Betroffene Stellen:
getSingleKey()- beim L?schen abgelaufener Dateienset()- beim L?schen alter Cache-Dateienforget()- beim expliziten L?schenclear()- beim L?schen aller Cache-Dateien
Implementierung:
// In getSingleKey()
if ($expiresAt > 0 && $expiresAt < time()) {
try {
$this->fileSystem->delete($fullPath);
} catch (\App\Framework\Filesystem\Exceptions\FilePermissionException $e) {
// Permission denied - continue (graceful degradation)
// Datei wird beim n?chsten Cleanup gel?scht
continue;
} catch (\Throwable $e) {
// Other errors - continue
continue;
}
}
// In set(), forget(), clear() - ?hnlich
Vorteil: Cache funktioniert weiter, auch wenn einzelne Dateien nicht gel?scht werden k?nnen.
L?sung 3: Optionale Auto-Fix vor L?schen (NIEDRIGE PRIORIT?T)
Option: Versuche Berechtigungen zu fixen, bevor gel?scht wird
Implementierung:
private function tryDeleteWithFix(string $path): bool
{
try {
$this->fileSystem->delete($path);
return true;
} catch (\App\Framework\Filesystem\Exceptions\FilePermissionException $e) {
// Versuche Berechtigungen zu fixen
try {
// Versuche chmod auf 0644 (falls m?glich)
@chmod($path, 0644);
// Versuche erneut zu l?schen
$this->fileSystem->delete($path);
return true;
} catch (\Throwable $e2) {
// Auto-fix fehlgeschlagen
return false;
}
}
}
Warnung: Funktioniert nur, wenn der Prozess Owner oder root ist. Sonst wird chmod() fehlschlagen.
L?sung 4: Infrastruktur-Fix f?r Staging (MITTEL PRIORIT?T)
Problem: Cache-Dateien werden von verschiedenen Usern/Prozessen erstellt
L?sungen:
Option A: Fix Berechtigungen im Entrypoint-Script
# In docker/php/docker-entrypoint.sh
# Nach Volume-Mounting:
chown -R appuser:appuser /var/www/html/storage/cache 2>/dev/null || true
chmod -R 775 /var/www/html/storage/cache 2>/dev/null || true
Option B: Fix Berechtigungen bei Cache-Erstellung
// In FileStorage::put() - nach dem Schreiben
// Stelle sicher, dass Owner/Group korrekt ist
if (function_exists('posix_geteuid')) {
$currentUid = posix_geteuid();
@chown($resolvedPath, $currentUid);
}
Option C: Verwendung von Group-Writable Permissions
// In FileStorage::put() - statt 0644
$this->permissions->setPermissions(
$path,
ValueObjects\FilePermissions::readWriteOwnerReadGroupWritable() // 0664
);
Empfehlung: Option A + Option C kombiniert
Implementierungsreihenfolge
-
? L?sung 1 (Bug-Fix) - SOFORT
- Behebt das Hauptproblem
- Semantisch korrekt (Unix-Verhalten)
-
? L?sung 2 (Graceful Degradation) - SOFORT
- Verhindert Fatal Errors
- Cache bleibt funktionsf?hig
-
?? L?sung 4 (Infrastruktur) - NACH Code-Fix
- Verhindert zuk?nftige Probleme
- Dokumentiere in
docs/deployment/
-
?? L?sung 3 (Auto-Fix) - NUR WENN N?TIG
- Kann Probleme verschlimmern, wenn nicht richtig implementiert
- Nur verwenden, wenn L?sungen 1+2+4 nicht ausreichen
Testing
Nach Implementierung testen:
- Unit-Test:
delete()sollte funktionieren, auch wenn Datei nicht beschreibbar ist - Integration-Test: FileCache sollte funktionieren, auch wenn einige Dateien nicht gel?scht werden k?nnen
- Staging-Test: Cache-Operationen sollten keine Fatal Errors mehr werfen
Dokumentation
? Dokumentation erstellt:
- ?
docs/deployment/cache-configuration.md- Vollst?ndige Cache-Konfigurations-Dokumentation docs/claude/error-handling.md- Cache-specific error handling (optional)
Status
? L?sung 1: Bug-Fix in delete() - IMPLEMENTIERT
? L?sung 2: Graceful Degradation in FileCache - IMPLEMENTIERT
? L?sung 4: Infrastruktur-Dokumentation - IMPLEMENTIERT
?? L?sung 3: Auto-Fix mit chmod() - NUR WENN N?TIG