Addresses critical performance issues identified in code review by refactoring the monolithic CheckTraefikVersionJob into a distributed architecture with parallel processing.
Changes:
- Split version checking into CheckTraefikVersionForServerJob for parallel execution
- Extract notification logic into NotifyOutdatedTraefikServersJob
- Dispatch individual server checks concurrently to handle thousands of servers
- Add comprehensive unit tests for the new job architecture
- Update feature tests to cover the refactored workflow
Performance improvements:
- Sequential SSH calls replaced with parallel queue jobs
- Scales efficiently for large installations with thousands of servers
- Reduces job execution time from hours to minutes
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add wait loops to ensure containers are fully removed before restarting.
This fixes race conditions where docker compose would fail because an
existing container was still being cleaned up.
Changes:
- StartProxy: Add explicit stop, wait loop before docker compose up
- StopProxy: Add wait loop after container removal
- Both actions now poll up to 10 seconds for complete removal
- Add error suppression to handle non-existent containers gracefully
Tests:
- Add StartProxyTest.php with 3 tests for cleanup logic
- Add StopProxyTest.php with 4 tests for stop behavior
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit fixes a critical N+1 query issue in CheckTraefikVersionJob
that was loading ALL proxy servers into memory then filtering in PHP,
causing potential OOM errors with thousands of servers.
Changes:
- Added scopeWhereProxyType() query scope to Server model for
database-level filtering using JSON column arrow notation
- Updated CheckTraefikVersionJob to use new scope instead of
collection filter, moving proxy type filtering into the SQL query
- Added comprehensive unit tests for the new query scope
Performance impact:
- Before: SELECT * FROM servers WHERE proxy IS NOT NULL (all servers)
- After: SELECT * FROM servers WHERE proxy->>'type' = 'TRAEFIK' (filtered)
- Eliminates memory overhead of loading non-Traefik servers
- Critical for cloud instances with thousands of connected servers
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add automated Traefik version checking job running weekly on Sundays
- Implement version detection from running containers and comparison with versions.json
- Add notifications across all channels (Email, Discord, Slack, Telegram, Pushover, Webhook) for outdated versions
- Create dismissible callout component with localStorage persistence
- Display cross-branch upgrade warnings (e.g., v3.5 -> v3.6) with changelog links
- Show patch update notifications within same branch
- Add warning icon that appears when callouts are dismissed
- Prevent duplicate notifications during proxy restart by adding restarting parameter
- Fix notification spam with transition-based logic for status changes
- Enable system email settings by default in development mode
- Track last saved/applied proxy settings to detect configuration drift
Previous approach used invalid inline styles with @media queries,
which browsers ignore. Now using:
- Unique modal ID generated with PHP uniqid()
- <style> tag with proper CSS media queries
- ID selector for scoped styling
This properly constrains modal width on large screens while keeping
full width on mobile.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Tailwind JIT compiler doesn't compile dynamically interpolated classes
like lg:max-w-[{{ $maxWidth }}]. Switched to inline styles with media
queries to support dynamic min/max width values.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The previous fix reduced minWidth but modal still expanded to fit
content. Now:
- Added maxWidth prop to modal-input component (default 48rem)
- Set Edit Domains modal to minWidth=32rem, maxWidth=40rem
- This constrains the modal to a reasonable size range
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Reduced the minWidth of the Edit Domains modal from 36rem to 24rem
to provide a more compact and focused user experience. The modal
was previously too wide for the simple domain input form.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Upgrade default Traefik proxy configuration from v3.5 to v3.6, with Coolify version bump to beta.444.
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
Fixes Docker installation failures on non-root servers by properly handling
complex shell commands with pipes and operators. Previously, the sudo parser
would insert sudo throughout command chains, breaking pipe structures like
'curl URL | sh || curl URL2 | sh'.
The fix detects complex piped commands (containing '| sh', '| bash', or
pipes combined with && or || operators) and wraps them in 'sudo bash -c'
instead of inserting sudo mid-command. This preserves the command structure
and prevents syntax errors.
Changes:
- Detect complex piped commands in parseCommandsByLineForSudo
- Wrap complex commands in 'sudo bash -c' with proper quote escaping
- Preserve original behavior for simple commands
- Add 27 comprehensive unit tests covering all scenarios
Fixes#7116