Skip to content

Commit 7fe1519

Browse files
FEATURE (installation): Add installation component
1 parent 577f297 commit 7fe1519

File tree

2 files changed

+133
-133
lines changed

2 files changed

+133
-133
lines changed
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
"use client";
2+
3+
import { useState } from "react";
4+
5+
type InstallMethod = "Automated Script" | "Docker Run" | "Docker Compose";
6+
7+
type Installation = {
8+
label: string;
9+
code: string;
10+
language: string;
11+
description: string;
12+
};
13+
14+
const installationMethods: Record<InstallMethod, Installation> = {
15+
"Automated Script": {
16+
label: "Automated script (recommended)",
17+
language: "bash",
18+
description:
19+
"The installation script will install Docker with Docker Compose (if not already installed), set up Postgresus, and configure automatic startup on system reboot.",
20+
code: `sudo apt-get install -y curl && \\
21+
sudo curl -sSL https://raw.githubusercontent.com/RostislavDugin/postgresus/refs/heads/main/install-postgresus.sh | sudo bash`,
22+
},
23+
"Docker Run": {
24+
label: "Docker",
25+
language: "bash",
26+
description:
27+
"The easiest way to run Postgresus. This single command will start Postgresus, store all data in ./postgresus-data directory, and automatically restart on system reboot.",
28+
code: `docker run -d \\
29+
--name postgresus \\
30+
-p 4005:4005 \\
31+
-v ./postgresus-data:/postgresus-data \\
32+
--restart unless-stopped \\
33+
rostislavdugin/postgresus:latest`,
34+
},
35+
"Docker Compose": {
36+
label: "Docker Compose",
37+
language: "yaml",
38+
description:
39+
"Create a docker-compose.yml file with the following configuration, then run: docker compose up -d",
40+
code: `services:
41+
postgresus:
42+
container_name: postgresus
43+
image: rostislavdugin/postgresus:latest
44+
ports:
45+
- "4005:4005"
46+
volumes:
47+
- ./postgresus-data:/postgresus-data
48+
restart: unless-stopped`,
49+
},
50+
};
51+
52+
const methods: InstallMethod[] = [
53+
"Automated Script",
54+
"Docker Run",
55+
"Docker Compose",
56+
];
57+
58+
export default function InstallationComponent() {
59+
const [selectedMethod, setSelectedMethod] =
60+
useState<InstallMethod>("Automated Script");
61+
const [copied, setCopied] = useState(false);
62+
63+
const currentInstallation = installationMethods[selectedMethod];
64+
65+
const handleMethodChange = (method: InstallMethod) => {
66+
setSelectedMethod(method);
67+
setCopied(false);
68+
};
69+
70+
const handleCopy = async () => {
71+
try {
72+
await navigator.clipboard.writeText(currentInstallation.code);
73+
setCopied(true);
74+
setTimeout(() => setCopied(false), 2000);
75+
} catch (err) {
76+
console.error("Failed to copy:", err);
77+
}
78+
};
79+
80+
return (
81+
<div className="mx-auto w-full">
82+
{/* Installation methods tabs */}
83+
<div className="mb-6 flex flex-wrap gap-2">
84+
{methods.map((method) => (
85+
<button
86+
key={method}
87+
onClick={() => handleMethodChange(method)}
88+
className={`cursor-pointer rounded-lg px-4 py-2 text-sm font-medium transition-colors md:px-6 md:py-2 md:text-base ${
89+
selectedMethod === method
90+
? "bg-blue-600 text-white"
91+
: "bg-gray-100 text-gray-700 hover:bg-gray-200"
92+
}`}
93+
>
94+
{installationMethods[method].label}
95+
</button>
96+
))}
97+
</div>
98+
99+
{/* Description */}
100+
<div className="mb-4 text-base md:text-lg max-w-[600px]">
101+
{currentInstallation.description}
102+
</div>
103+
104+
{/* Code block with copy button */}
105+
<div className="relative max-w-[600px]">
106+
<pre className="rounded-lg bg-gray-100 p-4 pr-16 text-sm">
107+
<code className="block whitespace-pre-wrap wrap-break-word">
108+
{currentInstallation.code}
109+
</code>
110+
</pre>
111+
112+
<button
113+
onClick={handleCopy}
114+
className={`absolute right-2 top-2 rounded px-2 py-1 text-xs text-white transition-colors ${
115+
copied ? "bg-green-500" : "bg-blue-600 hover:bg-blue-700"
116+
}`}
117+
>
118+
{copied ? "Copied!" : "Copy"}
119+
</button>
120+
</div>
121+
</div>
122+
);
123+
}

app/page.tsx

Lines changed: 10 additions & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { Metadata } from "next";
22
import Image from "next/image";
3-
import { CopyButton } from "./components/CopyButton";
3+
import InstallationComponent from "./components/InstallationComponent";
44

55
export const metadata: Metadata = {
66
title: "Postgresus | PostgreSQL backup",
@@ -50,28 +50,6 @@ export const metadata: Metadata = {
5050
};
5151

5252
export default function Index() {
53-
const installScript = `sudo apt-get install -y curl && \\
54-
sudo curl -sSL https://raw.githubusercontent.com/RostislavDugin/postgresus/refs/heads/main/install-postgresus.sh | sudo bash`;
55-
56-
const dockerRun = `docker run -d \\
57-
--name postgresus \\
58-
-p 4005:4005 \\
59-
-v ./postgresus-data:/postgresus-data \\
60-
--restart unless-stopped \\
61-
rostislavdugin/postgresus:latest`;
62-
63-
const dockerCompose = `version: "3"
64-
65-
services:
66-
postgresus:
67-
container_name: postgresus
68-
image: rostislavdugin/postgresus:latest
69-
ports:
70-
- "4005:4005"
71-
volumes:
72-
- ./postgresus-data:/postgresus-data
73-
restart: unless-stopped`;
74-
7553
return (
7654
<>
7755
{/* JSON-LD Structured Data */}
@@ -780,7 +758,7 @@ services:
780758
className="flex justify-center py-[50px] md:py-[100px]"
781759
>
782760
<div className="w-[320px] max-w-[320px] sm:w-[640px] sm:max-w-[640px] lg:w-[1200px] lg:max-w-[1200px]">
783-
<div className="mb-10 md:mb-20">
761+
<div className="mb-10 md:mb-10">
784762
<h2 className="text-2xl font-bold sm:text-4xl">How to install?</h2>
785763

786764
<p className="mt-5 max-w-[550px] text-base sm:text-lg">
@@ -789,116 +767,15 @@ services:
789767
</p>
790768
</div>
791769

792-
<div className="mt-20">
793-
<div className="mb-16 block xl:flex">
794-
<div className="w-full sm:pr-10 xl:w-1/2">
795-
<h3 className="mb-3 text-xl font-bold md:text-2xl">
796-
Option 1: automated installation script (recommended)
797-
</h3>
798-
799-
<p className="max-w-[500px] md:text-lg">
800-
The installation script will:
801-
<br />
802-
✅ Install Docker with Docker Compose (if not already
803-
installed)
804-
<br />
805-
✅ Set up Postgresus
806-
<br />✅ Configure automatic startup on system reboot
807-
</p>
808-
809-
<div className="relative mt-5 max-w-[550px]">
810-
<code className="block w-full overflow-x-auto whitespace-nowrap rounded-lg bg-gray-100 p-4 pr-16 text-sm">
811-
sudo apt-get install -y curl && \
812-
<br />
813-
sudo curl -sSL
814-
https://raw.githubusercontent.com/RostislavDugin/postgresus/refs/heads/main/install-postgresus.sh
815-
\ | sudo bash
816-
</code>
817-
<div className="absolute right-2 top-2">
818-
<CopyButton text={installScript} />
819-
</div>
820-
</div>
821-
</div>
822-
823-
<div className="mt-20 w-full sm:pr-10 xl:mt-0 xl:w-1/2">
824-
<h3 className="mb-3 text-xl font-bold md:text-2xl">
825-
Option 2: simple Docker run
826-
</h3>
827-
828-
<p className="max-w-[500px] md:text-lg">
829-
The easiest way to run Postgresus with embedded PostgreSQL.
830-
This single command will:
831-
<br />
832-
✅ Start Postgresus
833-
<br />
834-
✅ Store all data in ./postgresus-data directory
835-
<br />✅ Automatically restart on system reboot
836-
</p>
837-
838-
<div className="relative mt-5 max-w-[550px]">
839-
<code className="block w-full overflow-x-auto whitespace-nowrap rounded-lg bg-gray-100 p-4 pr-16 text-sm">
840-
docker run -d \
841-
<br />
842-
&nbsp;&nbsp;--name postgresus \
843-
<br />
844-
&nbsp;&nbsp;-p 4005:4005 \
845-
<br />
846-
&nbsp;&nbsp;-v ./postgresus-data:/postgresus-data \
847-
<br />
848-
&nbsp;&nbsp;--restart unless-stopped \
849-
<br />
850-
&nbsp;&nbsp;rostislavdugin/postgresus:latest
851-
</code>
852-
<div className="absolute right-2 top-2">
853-
<CopyButton text={dockerRun} />
854-
</div>
855-
</div>
856-
</div>
857-
</div>
858-
859-
<div className="block xl:flex">
860-
<div className="w-full sm:pr-10">
861-
<h3 className="mb-3 text-xl font-bold md:text-2xl">
862-
Option 3: Docker Compose setup
863-
</h3>
864-
865-
<p className="max-w-[500px] md:text-lg">
866-
Create a docker-compose.yml file with the following
867-
configuration, then run: <strong>docker compose up -d</strong>
868-
</p>
770+
<InstallationComponent />
869771

870-
<div className="relative mt-5 max-w-[550px]">
871-
<code className="block w-full overflow-x-auto whitespace-nowrap rounded-lg bg-gray-100 p-4 pr-16 text-sm">
872-
version: &quot;3&quot;
873-
<br />
874-
<br />
875-
services:
876-
<br />
877-
&nbsp;&nbsp;postgresus:
878-
<br />
879-
&nbsp;&nbsp;&nbsp;&nbsp;container_name: postgresus
880-
<br />
881-
&nbsp;&nbsp;&nbsp;&nbsp;image:
882-
rostislavdugin/postgresus:latest
883-
<br />
884-
&nbsp;&nbsp;&nbsp;&nbsp;ports:
885-
<br />
886-
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- &quot;4005:4005&quot;
887-
<br />
888-
&nbsp;&nbsp;&nbsp;&nbsp;volumes:
889-
<br />
890-
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-
891-
./postgresus-data:/postgresus-data
892-
<br />
893-
&nbsp;&nbsp;&nbsp;&nbsp;restart: unless-stopped
894-
</code>
895-
896-
<div className="absolute right-2 top-2">
897-
<CopyButton text={dockerCompose} />
898-
</div>
899-
</div>
900-
</div>
901-
</div>
772+
<div className="mt-4">
773+
<a
774+
href="/installation"
775+
className="text-blue-600 hover:text-blue-700"
776+
>
777+
Read more about installation →
778+
</a>
902779
</div>
903780
</div>
904781
</div>

0 commit comments

Comments
 (0)