Commit Graph

34 Commits

Author SHA1 Message Date
Jacky
54b1f2096e Nginx-UI disk I/O (#1547)
* fix: prevent disk I/O overload from static files in nginx config directory

This fix addresses the issue where placing static asset folders (like
frontend dist folders) under the nginx config directory would cause
severe disk I/O and crash the server.

Root cause: The file watcher (fsnotify) was monitoring ALL files under
the nginx config directory, including static assets. When extracting
zip files or copying large frontend distributions, each file change
event would trigger a scan, overwhelming the system.

Changes made:
- Added more excluded directories: html, www, static, assets, public, webroot
- Added shouldWatchDirectory() to skip directories that typically contain
  static assets (dist, build, node_modules, __MACOSX, etc.)
- Added isConfigFilePath() to filter files by extension and path patterns
- Only process files that appear to be nginx config files (.conf, files
  in sites-available/sites-enabled/streams-available/streams-enabled, etc.)
- Skip files with common static asset extensions (images, scripts, styles,
  archives, etc.)

This prevents the scanner from being overwhelmed by thousands of file
events from static asset directories while still properly monitoring
actual nginx configuration files.

Fixes: disk I/O overload when static files placed in nginx config dir

Co-authored-by: Jacky <me@jackyu.cn>

* Fix path matching bugs in shouldSkipPath and shouldWatchDirectory

Fix two issues in directory/path filtering logic:

1. shouldSkipPath: Add path separator boundary check to prevent false-positive
   prefix matching. e.g., excludedDir='/etc/nginx/html' should match
   '/etc/nginx/html/file' but NOT '/etc/nginx/html-configs/file'

2. shouldWatchDirectory: Split static directory patterns into two separate
   loops - one for slash-terminated patterns (intermediate directories via
   Contains) and one for slash-prefixed patterns (directories at end of path
   via HasSuffix). This prevents false positives where '/js' would match
   '/json-schemas/' because the old code had HasSuffix || Contains which
   effectively reduced to just Contains.

* fix: use relative paths for static directory pattern matching to avoid ancestor match

- Fixed shouldWatchDirectory and isConfigFilePath to check static directory
  patterns against only the path portion relative to the nginx config root,
  not the full absolute path. This prevents false matches when the nginx
  config directory itself is under a path containing pattern names like
  /opt/vendor/nginx/conf.

- Consolidated the duplicate staticDirPatterns and staticDirSuffixes lists
  into a single staticDirNames list, reducing maintenance burden and
  ensuring consistency between Contains and HasSuffix checks.

* fix: use filepath.Separator for cross-platform path matching in static directory checks

Replace hardcoded forward slashes with filepath.Separator in shouldWatchDirectory()
and isConfigFilePath() functions to ensure proper path matching on Windows.

The shouldSkipPath() function already uses filepath.Separator correctly, but the
static directory name checks were using hardcoded '/' which would never match
on Windows where paths use '\' as separator. This would cause all directories
to be watched and all files scanned on Windows, completely disabling the static
directory filtering.

* fix: reorder static dir checks before config dir checks to prevent I/O overload

Two bugs fixed:

1. Config dir check uses full path instead of relative - isConfigFilePath now
   uses relative path for config directory pattern checks, matching the logic
   in shouldWatchDirectory. This prevents paths like /srv/conf.d/nginx/ from
   incorrectly matching all files.

2. Config dir patterns short-circuit static directory filtering - Both
   shouldWatchDirectory and isConfigFilePath now check static directory
   patterns BEFORE config directory patterns. This ensures paths like
   /etc/nginx/conf.d/myapp/node_modules/ are correctly filtered out,
   preventing the I/O overload this PR aims to prevent.

* fix: remove redundant config dir check and add path-separator boundaries

Two bugs fixed:

1. Redundant config directory check in shouldWatchDirectory - Removed the
   configDirPatterns check which was dead code since both branches returned
   true. The function now simply returns true for any directory that passes
   the static directory filter.

2. Config dir patterns lack path-separator boundary checks - Modified
   isConfigFilePath to use separator-bounded matching for config directory
   patterns (conf.d, sites-enabled, etc.) to avoid false positives like
   'myconf.db' matching 'conf.d' across the name/extension boundary.

* perf: move constant data structures to package level to avoid allocations

Move configDirPatterns, configFilePatterns, and nonConfigExtensions from
function-local variables to package-level variables. These data structures
are constant and were being allocated on every isConfigFilePath call,
which is called twice per file during batch scans and for every file event
during watching.

This change eliminates thousands of unnecessary allocations during scans,
improving performance in a PR specifically aimed at reducing resource overhead.

* fix: remove redundant HasPrefix check in isConfigFilePath

The first operand strings.HasPrefix(lowerRelativePath, sep+pattern+sep)
was dead code because the strings.Contains check above already covers
this case - if a string starts with X, it necessarily contains X.

Simplified to only check HasPrefix(lowerRelativePath, pattern+sep) which
adds meaningful coverage for paths starting with the pattern directly
after the config root.

* fix: remove dead HasPrefix branch in config dir pattern matching

The strings.HasPrefix(lowerRelativePath, pattern+sep) check was dead code
because relativePath always starts with a path separator after TrimPrefix
from a filepath.Clean'd configRoot. Since pattern values like 'sites-available'
don't start with '/', HasPrefix with 'pattern+sep' (e.g., 'sites-available/')
could never match a path starting with '/sites-available/'.

The Contains(lowerRelativePath, sep+pattern+sep) check already correctly
handles this case since it looks for '/pattern/' anywhere in the path.

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-02-07 21:38:44 +08:00
0xJacky
aec291d21e chore: update dependencies and improve component styles 2025-11-24 11:31:48 +08:00
0xJacky
9a625075f2 enhance(config-list): content filter #1413 2025-11-09 10:04:27 +00:00
0xJacky
49623c21c9 feat(scanner): enhance scanning functionality with configurable options and post-scan callbacks 2025-10-06 23:30:21 +00:00
0xJacky
9124b33cf3 feat(nginx_log): add basic log_list fallback when AdvancedIndexing is disabled
- Introduce in-memory fallback cache and simple rotation grouping
- Route AddLogPath/RemoveLogPathsFromConfig/Get* to fallback when LogFileManager is unavailable
- Preserve existing behavior when AdvancedIndexingEnabled is true
2025-10-01 04:03:59 +00:00
0xJacky
1626c6117b perf: optimize indexer config for multi-core systems 2025-09-08 09:36:07 +08:00
0xJacky
8d15d1fcab enhance(nginx_log): indexing status management 2025-08-31 08:25:51 +08:00
0xJacky
b34fa8eeaf enhance(nginx_log): indexing logic, UI feedback for log availability 2025-08-29 23:55:12 +08:00
0xJacky
4b26a559ed enhance: gracefully restart, logging, nginx_log analytics 2025-08-29 15:04:35 +08:00
0xJacky
03fbd9be4c perf: introduced cache for user, site_config, node 2025-08-25 18:50:44 +08:00
0xJacky
0ff4a6e4ed refactor: nginx log with indexer parse and search 2025-08-19 23:01:12 +08:00
0xJacky
38ee12f587 feat: add EAB supports for ACME user register #1255 2025-08-02 21:18:32 +08:00
0xJacky
39ebb729a6 enhance(cache): handle symlinks in file event handler 2025-07-27 10:30:58 +08:00
0xJacky
f67bff7a4f enhance: memory management in search indexing #1240 2025-07-19 17:13:57 +08:00
0xJacky
b8e017e715 enhance: content validation in config indexing #1240 2025-07-18 08:26:39 +08:00
Jacky
86390a5ec2 feat(kernal): add support for h2 and h3 protocols 2025-07-07 10:19:15 +08:00
Jacky
9113e82162 refactor: update upstream availability monitoring 2025-07-05 22:27:27 +08:00
Jacky
544d2badec refactor: add bleve search integration and enhance config list #1207 2025-07-05 20:37:28 +08:00
Jacky
52cf30841c refactor: simplify event bus for ws broadcasting 2025-07-05 12:22:22 +08:00
Jacky
69250a6cbe perf: reduce recursion depth #1178 2025-06-27 11:53:08 +08:00
Jacky
dd8dfe0f8b enhance: file scanning with recursion protection and abs path resolution #1178 2025-06-26 14:30:14 +00:00
Jacky
7580fa4572 feat: add proxy targets support in site and stream #904 2025-05-26 11:39:24 +08:00
Jacky
1ba1da0d5d chore: use nginx.GetConfEntryPath() #1013 2025-05-07 11:54:22 +08:00
Jacky
0162e10c53 fix: pass context to cert and cache 2025-05-05 01:36:39 +00:00
Jacky
5f0e59d095 refactor(cache): simplify event handling in file watcher and improve directory change detection 2025-05-04 03:10:37 +00:00
Jacky
f31407dd7e fix(cache): index dir 2025-04-24 08:44:30 +00:00
Jacky
269397e114 refactor: cache index 2025-04-04 02:00:18 +00:00
Jacky
56f4e5b87f enhance: nginx log 2025-04-02 19:02:38 +08:00
Jacky
ea146ca37b chore(go): update deps 2024-10-24 18:58:06 +08:00
Jacky
c5f5038d35 style(go): sort imports 2024-10-24 18:22:45 +08:00
Jacky
33a996e777 refactor: migrate to new cosy 2024-10-22 16:38:38 +08:00
Jacky
deda31a6e1 enhance: proxy settings 2024-10-07 11:07:44 +08:00
Jacky
bdfbbd0e8f feat: login via passkey 2024-09-15 20:32:03 +08:00
Jacky
3a22861640 feat: 2FA authorization for web terminal 2024-07-23 20:35:32 +08:00