fix(update): v2.7.1 avoid transient Nginx 502 error during 1-click web update

This commit is contained in:
sorcier committed 2026-11-12 11:44:10 +01:00
1 parent 64b8339d14
commit 5cb3900c67
4 files changed
+52 -24

No files matched your search

+1
View File
@@ -2621,6 +2621,7 @@ try {
break; break;
case 'run_update': case 'run_update':
@set_time_limit(300);
$output = []; $output = [];
$code = 0; $code = 0;
exec("sudo /var/www/nexus-pbx/scripts/update.sh 2>&1", $output, $code); exec("sudo /var/www/nexus-pbx/scripts/update.sh 2>&1", $output, $code);
+32 -19
View File
@@ -6412,11 +6412,29 @@ async function executeSystemUpdate() {
showToast("Mise à jour en cours d'exécution en arrière-plan...", 'info'); showToast("Mise à jour en cours d'exécution en arrière-plan...", 'info');
// Pause du polling métriques pour éviter un 502 Nginx pendant le reload php-fpm/nginx
stopMetricsPolling();
// Purge préventive du cache local // Purge préventive du cache local
localStorage.removeItem('nexus_update_last_check_ts'); localStorage.removeItem('nexus_update_last_check_ts');
localStorage.removeItem('nexus_update_cached_data'); localStorage.removeItem('nexus_update_cached_data');
function finalizeUpdateSuccess(newVer) { async function probeUpdateReady(maxAttempts = 6, delayMs = 1500) {
for (let i = 0; i < maxAttempts; i++) {
await new Promise(r => setTimeout(r, delayMs));
try {
const probeRes = await fetch('/api.php?action=check_update&_t=' + Date.now());
if (!probeRes.ok) continue;
const probeData = await probeRes.json();
if (probeData && probeData.success && probeData.current_version) {
return probeData;
}
} catch (_) {}
}
return null;
}
async function finalizeUpdateSuccess(newVer) {
newVer = String(newVer || '').replace(/^v/, ''); newVer = String(newVer || '').replace(/^v/, '');
localStorage.setItem('nexus_update_last_check_ts', Date.now().toString()); localStorage.setItem('nexus_update_last_check_ts', Date.now().toString());
localStorage.setItem('nexus_update_cached_data', JSON.stringify({ localStorage.setItem('nexus_update_cached_data', JSON.stringify({
@@ -6449,10 +6467,11 @@ async function executeSystemUpdate() {
btnModalConfirm.innerHTML = '✓ Mise à jour terminée ! Rechargement...'; btnModalConfirm.innerHTML = '✓ Mise à jour terminée ! Rechargement...';
} }
setTimeout(() => { // Attendre que le reload différé php-fpm/nginx soit terminé avant de recharger la page
await new Promise(r => setTimeout(r, 2500));
await probeUpdateReady(5, 1000);
closeUpdateConfirmModal(); closeUpdateConfirmModal();
window.location.href = window.location.origin + window.location.pathname + '?_t=' + Date.now(); window.location.href = window.location.origin + window.location.pathname + '?_t=' + Date.now();
}, 1800);
} }
try { try {
@@ -6476,18 +6495,15 @@ async function executeSystemUpdate() {
} }
// Si la réponse n'était pas un JSON valide ou a été interrompue par le rechargement de php-fpm/nginx, // Si la réponse n'était pas un JSON valide ou a été interrompue par le rechargement de php-fpm/nginx,
// on sonde le serveur pour vérifier si la mise à jour a en réalité bien été appliquée sur le disque // on sonde le serveur à plusieurs reprises pour laisser Nginx/PHP-FPM terminer leur reload
await new Promise(r => setTimeout(r, 2000)); const probeData = await probeUpdateReady(6, 1500);
try { if (probeData) {
const probeRes = await fetch('/api.php?action=check_update&_t=' + Date.now()); await finalizeUpdateSuccess(probeData.current_version);
const probeData = await probeRes.json();
if (probeData && probeData.success && probeData.current_version) {
finalizeUpdateSuccess(probeData.current_version);
return; return;
} }
} catch (_) {}
// En cas d'échec réel avéré // En cas d'échec réel avéré
startMetricsPolling();
closeUpdateConfirmModal(); closeUpdateConfirmModal();
const errMsg = (data && (data.output || data.message)) ? (data.output || data.message) : (rawText.slice(0, 150) || "Erreur inconnue"); const errMsg = (data && (data.output || data.message)) ? (data.output || data.message) : (rawText.slice(0, 150) || "Erreur inconnue");
alert("Erreur lors de la mise à jour :\n\n" + errMsg); alert("Erreur lors de la mise à jour :\n\n" + errMsg);
@@ -6503,17 +6519,14 @@ async function executeSystemUpdate() {
} catch (e) { } catch (e) {
// En cas d'interruption réseau du socket (Safari WebKit DOMException ou timeout), // En cas d'interruption réseau du socket (Safari WebKit DOMException ou timeout),
// on vérifie avant d'alerter si le serveur a quand même réussi à déployer les fichiers // on vérifie à plusieurs reprises si le serveur a quand même réussi à déployer les fichiers
await new Promise(r => setTimeout(r, 2000)); const probeData = await probeUpdateReady(6, 1500);
try { if (probeData) {
const probeRes = await fetch('/api.php?action=check_update&_t=' + Date.now()); await finalizeUpdateSuccess(probeData.current_version);
const probeData = await probeRes.json();
if (probeData && probeData.success && probeData.current_version) {
finalizeUpdateSuccess(probeData.current_version);
return; return;
} }
} catch (_) {}
startMetricsPolling();
closeUpdateConfirmModal(); closeUpdateConfirmModal();
alert("Erreur réseau lors de la mise à jour : " + (e.message || "Connexion interrompue")); alert("Erreur réseau lors de la mise à jour : " + (e.message || "Connexion interrompue"));
if (btnRun) { if (btnRun) {
+11 -4
View File
@@ -261,7 +261,7 @@ if [ -t 1 ]; then
systemctl reload nginx 2>/dev/null || true systemctl reload nginx 2>/dev/null || true
fail2ban-client reload >/dev/null 2>&1 || true fail2ban-client reload >/dev/null 2>&1 || true
else else
(nohup bash -c "sleep 2 && (systemctl reload php8.4-fpm 2>/dev/null || systemctl reload php8.2-fpm 2>/dev/null || systemctl reload php*-fpm 2>/dev/null || true); systemctl reload nginx 2>/dev/null || true; fail2ban-client reload >/dev/null 2>&1 || true" >/dev/null 2>&1 &) (nohup bash -c "sleep 1 && (systemctl reload php8.4-fpm 2>/dev/null || systemctl reload php8.2-fpm 2>/dev/null || systemctl reload php*-fpm 2>/dev/null || true); systemctl reload nginx 2>/dev/null || true; fail2ban-client reload >/dev/null 2>&1 || true" </dev/null >/dev/null 2>&1 &)
fi fi
NEW_VER="Inconnue" NEW_VER="Inconnue"
@@ -279,11 +279,18 @@ echo ""
if [ -f "$APP_DIR/version.json" ]; then if [ -f "$APP_DIR/version.json" ]; then
echo -e "${C_CYAN}${C_BOLD}Nouveautés de cette version :${C_RESET}" echo -e "${C_CYAN}${C_BOLD}Nouveautés de cette version :${C_RESET}"
php -r ' php -r '
$v = json_decode(file_get_contents("/var/www/nexus-pbx/version.json"), true); $v = json_decode(@file_get_contents("/var/www/nexus-pbx/version.json"), true);
if (!empty($v["changelog"])) { if (!empty($v["changelog"]) && is_array($v["changelog"])) {
foreach ($v["changelog"] as $line) { $first = $v["changelog"][0];
if (is_array($first) && !empty($first["changes"])) {
foreach ($first["changes"] as $line) {
echo " • " . $line . "\n"; echo " • " . $line . "\n";
} }
} else {
foreach ($v["changelog"] as $line) {
if (is_string($line)) echo " • " . $line . "\n";
}
}
} }
' '
fi fi
+8 -1
View File
@@ -1,9 +1,16 @@
{ {
"version": "2.7.0", "version": "2.7.1",
"codename": "Pulsar UCP", "codename": "Pulsar UCP",
"release_date": "2026-11-12", "release_date": "2026-11-12",
"min_php_version": "8.2", "min_php_version": "8.2",
"changelog": [ "changelog": [
{
"version": "2.7.1",
"date": "2026-11-12",
"changes": [
"Mise à jour 1-Clic : Suppression de l'erreur Nginx 502 transitoire après mise à jour (pause du polling métriques, attente du reload PHP-FPM/Nginx avec sonde multi-essais avant rechargement de la page, fermeture stdin dans update.sh)"
]
},
{ {
"version": "2.7.0", "version": "2.7.0",
"date": "2026-11-12", "date": "2026-11-12",