mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
fix: check health endpoint instead of awaiting service restart to fix update success status
This commit is contained in:
@@ -11,30 +11,50 @@ import {
|
||||
} from "@/components/ui/alert-dialog";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { api } from "@/utils/api";
|
||||
import { HardDriveDownload } from "lucide-react";
|
||||
import { HardDriveDownload, Loader2 } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
|
||||
interface Props {
|
||||
isNavbar?: boolean;
|
||||
}
|
||||
export const UpdateWebServer = () => {
|
||||
const [updating, setUpdating] = useState(false);
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
export const UpdateWebServer = ({ isNavbar }: Props) => {
|
||||
const { mutateAsync: updateServer, isLoading } =
|
||||
api.settings.updateServer.useMutation();
|
||||
const { mutateAsync: updateServer } = api.settings.updateServer.useMutation();
|
||||
|
||||
const buttonLabel = isNavbar ? "Update available" : "Update Server";
|
||||
|
||||
const handleConfirm = async () => {
|
||||
const checkIsUpdateFinished = async () => {
|
||||
try {
|
||||
await updateServer();
|
||||
const response = await fetch("/api/health");
|
||||
if (!response.ok) {
|
||||
throw new Error("Health check failed");
|
||||
}
|
||||
|
||||
toast.success(
|
||||
"The server has been updated. The page will be reloaded to reflect the changes...",
|
||||
);
|
||||
|
||||
setTimeout(() => {
|
||||
// Allow seeing the toast before reloading
|
||||
window.location.reload();
|
||||
}, 2000);
|
||||
} catch {
|
||||
// Delay each request
|
||||
await new Promise((resolve) => setTimeout(resolve, 2000));
|
||||
// Keep running until it returns 200
|
||||
void checkIsUpdateFinished();
|
||||
}
|
||||
};
|
||||
|
||||
const handleConfirm = async () => {
|
||||
try {
|
||||
setUpdating(true);
|
||||
await updateServer();
|
||||
|
||||
// Give some time for docker service restart before starting to check status
|
||||
await new Promise((resolve) => setTimeout(resolve, 8000));
|
||||
|
||||
await checkIsUpdateFinished();
|
||||
} catch (error) {
|
||||
setUpdating(false);
|
||||
console.error("Error updating server:", error);
|
||||
toast.error(
|
||||
"An error occurred while updating the server, please try again.",
|
||||
@@ -43,35 +63,54 @@ export const UpdateWebServer = ({ isNavbar }: Props) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<AlertDialog>
|
||||
<AlertDialog open={open}>
|
||||
<AlertDialogTrigger asChild>
|
||||
<Button
|
||||
className="relative w-full"
|
||||
variant={isNavbar ? "outline" : "secondary"}
|
||||
isLoading={isLoading}
|
||||
variant="secondary"
|
||||
onClick={() => setOpen(true)}
|
||||
>
|
||||
{!isLoading && <HardDriveDownload className="h-4 w-4" />}
|
||||
{!isLoading && (
|
||||
<span className="absolute -right-1 -top-2 flex h-3 w-3">
|
||||
<span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 opacity-75" />
|
||||
<span className="relative inline-flex rounded-full h-3 w-3 bg-green-500" />
|
||||
</span>
|
||||
)}
|
||||
{isLoading ? "Updating..." : buttonLabel}
|
||||
<HardDriveDownload className="h-4 w-4" />
|
||||
<span className="absolute -right-1 -top-2 flex h-3 w-3">
|
||||
<span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 opacity-75" />
|
||||
<span className="relative inline-flex rounded-full h-3 w-3 bg-green-500" />
|
||||
</span>
|
||||
Update Server
|
||||
</Button>
|
||||
</AlertDialogTrigger>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
|
||||
<AlertDialogTitle>
|
||||
{updating
|
||||
? "Server update in progress"
|
||||
: "Are you absolutely sure?"}
|
||||
</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
This action cannot be undone. This will update the web server to the
|
||||
new version. The page will be reloaded once the update is finished.
|
||||
{updating ? (
|
||||
<span className="flex items-center gap-1">
|
||||
<Loader2 className="animate-spin" />
|
||||
The server is being updated, please wait...
|
||||
</span>
|
||||
) : (
|
||||
<>
|
||||
This action cannot be undone. This will update the web server to
|
||||
the new version. You will not be able to use the panel during
|
||||
the update process. The page will be reloaded once the update is
|
||||
finished.
|
||||
</>
|
||||
)}
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
||||
<AlertDialogAction onClick={handleConfirm}>Confirm</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
{!updating && (
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel onClick={() => setOpen(false)}>
|
||||
Cancel
|
||||
</AlertDialogCancel>
|
||||
<AlertDialogAction onClick={handleConfirm}>
|
||||
Confirm
|
||||
</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
)}
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
);
|
||||
|
||||
@@ -359,7 +359,9 @@ export const settingsRouter = createTRPCRouter({
|
||||
|
||||
await pullLatestRelease();
|
||||
|
||||
await spawnAsync("docker", [
|
||||
// This causes restart of dokploy, thus it will not finish executing properly, so don't await it
|
||||
// Status after restart is checked via frontend /api/health endpoint
|
||||
void spawnAsync("docker", [
|
||||
"service",
|
||||
"update",
|
||||
"--force",
|
||||
|
||||
Reference in New Issue
Block a user