feat: rename Updaterup to Daterup and update related links and metadata

This commit is contained in:
Anders Böttcher
2026-05-13 13:57:27 +02:00
parent 37e916594e
commit b711aa510a
7 changed files with 56 additions and 55 deletions
+5 -5
View File
@@ -5,14 +5,14 @@ import { usePathname } from "next/navigation";
export default function ProductTabs() { export default function ProductTabs() {
const pathname = usePathname(); const pathname = usePathname();
const isUpdaterup = pathname.startsWith("/updaterup"); const isDaterup = pathname.startsWith("/daterup");
return ( return (
<div className="flex items-center gap-1 rounded-xl border border-white/8 bg-white/3 p-1"> <div className="flex items-center gap-1 rounded-xl border border-white/8 bg-white/3 p-1">
<Link <Link
href="/" href="/"
className={`px-4 py-1.5 rounded-lg text-sm font-semibold transition-all ${ className={`px-4 py-1.5 rounded-lg text-sm font-semibold transition-all ${
!isUpdaterup !isDaterup
? "bg-cyan-500/20 text-cyan-300 border border-cyan-500/30 shadow-sm" ? "bg-cyan-500/20 text-cyan-300 border border-cyan-500/30 shadow-sm"
: "text-slate-400 hover:text-slate-200 hover:bg-white/5" : "text-slate-400 hover:text-slate-200 hover:bg-white/5"
}`} }`}
@@ -20,14 +20,14 @@ export default function ProductTabs() {
Backerup Backerup
</Link> </Link>
<Link <Link
href="/updaterup" href="/daterup"
className={`px-4 py-1.5 rounded-lg text-sm font-semibold transition-all ${ className={`px-4 py-1.5 rounded-lg text-sm font-semibold transition-all ${
isUpdaterup isDaterup
? "bg-violet-500/20 text-violet-300 border border-violet-500/30 shadow-sm" ? "bg-violet-500/20 text-violet-300 border border-violet-500/30 shadow-sm"
: "text-slate-400 hover:text-slate-200 hover:bg-white/5" : "text-slate-400 hover:text-slate-200 hover:bg-white/5"
}`} }`}
> >
Updaterup Daterup
</Link> </Link>
</div> </div>
); );
+19 -19
View File
@@ -6,7 +6,7 @@ import { LINKS } from "@/lib/links";
export interface TerminalLinks { export interface TerminalLinks {
dockerImage?: string; dockerImage?: string;
uiPort?: string; uiPort?: string;
updaterupDockerImage?: string; daterupDockerImage?: string;
} }
interface Line { interface Line {
@@ -65,37 +65,37 @@ function buildDockerComposeLines(links: TerminalLinks): Line[] {
]; ];
} }
function buildUpdaterupRunLines(links: TerminalLinks): Line[] { function buildDaterupRunLines(links: TerminalLinks): Line[] {
const updaterupDockerImage = links.updaterupDockerImage ?? LINKS.updaterupDockerImage; const daterupDockerImage = links.daterupDockerImage ?? LINKS.daterupDockerImage;
return [ return [
{ type: "comment", text: "# Quick start: Run Updaterup directly" }, { type: "comment", text: "# Quick start: Run Daterup directly" },
{ type: "cmd", text: "docker run -d --name updaterup \\", copyable: true }, { type: "cmd", text: "docker run -d --name daterup \\", copyable: true },
{ type: "cmd-cont", text: " -p 8080:80 \\", copyable: true }, { type: "cmd-cont", text: " -p 8080:80 \\", copyable: true },
{ type: "cmd-cont", text: " -v /var/run/docker.sock:/var/run/docker.sock \\", copyable: true }, { type: "cmd-cont", text: " -v /var/run/docker.sock:/var/run/docker.sock \\", copyable: true },
{ type: "cmd-cont", text: " -v updaterup-config:/app/config \\", copyable: true }, { type: "cmd-cont", text: " -v daterup-config:/app/config \\", copyable: true },
{ type: "cmd-cont", text: ` ${updaterupDockerImage}`, copyable: true }, { type: "cmd-cont", text: ` ${daterupDockerImage}`, copyable: true },
{ type: "output", text: "b3c91d2e4f07" }, { type: "output", text: "b3c91d2e4f07" },
{ type: "success", text: "✓ Container started" }, { type: "success", text: "✓ Container started" },
{ type: "success", text: "✓ Ready at http://localhost:8080" }, { type: "success", text: "✓ Ready at http://localhost:8080" },
]; ];
} }
function buildUpdaterupComposeLines(links: TerminalLinks): Line[] { function buildDaterupComposeLines(links: TerminalLinks): Line[] {
const updaterupDockerImage = links.updaterupDockerImage ?? LINKS.updaterupDockerImage; const daterupDockerImage = links.daterupDockerImage ?? LINKS.daterupDockerImage;
return [ return [
{ type: "comment", text: "# Using docker-compose for Updaterup" }, { type: "comment", text: "# Using docker-compose for Daterup" },
{ type: "cmd", text: "cat > docker-compose.yml << 'EOF'", copyable: false }, { type: "cmd", text: "cat > docker-compose.yml << 'EOF'", copyable: false },
{ type: "output", text: "services:" }, { type: "output", text: "services:" },
{ type: "output", text: " updaterup:" }, { type: "output", text: " daterup:" },
{ type: "output", text: ` image: ${updaterupDockerImage}` }, { type: "output", text: ` image: ${daterupDockerImage}` },
{ type: "output", text: " ports:" }, { type: "output", text: " ports:" },
{ type: "output", text: " - \"8080:80\"" }, { type: "output", text: " - \"8080:80\"" },
{ type: "output", text: " volumes:" }, { type: "output", text: " volumes:" },
{ type: "output", text: " - /var/run/docker.sock:/var/run/docker.sock" }, { type: "output", text: " - /var/run/docker.sock:/var/run/docker.sock" },
{ type: "output", text: " - updaterup-config:/app/config" }, { type: "output", text: " - daterup-config:/app/config" },
{ type: "output", text: " restart: unless-stopped" }, { type: "output", text: " restart: unless-stopped" },
{ type: "output", text: "volumes:" }, { type: "output", text: "volumes:" },
{ type: "output", text: " updaterup-config:" }, { type: "output", text: " daterup-config:" },
{ type: "output", text: "EOF" }, { type: "output", text: "EOF" },
{ type: "success", text: "✓ docker-compose.yml created" }, { type: "success", text: "✓ docker-compose.yml created" },
{ type: "cmd", text: "docker compose up -d", copyable: false }, { type: "cmd", text: "docker compose up -d", copyable: false },
@@ -104,11 +104,11 @@ function buildUpdaterupComposeLines(links: TerminalLinks): Line[] {
]; ];
} }
function buildLines(mode: "docker-run" | "docker-compose" | "updaterup" | "updaterup-compose" = "docker-run", links: TerminalLinks = {}): Line[] { function buildLines(mode: "docker-run" | "docker-compose" | "daterup" | "daterup-compose" = "docker-run", links: TerminalLinks = {}): Line[] {
switch (mode) { switch (mode) {
case "docker-compose": return buildDockerComposeLines(links); case "docker-compose": return buildDockerComposeLines(links);
case "updaterup": return buildUpdaterupRunLines(links); case "daterup": return buildDaterupRunLines(links);
case "updaterup-compose": return buildUpdaterupComposeLines(links); case "daterup-compose": return buildDaterupComposeLines(links);
default: return buildDockerRunLines(links); default: return buildDockerRunLines(links);
} }
} }
@@ -142,7 +142,7 @@ function linePrompt(line: Line): string {
return ""; return "";
} }
export default function TerminalTyper({ mode = "docker-run", links = {} }: { mode?: "docker-run" | "docker-compose" | "updaterup" | "updaterup-compose"; links?: TerminalLinks } = {}) { export default function TerminalTyper({ mode = "docker-run", links = {} }: { mode?: "docker-run" | "docker-compose" | "daterup" | "daterup-compose"; links?: TerminalLinks } = {}) {
const LINES = buildLines(mode, links); const LINES = buildLines(mode, links);
const [doneLines, setDoneLines] = useState<number[]>([]); const [doneLines, setDoneLines] = useState<number[]>([]);
const [current, setCurrent] = useState<{ idx: number; chars: number } | null>({ idx: 0, chars: 0 }); const [current, setCurrent] = useState<{ idx: number; chars: number } | null>({ idx: 0, chars: 0 });
@@ -151,7 +151,7 @@ export default function TerminalTyper({ mode = "docker-run", links = {} }: { mod
const copyToClipboard = () => { const copyToClipboard = () => {
let textToCopy = ""; let textToCopy = "";
if (mode === "docker-compose" || mode === "updaterup-compose") { if (mode === "docker-compose" || mode === "daterup-compose") {
// For docker-compose, copy the YAML content only // For docker-compose, copy the YAML content only
const startIdx = LINES.findIndex(line => line.type === "output" && line.text === "services:"); const startIdx = LINES.findIndex(line => line.type === "output" && line.text === "services:");
const endIdx = LINES.findIndex((line, i) => i > startIdx && line.type === "output" && line.text === "EOF"); const endIdx = LINES.findIndex((line, i) => i > startIdx && line.type === "output" && line.text === "EOF");
@@ -8,7 +8,7 @@ import { LINKS } from "@/lib/links";
import { getLinks } from "@/lib/links-db"; import { getLinks } from "@/lib/links-db";
export const metadata: Metadata = { export const metadata: Metadata = {
title: "Updaterup — Docker Container Updates", title: "Daterup — Docker Container Updates",
description: description:
"Automated Docker container update manager. Check running containers for new image versions and update them in one click — or on a cron schedule.", "Automated Docker container update manager. Check running containers for new image versions and update them in one click — or on a cron schedule.",
}; };
@@ -112,7 +112,7 @@ const features = [
iconBg: "bg-indigo-500/10", iconBg: "bg-indigo-500/10",
iconColor: "text-indigo-400", iconColor: "text-indigo-400",
title: "Batch operations", title: "Batch operations",
body: "Check or update all containers at once with a single click. Updaterup handles each container sequentially to avoid Docker socket contention.", body: "Check or update all containers at once with a single click. Daterup handles each container sequentially to avoid Docker socket contention.",
}, },
{ {
icon: <ClockIcon />, icon: <ClockIcon />,
@@ -140,7 +140,7 @@ const steps = [
icon: <LinkIcon />, icon: <LinkIcon />,
color: "bg-violet-500/20 text-violet-400", color: "bg-violet-500/20 text-violet-400",
title: "Connect", title: "Connect",
body: "Mount the Docker socket. Updaterup auto-discovers all running containers immediately on startup.", body: "Mount the Docker socket. Daterup auto-discovers all running containers immediately on startup.",
}, },
{ {
n: "02", n: "02",
@@ -161,7 +161,7 @@ const steps = [
icon: <ArrowUpIcon />, icon: <ArrowUpIcon />,
color: "bg-indigo-500/20 text-indigo-400", color: "bg-indigo-500/20 text-indigo-400",
title: "Update", title: "Update",
body: "One click to update — Updaterup stops, removes, and recreates the container with zero config drift.", body: "One click to update — Daterup stops, removes, and recreates the container with zero config drift.",
}, },
]; ];
@@ -180,7 +180,7 @@ const stats = [
]; ];
/* ── Page ───────────────────────────────────────────────────── */ /* ── Page ───────────────────────────────────────────────────── */
export default async function UpdaterupPage() { export default async function DaterupPage() {
const links = await getLinks(); const links = await getLinks();
return ( return (
<> <>
@@ -251,7 +251,7 @@ export default async function UpdaterupPage() {
className="mx-auto mt-7 max-w-2xl text-lg leading-relaxed text-slate-400" className="mx-auto mt-7 max-w-2xl text-lg leading-relaxed text-slate-400"
style={{ animation: "slideUp 0.75s cubic-bezier(0.22,1,0.36,1) 380ms both" }} style={{ animation: "slideUp 0.75s cubic-bezier(0.22,1,0.36,1) 380ms both" }}
> >
Updaterup watches your running containers for new image versions and lets you update Daterup watches your running containers for new image versions and lets you update
them with a single click or automatically on a cron schedule. Zero config drift, them with a single click or automatically on a cron schedule. Zero config drift,
full audit history, all from a self-hosted UI. full audit history, all from a self-hosted UI.
</p> </p>
@@ -262,7 +262,7 @@ export default async function UpdaterupPage() {
style={{ animation: "slideUp 0.75s cubic-bezier(0.22,1,0.36,1) 520ms both" }} style={{ animation: "slideUp 0.75s cubic-bezier(0.22,1,0.36,1) 520ms both" }}
> >
<a <a
href={links.updaterupGitea} href={links.daterupGitea}
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
className="group flex items-center gap-2 rounded-xl px-7 py-3.5 text-sm font-bold text-white transition-all hover:brightness-110 hover:scale-105 active:scale-95 shadow-lg" className="group flex items-center gap-2 rounded-xl px-7 py-3.5 text-sm font-bold text-white transition-all hover:brightness-110 hover:scale-105 active:scale-95 shadow-lg"
@@ -281,7 +281,7 @@ export default async function UpdaterupPage() {
</svg> </svg>
</Link> </Link>
<a <a
href={links.updaterupGitea} href={links.daterupGitea}
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
className="flex items-center gap-2 rounded-xl border border-white/8 bg-white/3 px-7 py-3.5 text-sm font-semibold text-slate-300 transition-all hover:bg-white/8 hover:text-white hover:scale-105" className="flex items-center gap-2 rounded-xl border border-white/8 bg-white/3 px-7 py-3.5 text-sm font-semibold text-slate-300 transition-all hover:bg-white/8 hover:text-white hover:scale-105"
@@ -306,14 +306,14 @@ export default async function UpdaterupPage() {
<span className="h-3 w-3 rounded-full bg-red-500/70" /> <span className="h-3 w-3 rounded-full bg-red-500/70" />
<span className="h-3 w-3 rounded-full bg-yellow-500/70" /> <span className="h-3 w-3 rounded-full bg-yellow-500/70" />
<span className="h-3 w-3 rounded-full bg-emerald-500/70" /> <span className="h-3 w-3 rounded-full bg-emerald-500/70" />
<span className="ml-3 text-xs text-slate-500 font-mono tracking-wide">updaterup · quick start</span> <span className="ml-3 text-xs text-slate-500 font-mono tracking-wide">daterup · quick start</span>
<div className="ml-auto flex items-center gap-1.5"> <div className="ml-auto flex items-center gap-1.5">
<span className="w-1.5 h-1.5 rounded-full bg-violet-500 animate-pulse" /> <span className="w-1.5 h-1.5 rounded-full bg-violet-500 animate-pulse" />
<span className="text-xs text-slate-600 font-mono">live</span> <span className="text-xs text-slate-600 font-mono">live</span>
</div> </div>
</div> </div>
<div className="p-6 min-h-[260px]"> <div className="p-6 min-h-[260px]">
<TerminalTyper mode="updaterup" links={{ updaterupDockerImage: links.updaterupDockerImage }} /> <TerminalTyper mode="daterup" links={{ daterupDockerImage: links.daterupDockerImage }} />
</div> </div>
</div> </div>
</div> </div>
@@ -428,7 +428,7 @@ export default async function UpdaterupPage() {
Zero config drift, guaranteed Zero config drift, guaranteed
</h2> </h2>
<p className="mt-4 text-slate-400 leading-relaxed"> <p className="mt-4 text-slate-400 leading-relaxed">
When Updaterup recreates a container, it reads the full{" "} When Daterup recreates a container, it reads the full{" "}
<code className="font-mono text-violet-300 text-xs">docker inspect</code> output <code className="font-mono text-violet-300 text-xs">docker inspect</code> output
and rebuilds the container with the exact same configuration nothing is lost and rebuilds the container with the exact same configuration nothing is lost
or changed except the image digest. or changed except the image digest.
@@ -455,7 +455,7 @@ export default async function UpdaterupPage() {
</ul> </ul>
<div className="mt-8 flex flex-wrap gap-3"> <div className="mt-8 flex flex-wrap gap-3">
<a <a
href={links.updaterupGitea} href={links.daterupGitea}
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
className="rounded-xl px-6 py-2.5 text-sm font-bold text-white transition-all hover:brightness-110" className="rounded-xl px-6 py-2.5 text-sm font-bold text-white transition-all hover:brightness-110"
@@ -502,7 +502,7 @@ export default async function UpdaterupPage() {
Setup with docker-compose Setup with docker-compose
</h2> </h2>
<p className="text-slate-400 mb-10"> <p className="text-slate-400 mb-10">
The easiest way to get Updaterup running is with docker-compose for declarative, reproducible deployments. The easiest way to get Daterup running is with docker-compose for declarative, reproducible deployments.
</p> </p>
<div className="rounded-2xl border border-white/6 glass overflow-hidden text-left"> <div className="rounded-2xl border border-white/6 glass overflow-hidden text-left">
@@ -513,7 +513,7 @@ export default async function UpdaterupPage() {
<span className="ml-3 text-xs font-mono text-slate-500">docker-compose setup</span> <span className="ml-3 text-xs font-mono text-slate-500">docker-compose setup</span>
</div> </div>
<div className="p-6"> <div className="p-6">
<TerminalTyper mode="updaterup-compose" links={{ updaterupDockerImage: links.updaterupDockerImage }} /> <TerminalTyper mode="daterup-compose" links={{ daterupDockerImage: links.daterupDockerImage }} />
</div> </div>
</div> </div>
</div> </div>
@@ -539,11 +539,11 @@ export default async function UpdaterupPage() {
</h2> </h2>
<p className="mx-auto mt-5 max-w-xl text-lg text-slate-400"> <p className="mx-auto mt-5 max-w-xl text-lg text-slate-400">
Open source, self-hosted, and free forever. Stop manually checking for image updates Open source, self-hosted, and free forever. Stop manually checking for image updates
and let Updaterup handle it automatically. and let Daterup handle it automatically.
</p> </p>
<div className="mt-10 flex flex-wrap justify-center gap-4"> <div className="mt-10 flex flex-wrap justify-center gap-4">
<a <a
href={links.updaterupGitea} href={links.daterupGitea}
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
className="flex items-center gap-2 px-4 py-2 rounded-lg border border-white/10 bg-white/3 text-xs text-slate-400 hover:text-white hover:border-white/20 transition-all" className="flex items-center gap-2 px-4 py-2 rounded-lg border border-white/10 bg-white/3 text-xs text-slate-400 hover:text-white hover:border-white/20 transition-all"
@@ -552,7 +552,7 @@ export default async function UpdaterupPage() {
Star on Gitea Star on Gitea
</a> </a>
<a <a
href={links.updaterupGitea} href={links.daterupGitea}
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
className="rounded-xl px-7 py-3.5 text-sm font-bold text-white transition-all hover:brightness-110 hover:scale-105 active:scale-95" className="rounded-xl px-7 py-3.5 text-sm font-bold text-white transition-all hover:brightness-110 hover:scale-105 active:scale-95"
+3 -2
View File
@@ -34,8 +34,9 @@ export default function LoginForm({ from }: Props) {
setLoading(false) setLoading(false)
return return
} }
// Navigate to intended destination — fresh page load picks up the session cookie // Full page navigation — bypasses Next.js router cache so the new session
router.push(from || '/browse') // cookie is always included in the first server request after login.
window.location.href = from || '/browse'
} catch { } catch {
setError('Network error — please try again') setError('Network error — please try again')
setLoading(false) setLoading(false)
+5 -5
View File
@@ -583,7 +583,7 @@ export default async function LandingPage() {
</SpotlightCard> </SpotlightCard>
</AnimateIn> </AnimateIn>
{/* Updaterup card */} {/* Daterup card */}}
<AnimateIn variant="fade-up" delay={100}> <AnimateIn variant="fade-up" delay={100}>
<SpotlightCard className="rounded-2xl border border-violet-500/20 bg-gradient-to-br from-violet-500/10 to-purple-600/10 p-8 h-full card-hover flex flex-col"> <SpotlightCard className="rounded-2xl border border-violet-500/20 bg-gradient-to-br from-violet-500/10 to-purple-600/10 p-8 h-full card-hover flex flex-col">
<div className="flex items-start justify-between gap-4"> <div className="flex items-start justify-between gap-4">
@@ -595,7 +595,7 @@ export default async function LandingPage() {
New New
</span> </span>
</div> </div>
<h3 className="mt-5 text-xl font-bold text-white">Updaterup</h3> <h3 className="mt-5 text-xl font-bold text-white">Daterup</h3>
<p className="mt-2 text-sm text-slate-400 leading-relaxed"> <p className="mt-2 text-sm text-slate-400 leading-relaxed">
Docker container update manager. Continuously checks your running containers for Docker container update manager. Continuously checks your running containers for
new image versions and lets you update them with a single click or automatically new image versions and lets you update them with a single click or automatically
@@ -619,14 +619,14 @@ export default async function LandingPage() {
</ul> </ul>
<div className="mt-7 flex gap-3"> <div className="mt-7 flex gap-3">
<Link <Link
href="/updaterup" href="/daterup"
className="flex items-center gap-2 rounded-xl px-5 py-2.5 text-xs font-bold text-white transition-all hover:brightness-110" className="flex items-center gap-2 rounded-xl px-5 py-2.5 text-xs font-bold text-white transition-all hover:brightness-110"
style={{ background: "linear-gradient(135deg, #a78bfa, #7c3aed)" }} style={{ background: "linear-gradient(135deg, #a78bfa, #7c3aed)" }}
> >
Explore Updaterup Explore Daterup
</Link> </Link>
<a <a
href={links.updaterupGitea} href={links.daterupGitea}
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
className="flex items-center gap-2 rounded-xl border border-white/10 bg-white/5 px-5 py-2.5 text-xs font-semibold text-slate-300 hover:bg-white/10 hover:text-white transition-all" className="flex items-center gap-2 rounded-xl border border-white/10 bg-white/5 px-5 py-2.5 text-xs font-semibold text-slate-300 hover:bg-white/10 hover:text-white transition-all"
+2 -2
View File
@@ -17,8 +17,8 @@ export const LINK_META: Record<LinkKey, { label: string; description: string; gr
docs: { label: 'Backerup — Docs', description: 'Primary documentation URL', group: 'Backerup' }, docs: { label: 'Backerup — Docs', description: 'Primary documentation URL', group: 'Backerup' },
dockerImage: { label: 'Backerup — Docker image', description: 'Full image reference shown in install snippets', group: 'Backerup' }, dockerImage: { label: 'Backerup — Docker image', description: 'Full image reference shown in install snippets', group: 'Backerup' },
uiPort: { label: 'Backerup — UI port', description: 'Default port the Backerup container exposes', group: 'Backerup' }, uiPort: { label: 'Backerup — UI port', description: 'Default port the Backerup container exposes', group: 'Backerup' },
updaterupGitea: { label: 'Updaterup — Gitea repo', description: 'Repository root used in Updaterup pages', group: 'Updaterup' }, daterupGitea: { label: 'Daterup — Gitea repo', description: 'Repository root used in Daterup pages', group: 'Daterup' },
updaterupDockerImage: { label: 'Updaterup — Docker image', description: 'Full image reference shown in Updaterup install snippets', group: 'Updaterup' }, daterupDockerImage: { label: 'Daterup — Docker image', description: 'Full image reference shown in Daterup install snippets', group: 'Daterup' },
} }
export interface LinkEntry { export interface LinkEntry {
+5 -5
View File
@@ -27,11 +27,11 @@ export const LINKS = {
/** Default UI port the container exposes */ /** Default UI port the container exposes */
uiPort: "8080", uiPort: "8080",
// ── Updaterup ───────────────────────────────────────────── // ── Daterup ─────────────────────────────────────────────
/** Updaterup repository root */ /** Daterup repository root */
updaterupGitea: "https://gitea.doomlabs.de/KptltD00M/updaterup", daterupGitea: "https://gitea.doomlabs.de/KptltD00M/daterup",
/** Updaterup Docker image reference */ /** Daterup Docker image reference */
updaterupDockerImage: "gitea.doomlabs.de/kptltd00m/updaterup:latest", daterupDockerImage: "gitea.doomlabs.de/kptltd00m/daterup:latest",
} as const; } as const;
export type Links = typeof LINKS; export type Links = typeof LINKS;