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] 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); }