diff --git a/app/views/install/installer/js/modules/progress.js b/app/views/install/installer/js/modules/progress.js index 02c1e0ef2b..8d43207662 100644 --- a/app/views/install/installer/js/modules/progress.js +++ b/app/views/install/installer/js/modules/progress.js @@ -861,6 +861,14 @@ const retryButton = event.target.closest('[data-install-retry]'); if (consoleButton) { + fetch('/install/cleanup', { + method: 'POST', + headers: withCsrfHeader({ + 'Content-Type': 'application/json' + }) + }).catch(() => {}); + + // Redirect immediately redirectToApp(); return; } diff --git a/src/Appwrite/Platform/Installer/HttpHandler.php b/src/Appwrite/Platform/Installer/HttpHandler.php index 0f610cd9c6..f3998427f1 100644 --- a/src/Appwrite/Platform/Installer/HttpHandler.php +++ b/src/Appwrite/Platform/Installer/HttpHandler.php @@ -57,6 +57,7 @@ class HttpHandler $method === 'GET' && $uri === '/install/status' => $this->handleStatusRequest($uri), $method === 'POST' && $uri === '/install/validate' => $this->handleValidateRequest($uri), $method === 'POST' && $uri === '/install/complete' => $this->handleCompleteRequest($uri), + $method === 'POST' && $uri === '/install/cleanup' => $this->handleCleanupRequest($uri), $method === 'POST' && $uri === '/install' => $this->handleInstallRequest($uri), $uri === '/' => $this->handleInstallerView($uri), default => false, @@ -239,6 +240,23 @@ class HttpHandler return true; } + private function handleCleanupRequest(string $uri): bool + { + if ($_SERVER['REQUEST_METHOD'] !== 'POST' || $uri !== '/install/cleanup') { + return false; + } + + header('Content-Type: application/json'); + $this->validateCsrf(false); + + // Remove the installer container + $container = escapeshellarg(Server::DEFAULT_CONTAINER); + @exec("docker rm -f $container >/dev/null 2>&1"); + + echo json_encode(['success' => true]); + return true; + } + private function handleInstallRequest(string $uri): bool { if ($_SERVER['REQUEST_METHOD'] !== 'POST' || $uri !== '/install') {