diff --git a/controller/internal/web/handlers.go b/controller/internal/web/handlers.go index 8c98987..888f4ef 100644 --- a/controller/internal/web/handlers.go +++ b/controller/internal/web/handlers.go @@ -1600,6 +1600,14 @@ func (s *Server) SyncFileBrowserMounts() { // Generate and write config.yaml (sources + sidebar entries per drive) configPath := stackDir + "/config.yaml" fbConfig := generateFileBrowserConfig(paths) + + // Detect if sources changed — if so, the database must be reset so + // FileBrowser picks up the new source list (user prefs cache old sources). + sourcesChanged := true + if oldConfig, err := os.ReadFile(configPath); err == nil { + sourcesChanged = string(oldConfig) != fbConfig + } + if err := os.WriteFile(configPath, []byte(fbConfig), 0644); err != nil { s.logger.Printf("[ERROR] Failed to write FileBrowser config: %v", err) return @@ -1617,6 +1625,20 @@ func (s *Server) SyncFileBrowserMounts() { return } + // If sources changed, reset database so FileBrowser re-reads config.yaml. + // The database caches user source preferences from the old config. + if sourcesChanged { + s.logger.Printf("[INFO] FileBrowser sources changed — resetting database") + resetCtx, resetCancel := context.WithTimeout(context.Background(), 30*time.Second) + defer resetCancel() + // Stop container first, then remove the data volume + stop := exec.CommandContext(resetCtx, "docker", "compose", "down", "-v") + stop.Dir = stackDir + if out, err := stop.CombinedOutput(); err != nil { + s.logger.Printf("[WARN] FileBrowser down -v: %s — %v", strings.TrimSpace(string(out)), err) + } + } + // Recreate container — H16: use 60s timeout to prevent hanging indefinitely. ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) defer cancel()