From 702be840b494b070a539cab088150116adc7faa3 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Fri, 28 Nov 2025 16:57:31 +0100 Subject: [PATCH 1/2] Improve manual update process with better user feedback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add elapsed time tracking and time-aware status messages during updates to inform users about extended downtime. Fix variable scoping issues by properly declaring interval variables in Alpine.js component data, and add error handling for network failures during health checks. Users now see clear, reassuring messages at different stages: update progress, restart phase, and revival with elapsed time. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- resources/views/livewire/upgrade.blade.php | 69 +++++++++++++++++----- 1 file changed, 54 insertions(+), 15 deletions(-) diff --git a/resources/views/livewire/upgrade.blade.php b/resources/views/livewire/upgrade.blade.php index aa3e289b7..4063f19ef 100644 --- a/resources/views/livewire/upgrade.blade.php +++ b/resources/views/livewire/upgrade.blade.php @@ -93,6 +93,10 @@ class="w-24 dark:bg-coolgray-200 dark:hover:bg-coolgray-300">Cancel modalOpen: false, showProgress: false, currentStatus: '', + checkHealthInterval: null, + checkIfIamDeadInterval: null, + healthCheckAttempts: 0, + startTime: null, confirmed() { this.showProgress = true; this.$wire.$call('upgrade') @@ -102,43 +106,78 @@ class="w-24 dark:bg-coolgray-200 dark:hover:bg-coolgray-300">Cancel event.returnValue = ''; }); }, + getReviveStatusMessage(elapsedMinutes, attempts) { + if (elapsedMinutes === 0) { + return `Waiting for Coolify to come back online... (attempt ${attempts})`; + } else if (elapsedMinutes < 2) { + return `Waiting for Coolify to come back online... (${elapsedMinutes} minute${elapsedMinutes !== 1 ? 's' : ''} elapsed)`; + } else if (elapsedMinutes < 5) { + return `Update in progress, this may take several minutes... (${elapsedMinutes} minutes elapsed)`; + } else if (elapsedMinutes < 10) { + return `Large updates can take 10+ minutes. Please be patient... (${elapsedMinutes} minutes elapsed)`; + } else { + return `Still updating. If this takes longer than 15 minutes, please check server logs... (${elapsedMinutes} minutes elapsed)`; + } + }, revive() { - if (checkHealthInterval) return true; + if (this.checkHealthInterval) return true; + this.healthCheckAttempts = 0; + this.startTime = Date.now(); console.log('Checking server\'s health...') - checkHealthInterval = setInterval(() => { + this.checkHealthInterval = setInterval(() => { + this.healthCheckAttempts++; + const elapsedMinutes = Math.floor((Date.now() - this.startTime) / 60000); fetch('/api/health') .then(response => { if (response.ok) { this.currentStatus = - 'Coolify is back online. Reloading this page (you can manually reload if its not done automatically)...'; - if (checkHealthInterval) clearInterval( - checkHealthInterval); + 'Coolify is back online. Reloading this page in 5 seconds...'; + if (this.checkHealthInterval) { + clearInterval(this.checkHealthInterval); + this.checkHealthInterval = null; + } setTimeout(() => { window.location.reload(); }, 5000) } else { - this.currentStatus = - "Waiting for Coolify to come back from the dead..." + this.currentStatus = this.getReviveStatusMessage(elapsedMinutes, this + .healthCheckAttempts); } }) + .catch(error => { + console.error('Health check failed:', error); + this.currentStatus = this.getReviveStatusMessage(elapsedMinutes, this + .healthCheckAttempts); + }); }, 2000); }, upgrade() { - if (checkIfIamDeadInterval || this.$wire.showProgress) return true; - this.currentStatus = 'Pulling new images and updating Coolify.'; - checkIfIamDeadInterval = setInterval(() => { + if (this.checkIfIamDeadInterval || this.$wire.showProgress) return true; + this.currentStatus = 'Update in progress. Pulling new images and preparing to restart Coolify...'; + this.checkIfIamDeadInterval = setInterval(() => { fetch('/api/health') .then(response => { if (response.ok) { - this.currentStatus = "Waiting for the update process..." - } else { this.currentStatus = - "Update done, restarting Coolify & waiting until it is revived!" - if (checkIfIamDeadInterval) clearInterval( - checkIfIamDeadInterval); + "Update in progress. Pulling new images and preparing to restart Coolify..." + } else { + this.currentStatus = "Coolify is restarting with the new version..." + if (this.checkIfIamDeadInterval) { + clearInterval(this.checkIfIamDeadInterval); + this.checkIfIamDeadInterval = null; + } this.revive(); } }) + .catch(error => { + console.error('Health check failed:', error); + this.currentStatus = "Coolify is restarting with the new version..." + if (this.checkIfIamDeadInterval) { + clearInterval(this.checkIfIamDeadInterval); + this.checkIfIamDeadInterval = null; + } + this.revive(); + }); }, 2000); } From b7fcb0f362e83ec3b64c39bbfd37e5d23e40534e Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Fri, 28 Nov 2025 17:48:52 +0100 Subject: [PATCH 2/2] Fix Alpine state reference and remove unused property in upgrade modal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix incorrect Alpine state reference: Changed `this.$wire.showProgress` to `this.showProgress` in upgrade.blade.php:155 - Remove unused `$showProgress` property from Upgrade.php Livewire component - The backend property was never set or used; all progress tracking is handled by Alpine state - This fixes potential race conditions where the guard condition was not working as intended 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- app/Livewire/Upgrade.php | 2 -- resources/views/livewire/upgrade.blade.php | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/app/Livewire/Upgrade.php b/app/Livewire/Upgrade.php index e50085c64..f13baa7a7 100644 --- a/app/Livewire/Upgrade.php +++ b/app/Livewire/Upgrade.php @@ -8,8 +8,6 @@ class Upgrade extends Component { - public bool $showProgress = false; - public bool $updateInProgress = false; public bool $isUpgradeAvailable = false; diff --git a/resources/views/livewire/upgrade.blade.php b/resources/views/livewire/upgrade.blade.php index 4063f19ef..37e43935d 100644 --- a/resources/views/livewire/upgrade.blade.php +++ b/resources/views/livewire/upgrade.blade.php @@ -152,7 +152,7 @@ class="w-24 dark:bg-coolgray-200 dark:hover:bg-coolgray-300">Cancel }, 2000); }, upgrade() { - if (this.checkIfIamDeadInterval || this.$wire.showProgress) return true; + if (this.checkIfIamDeadInterval || this.showProgress) return true; this.currentStatus = 'Update in progress. Pulling new images and preparing to restart Coolify...'; this.checkIfIamDeadInterval = setInterval(() => { fetch('/api/health')