Refactors generate_buildtime_environment_variables() to use an associative
array (dictionary) approach instead of sequential push() calls. This prevents
duplicate variable declarations in the buildtime.env file.
**Problem:**
After adding nixpacks plan variables to buildtime.env, the same variable
could appear twice in the file:
- Once from nixpacks plan (e.g., NIXPACKS_NODE_VERSION='22')
- Once from user-defined variables (e.g., NIXPACKS_NODE_VERSION="22")
This caused shell errors and undefined behavior during Docker builds.
**Root Cause:**
The push() method adds items sequentially without checking for duplicate
keys. When a variable existed in both nixpacks plan AND user-defined vars,
both would be written to the file.
**Solution:**
- Use associative array ($envs_dict) for automatic deduplication
- Establish clear override precedence:
1. Nixpacks plan variables (lowest priority)
2. COOLIFY_* variables (medium priority)
3. SERVICE_* variables (medium priority)
4. User-defined variables (highest priority - can override everything)
- Convert to collection format at the end
- Add debug logging when user variables override plan variables
**Benefits:**
- Automatic deduplication (array keys are unique by nature)
- User variables properly override nixpacks plan values
- Clear, explicit precedence order
- No breaking changes to existing functionality
Fixes#7114🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Wrap ActivityMonitor components in wire:ignore to prevent parent component
re-renders from destroying the Livewire component and causing "Snapshot missing"
errors in production mode.
The issue occurred when toggling the "Backup includes all databases" checkbox
during database restore operations. The checkbox uses wire:model.live which
triggers immediate parent re-renders, destroying the nested ActivityMonitor
component in the slide-over.
Changes:
- Wrap ActivityMonitor in wire:ignore div in import.blade.php
- Apply same fix preventatively to heading.blade.php
wire:ignore prevents Livewire from re-rendering the DOM inside the wrapper,
while still allowing event listeners and Alpine.js functionality to work
correctly. The existing reset logic (slideOverClosed event) continues to
function properly.
Fixes#7335🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Include 'Inject Build Args to Dockerfile' and 'Include Source Commit in Build' settings in the configuration hash calculation. These settings affect Docker build behavior, so changes to them should trigger the restart required notification. Add unit tests to verify hash changes when these settings are modified.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add endsWith() checks before appending template paths in serviceParser() to
prevent duplicate paths when parse() is called after FQDN updates. This fixes
the bug where services like Appwrite realtime would get `/v1/realtime/v1/realtime`.
Fixes#7363🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Fix sudo prefix bug: Use word boundary matching to prevent 'do' keyword from matching 'docker' commands
- Add ensureProxyNetworksExist() helper to create networks before docker compose up
- Ensure networks exist synchronously before dispatching async proxy startup to prevent race conditions
- Update comprehensive unit tests for sudo parsing (50 tests passing)
This resolves issues where Docker commands failed to execute with sudo on non-root servers and where proxy networks were not created before the proxy container started.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Reduce excessive logging in CleanupRedis and CleanupNames commands to output only a single summary line. Remove per-item logs and detailed status messages while keeping the final count of items cleaned up. Detail logs still available in dry-run mode for preview.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Replace 6 line number references in deployment-architecture.md with descriptive
method-based references that remain accurate as code evolves.
Changes:
- Section 1 (Docker Build Cache): Replaced 4 line number refs (~line 1960, ~line 2340,
~line 3358, ~line 3530) with detailed method descriptions in ApplicationDeploymentJob.php
- Section 2 (content field): Replaced "line 717" with "parseCompose() function" reference
- Section 3 (is_directory field): Replaced "line 718" with "parseCompose() function" reference
Benefits:
- Documentation remains accurate when code changes
- More informative (explains WHAT methods do, not just WHERE)
- Search-friendly (developers can find methods by name)
- Future-proof (survives refactoring and code movement)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixes issue #7346 where proxy startup failed on non-root servers due to
bash syntax errors when control structure keywords like 'for', 'do', 'done',
'break', and 'continue' were being prefixed with 'sudo'.
Added comprehensive exclusion list including for/while/until/case/select
loops, conditionals (if/then/else/elif/fi), and loop control keywords
(break/continue). Also excludes comment lines starting with '#'.
All 37 unit tests pass, including new tests for each bash control structure.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add two new application settings to control Docker build cache invalidation:
- inject_build_args_to_dockerfile (default: true) - Skip Dockerfile ARG injection
- include_source_commit_in_build (default: false) - Exclude SOURCE_COMMIT from build context
These toggles let users preserve Docker cache when SOURCE_COMMIT or custom ARGs change frequently. Development-only logging shows which ARGs are being injected for debugging.
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
Fixes issue #7348 where curl fails to follow HTTP 302 redirects from the CDN
when fetching versions.json and docker-compose files. The -L flag instructs
curl to automatically follow redirects to the final destination URL, resolving
silent installation failures.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixes the "Snapshot missing on Livewire component" error that occurs when
toggling the "Backup includes all databases" checkbox during MariaDB database
import operations.
Root Cause:
- ActivityMonitor component was initialized without proper lifecycle hooks
- When parent Import component re-rendered (via checkbox toggle), the
ActivityMonitor's Livewire snapshot became stale
- Missing null checks caused errors when querying with undefined activityId
- No state cleanup when slide-over closed, causing issues on subsequent opens
Changes:
- Add updatedActivityId() lifecycle hook to ActivityMonitor for proper hydration
- Add defensive null check in hydrateActivity() to prevent query errors
- Track activityId in Import component for state management
- Add slideOverClosed event dispatch in slide-over component
- Add event listener in Import component to reset activityId on close
Testing:
- Manually verify checkbox toggle doesn't trigger popup
- Verify actual restore operations work correctly
- Test both file-based and S3-based restore methods
- Ensure X button properly closes the modal
- Verify no console errors or Livewire warnings
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>