- Fix null-safe operator on currentTeam() call in Upgrade.php
- Add --rm flag to docker run in upgrade.sh for cleanup consistency
- Store beforeunload handler as named reference and clean up on success
- Add clarifying comments for upgrade method calls
- Add error state handling with close option in upgrade modal
- Add step mapping documentation comment in upgrade-progress component
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove /api/upgrade-status endpoint and route
- Add getUpgradeStatus() method to Upgrade Livewire component
- Update frontend to call Livewire method via $wire.getUpgradeStatus()
- Simpler approach: no separate API, auth handled by Livewire
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add auth:sanctum middleware to /api/upgrade-status route
- Check user belongs to root team (id 0) before returning status
- Return 403 if user is not authorized
- Update frontend to send credentials with fetch request
- Update OpenAPI docs with 401/403 responses
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- upgrade.sh now writes status to /data/coolify/source/.upgrade-status
- New /api/upgrade-status endpoint reads status file for real progress
- Frontend polls status API instead of simulating progress
- Falls back to health check when service goes down during restart
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove changelog preview section to streamline the UI
- Simplify warning message
- Add reference to upgrade logs location on server
- Minor formatting improvements
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Add step-by-step progress indicator (Preparing → Helper → Image → Restart)
- Display elapsed time during upgrade (MM:SS format)
- Show version transition in header (v4.0.0-beta.454 → v4.0.0-beta.456)
- Add expandable changelog preview before upgrading
- Reduce reload delay from 5s to 3s with countdown timer
- Add "Reload Now" button to skip countdown
- Improve status messages with step-specific descriptions
- Add success state with clear indication when upgrade completes
- Create new upgrade-progress component for visual step tracking
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
OAuth users don't have passwords set, so they should not be prompted for password confirmation when performing destructive actions. This fix:
- Detects OAuth users via the hasPassword() method
- Skips password confirmation in modal for OAuth users
- Keeps text name confirmation as the final step
- Centralizes logic in helper functions for maintainability
- Changes button text to "Confirm" when password step is skipped
Fixes#4457🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Update tooltip text to correctly show that the maximum execution time is 36000 seconds (10 hours) instead of 3600 seconds. The validation already allowed up to 36000 seconds, but the UI was displaying incorrect information.
🤖 Generated with Claude Code
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Allow manually-added servers to be linked to Hetzner Cloud instances by
matching IP address. Once linked, servers gain power controls and status
monitoring.
Changes:
- Add getServers() and findServerByIp() methods to HetznerService
- Add Hetzner linking UI section to Server General page
- Add unit tests for new HetznerService methods
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add isServiceResource() and shouldBeReadOnlyInUI() to LocalFileVolume
- Update path matching to handle leading slashes in volume comparisons
- Update FileStorage and Show components to use shouldBeReadOnlyInUI()
- Show consolidated warning message for service/compose resources in all.blade.php
- Remove redundant per-volume warnings for service resources
- Clean up configuration.blade.php formatting
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fixed isReadOnlyVolume() to detect both short-form (:ro) and long-form (read_only: true) Docker Compose volume syntax
- Fixed path matching to use mount_path only (fs_path is transformed during parsing from ./file to absolute path)
- Added "Load from server" button for read-only volumes to allow users to refresh content
- Changed loadStorageOnServer() authorization from 'update' to 'view' since loading is a read operation
- Added helper text to Content field warning users that content may be outdated
- Applied fixes to both LocalFileVolume and LocalPersistentVolume models
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The option is now always visible for git-based applications but only editable when Preview Deployments are enabled. This allows users to understand and configure the public PR deployment setting regardless of preview deployment status.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Replace client-side JavaScript URL checking with Laravel's routeIs() for determining when to reduce indicator opacity. This simplifies the code and uses route names as the source of truth.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Reduce deployment logs max-height from 40rem to 30rem to prevent overlap with deployments indicator
- Add conditional opacity (60%) to deployments indicator on deployment pages only (100% on other pages)
- Indicator becomes fully visible on hover or when expanded
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Removed auto-disable behaviors that caused follow logs to stop unexpectedly:
- Removed scroll detection that disabled following when user scrolled >50px from bottom
- Removed fullscreen exit handler that disabled following
- Removed ServiceChecked event listener that caused unnecessary flickers
Follow logs now only stops when:
- User explicitly clicks the Follow Logs button
- Deployment finishes (auto-scrolls to end first, then disables after 500ms delay)
Also improved get-logs component with memory optimizations:
- Limited display to last 2000 lines to prevent memory exhaustion
- Added debounced search (300ms) and scroll handling (150ms)
- Optimized DOM rendering
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Change empty state message from "Refresh to get the logs..." to "No logs yet." with proper styling
- Auto-fetch logs when expanding containers by passing refresh=true to getLogs()
- Ensure fullscreen mode covers entire viewport with solid background by overriding x-collapse styles
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add visibility API handling to pause heartbeat monitoring when the browser tab is hidden, preventing false disconnection timeouts. When the tab becomes visible again, verify the connection is still alive or attempt reconnection.
Also remove the ApplicationStatusChanged event listener that was triggering terminal reloads whenever any application status changed across the team.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The {{port}} template variable was undocumented and caused a double port bug
when used in preview URL templates. Since ports are always appended to the final
URL anyway, we remove {{port}} substitution entirely and ensure consistent port
handling across ApplicationPreview, PreviewsCompose, and the applicationParser helper.
Also fix PreviewsCompose.php which wasn't preserving ports at all, and improve
the Blade template formatting in previews-compose.blade.php.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Initialize logsLoaded as false to ensure init() triggers log loading
- Set logsLoaded=true after calling getLogs() in init()
- Allow services/PRs to load logs automatically when expandByDefault=true (single container)
- Previously, services would skip initial load unless refresh=true, now single containers work
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Adds a new server-level setting that allows administrators to disable
per-application image retention globally for all applications on a server.
When enabled, Docker cleanup will only keep the currently running image
regardless of individual application retention settings.
Changes:
- Add migration for disable_application_image_retention boolean field
- Update ServerSetting model with cast
- Add checkbox in DockerCleanup page (Advanced section)
- Modify CleanupDocker action to check server-level setting
- Update Rollback page to show warning and disable inputs when server
retention is disabled
- Add helper text noting server-level override capability
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Existing Docker Compose deployments may have 'latest' or custom tags
that aren't valid git commit SHAs. When rollback is triggered with these
tags, the deployment fails because the system tries to use the tag as a
git commit reference.
This change:
- Detects if image tag is a valid commit SHA or PR tag
- Disables rollback button for non-commit tags with helpful tooltip
- Displays appropriate label (SHA/PR/Tag) based on tag type
- Guides users to re-deploy to create rollback-enabled images
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implement a per-application setting (`docker_images_to_keep`) in `application_settings` table to control how many Docker images are preserved during cleanup. The cleanup process now:
- Respects per-application retention settings (default: 2 images)
- Preserves the N most recent images per application for easy rollback
- Always deletes PR images and keeps the currently running image
- Dynamically excludes application images from general Docker image prune
- Cleans up non-Coolify unused images to prevent disk bloat
Fixes issues where cleanup would delete all images needed for rollback.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add color toggle button (paint brush icon) to runtime logs toolbar
- Color log lines by level: error (red), warning (yellow), debug (purple), info (blue)
- Store color preference in localStorage ('coolify-color-logs')
- Widen Lines input from w-24 to w-32 for better usability
- Remove color features from deployment logs (keeping it cleaner)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added a new `collapsible` property to GetLogs component that allows disabling the expandable header, useful for log viewers in dedicated pages and slide-overs. Applied this to Sentinel logs, Proxy logs, and Coolify Proxy log pages. Also improved the toolbar by moving the lines counter to the left side with an inline prefix label and repositioning the match counter next to it for better organization.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Replace text "Documentation" links with SVG icons positioned in top-right corner, matching the established design pattern used in the service list. Update all four PostgreSQL type options: PostgreSQL 17, Supabase, PostGIS, and PGVector.
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
- Add configurable deployment_queue_limit server setting (default: 25)
- Check queue size before accepting new deployments
- Return 429 status for webhooks/API when queue is full (allows retry)
- Show error toast in UI when queue limit reached
- Add UI control in Server Advanced settings
Fixes#6708🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Updated the timestamp rendering condition to check both $timestamp and $showTimeStamps, ensuring the "Toggle Timestamps" button properly controls timestamp visibility in the log viewer.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added maximum iteration limit (maxIterations = 3) to the decodeHtml function to prevent potential DoS attacks from deeply nested HTML entities. This matches the implementation in deployment/show.blade.php and ensures the function cannot be exploited for excessive CPU usage.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Moved .log-highlight styles from Livewire component views to resources/css/app.css for better separation of concerns and reusability. This follows Laravel and Livewire best practices by keeping styles in the appropriate location rather than inline in component views.
Changes:
- Added .log-highlight styles to resources/css/app.css
- Removed inline <style> tags from deployment/show.blade.php
- Removed inline <style> tags from get-logs.blade.php
- Added XSS security test for log viewer
- Applied code formatting with Laravel Pint
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Features:
- Add client-side search filtering for runtime and deployment logs
- Add log download functionality (respects search filters)
- Make runtime log sections collapsible by default
- Auto-expand single container and lazy load logs on first expand
- Match deployment and runtime log view heights (40rem)
- Add debug toggle for deployment logs
- Improve scroll behavior with follow logs feature
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
The guard was setting and immediately resetting the flag in the same
synchronous execution, providing no actual protection. Now the flag
stays true until proxy reaches a stable state (running/exited/error)
via WebSocket notification, with additional client-side guard.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
When restarting the proxy on localhost (server id 0), shows a warning
banner in the logs sidebar explaining that the connection may be
temporarily lost and to refresh the browser if logs stop updating.
Also cleans up notification noise by commenting out intermediate
status notifications (restarting, starting, stopping) that were
redundant with the visual status indicators.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Apply the same frontend path normalization pattern from commit f6398f7cf
to the General Settings page for consistency across all forms.
Changes:
- Add Alpine.js path normalization to Docker Compose section (base directory + compose location)
- Add Alpine.js path normalization to non-Docker Compose section (base directory + dockerfile location)
- Change wire:model to wire:model.defer to prevent backend requests during tab navigation
- Add @blur event handlers for immediate path normalization feedback
- Backend normalization remains as defensive fallback
This ensures consistent validation behavior and fixes potential tab focus
issues on the General Settings page.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Change wire:model.blur to wire:model.defer to prevent backend requests
during form navigation. Add Alpine.js path normalization functions that
run on blur, fixing tab focus issues while keeping path validation
purely on the frontend.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>