Upload release asset: installation-guide.html
Browse files- installation-guide.html +1213 -0
installation-guide.html
ADDED
|
@@ -0,0 +1,1213 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="ko" data-theme="dark">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<title id="html-title">CertBridge ์ค์น ๊ฐ์ด๋</title>
|
| 7 |
+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Outfit:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
| 8 |
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
| 9 |
+
<style>
|
| 10 |
+
/* โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 11 |
+
CertBridge Guide Design System
|
| 12 |
+
Dual Theme Sync (Light + Dark)
|
| 13 |
+
Premium Modern Style
|
| 14 |
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ */
|
| 15 |
+
* {
|
| 16 |
+
margin: 0;
|
| 17 |
+
padding: 0;
|
| 18 |
+
box-sizing: border-box;
|
| 19 |
+
transition: background-color 0.25s ease, border-color 0.25s ease, color 0.25s ease;
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
:root {
|
| 23 |
+
/* Light Theme (Default) */
|
| 24 |
+
--bg-primary: #ffffff;
|
| 25 |
+
--bg-secondary: #f8fafc;
|
| 26 |
+
--bg-card: #ffffff;
|
| 27 |
+
--bg-glass: rgba(0, 0, 0, 0.015);
|
| 28 |
+
--bg-hover: rgba(0, 0, 0, 0.025);
|
| 29 |
+
|
| 30 |
+
--text-primary: #1e293b;
|
| 31 |
+
--text-secondary: #475569;
|
| 32 |
+
--text-muted: #94a3b8;
|
| 33 |
+
|
| 34 |
+
--accent-blue: #2563eb;
|
| 35 |
+
--accent-blue-hover: #1d4ed8;
|
| 36 |
+
--accent-blue-subtle: rgba(37, 99, 235, 0.08);
|
| 37 |
+
--accent-emerald: #059669;
|
| 38 |
+
--accent-amber: #d97706;
|
| 39 |
+
--accent-red: #dc2626;
|
| 40 |
+
--accent-purple: #7c3aed;
|
| 41 |
+
|
| 42 |
+
--border-subtle: rgba(0, 0, 0, 0.08);
|
| 43 |
+
--border-active: rgba(37, 99, 235, 0.4);
|
| 44 |
+
|
| 45 |
+
--shadow-card: 0 1px 3px rgba(0, 0, 0, 0.04), 0 1px 2px rgba(0, 0, 0, 0.03);
|
| 46 |
+
--shadow-card-hover: 0 2px 8px rgba(0, 0, 0, 0.06);
|
| 47 |
+
--shadow-glow: none;
|
| 48 |
+
|
| 49 |
+
--grad: linear-gradient(135deg, #2563eb 0%, #0284c7 100%);
|
| 50 |
+
--grad-hero: linear-gradient(135deg, rgba(37, 99, 235, 0.05) 0%, rgba(2, 132, 199, 0.05) 100%);
|
| 51 |
+
--hero-text: #1e293b;
|
| 52 |
+
--hero-desc: #475569;
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
[data-theme='dark'] {
|
| 56 |
+
/* Dark Theme */
|
| 57 |
+
--bg-primary: #0f1117;
|
| 58 |
+
--bg-secondary: #1a1d27;
|
| 59 |
+
--bg-card: #1e2130;
|
| 60 |
+
--bg-glass: rgba(255, 255, 255, 0.04);
|
| 61 |
+
--bg-hover: rgba(255, 255, 255, 0.05);
|
| 62 |
+
|
| 63 |
+
--text-primary: #e8eaed;
|
| 64 |
+
--text-secondary: #9aa0b0;
|
| 65 |
+
--text-muted: #5f6577;
|
| 66 |
+
|
| 67 |
+
--accent-blue: #3b82f6;
|
| 68 |
+
--accent-blue-hover: #2563eb;
|
| 69 |
+
--accent-blue-subtle: rgba(59, 130, 246, 0.12);
|
| 70 |
+
--accent-emerald: #10b981;
|
| 71 |
+
--accent-amber: #f59e0b;
|
| 72 |
+
--accent-red: #ef4444;
|
| 73 |
+
--accent-purple: #8b5cf6;
|
| 74 |
+
|
| 75 |
+
--border-subtle: rgba(255, 255, 255, 0.07);
|
| 76 |
+
--border-active: rgba(59, 130, 246, 0.5);
|
| 77 |
+
|
| 78 |
+
--shadow-card: 0 1px 4px rgba(0, 0, 0, 0.2);
|
| 79 |
+
--shadow-card-hover: 0 4px 16px rgba(0, 0, 0, 0.3);
|
| 80 |
+
--shadow-glow: 0 0 20px rgba(59, 130, 246, 0.1);
|
| 81 |
+
|
| 82 |
+
--grad: linear-gradient(135deg, #3b82f6 0%, #0ea5e9 100%);
|
| 83 |
+
--grad-hero: linear-gradient(135deg, rgba(59, 130, 246, 0.08) 0%, rgba(14, 165, 233, 0.08) 100%);
|
| 84 |
+
--hero-text: #e8eaed;
|
| 85 |
+
--hero-desc: #9aa0b0;
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
body {
|
| 89 |
+
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
| 90 |
+
background-color: var(--bg-primary);
|
| 91 |
+
color: var(--text-primary);
|
| 92 |
+
line-height: 1.6;
|
| 93 |
+
display: flex;
|
| 94 |
+
min-height: 100vh;
|
| 95 |
+
}
|
| 96 |
+
|
| 97 |
+
::selection {
|
| 98 |
+
background: var(--accent-blue-subtle);
|
| 99 |
+
color: var(--accent-blue);
|
| 100 |
+
}
|
| 101 |
+
|
| 102 |
+
a {
|
| 103 |
+
color: var(--accent-blue);
|
| 104 |
+
text-decoration: none;
|
| 105 |
+
font-weight: 500;
|
| 106 |
+
}
|
| 107 |
+
a:hover {
|
| 108 |
+
text-decoration: underline;
|
| 109 |
+
}
|
| 110 |
+
|
| 111 |
+
/* Sidebar Styling */
|
| 112 |
+
.sidebar {
|
| 113 |
+
position: fixed;
|
| 114 |
+
top: 0;
|
| 115 |
+
left: 0;
|
| 116 |
+
width: 260px;
|
| 117 |
+
height: 100vh;
|
| 118 |
+
background: var(--bg-secondary);
|
| 119 |
+
border-right: 1px solid var(--border-subtle);
|
| 120 |
+
padding: 24px 0;
|
| 121 |
+
overflow-y: auto;
|
| 122 |
+
z-index: 100;
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
+
.sidebar-logo {
|
| 126 |
+
padding: 0 24px 20px;
|
| 127 |
+
border-bottom: 1px solid var(--border-subtle);
|
| 128 |
+
margin-bottom: 16px;
|
| 129 |
+
}
|
| 130 |
+
|
| 131 |
+
.sidebar-logo h1 {
|
| 132 |
+
font-size: 16px;
|
| 133 |
+
font-weight: 700;
|
| 134 |
+
color: var(--accent-blue);
|
| 135 |
+
letter-spacing: -0.3px;
|
| 136 |
+
font-family: 'Outfit', sans-serif;
|
| 137 |
+
}
|
| 138 |
+
|
| 139 |
+
.sidebar-logo p {
|
| 140 |
+
font-size: 11px;
|
| 141 |
+
color: var(--text-muted);
|
| 142 |
+
margin-top: 4px;
|
| 143 |
+
}
|
| 144 |
+
|
| 145 |
+
.sidebar nav a {
|
| 146 |
+
display: flex;
|
| 147 |
+
align-items: center;
|
| 148 |
+
padding: 10px 24px;
|
| 149 |
+
font-size: 13px;
|
| 150 |
+
color: var(--text-secondary);
|
| 151 |
+
transition: all 0.2s;
|
| 152 |
+
border-left: 3px solid transparent;
|
| 153 |
+
text-decoration: none;
|
| 154 |
+
}
|
| 155 |
+
|
| 156 |
+
.sidebar nav a:hover, .sidebar nav a.active {
|
| 157 |
+
color: var(--accent-blue);
|
| 158 |
+
background: var(--accent-blue-subtle);
|
| 159 |
+
border-left-color: var(--accent-blue);
|
| 160 |
+
}
|
| 161 |
+
|
| 162 |
+
.sidebar nav a .num {
|
| 163 |
+
display: inline-flex;
|
| 164 |
+
align-items: center;
|
| 165 |
+
justify-content: center;
|
| 166 |
+
width: 20px;
|
| 167 |
+
height: 20px;
|
| 168 |
+
border-radius: 4px;
|
| 169 |
+
background: var(--bg-glass);
|
| 170 |
+
font-size: 10px;
|
| 171 |
+
font-weight: 600;
|
| 172 |
+
margin-right: 10px;
|
| 173 |
+
color: var(--text-muted);
|
| 174 |
+
}
|
| 175 |
+
|
| 176 |
+
.sidebar nav a.active .num {
|
| 177 |
+
background: var(--accent-blue);
|
| 178 |
+
color: white;
|
| 179 |
+
}
|
| 180 |
+
|
| 181 |
+
/* Main Area */
|
| 182 |
+
.main {
|
| 183 |
+
margin-left: 260px;
|
| 184 |
+
flex: 1;
|
| 185 |
+
padding: 0;
|
| 186 |
+
overflow-y: auto;
|
| 187 |
+
height: 100vh;
|
| 188 |
+
}
|
| 189 |
+
|
| 190 |
+
/* Embedded in Iframe */
|
| 191 |
+
body.in-iframe .sidebar {
|
| 192 |
+
display: none !important;
|
| 193 |
+
}
|
| 194 |
+
|
| 195 |
+
body.in-iframe .main {
|
| 196 |
+
margin-left: 0 !important;
|
| 197 |
+
width: 100% !important;
|
| 198 |
+
height: 100% !important;
|
| 199 |
+
}
|
| 200 |
+
|
| 201 |
+
body.in-iframe .content {
|
| 202 |
+
padding: 32px 24px 60px;
|
| 203 |
+
max-width: 100%;
|
| 204 |
+
}
|
| 205 |
+
|
| 206 |
+
/* Hero Header */
|
| 207 |
+
.hero {
|
| 208 |
+
background: var(--grad-hero);
|
| 209 |
+
padding: 48px 40px;
|
| 210 |
+
border-bottom: 1px solid var(--border-subtle);
|
| 211 |
+
position: relative;
|
| 212 |
+
overflow: hidden;
|
| 213 |
+
}
|
| 214 |
+
|
| 215 |
+
.hero h1 {
|
| 216 |
+
font-size: 26px;
|
| 217 |
+
font-weight: 700;
|
| 218 |
+
color: var(--hero-text);
|
| 219 |
+
font-family: 'Outfit', sans-serif;
|
| 220 |
+
letter-spacing: -0.5px;
|
| 221 |
+
}
|
| 222 |
+
|
| 223 |
+
.hero p {
|
| 224 |
+
font-size: 13.5px;
|
| 225 |
+
color: var(--hero-desc);
|
| 226 |
+
margin-top: 8px;
|
| 227 |
+
max-width: 800px;
|
| 228 |
+
}
|
| 229 |
+
|
| 230 |
+
.hero .badge {
|
| 231 |
+
display: inline-block;
|
| 232 |
+
padding: 4px 12px;
|
| 233 |
+
background: var(--bg-glass);
|
| 234 |
+
border: 1px solid var(--border-subtle);
|
| 235 |
+
border-radius: 20px;
|
| 236 |
+
font-size: 11px;
|
| 237 |
+
font-weight: 600;
|
| 238 |
+
color: var(--text-secondary);
|
| 239 |
+
margin-top: 12px;
|
| 240 |
+
}
|
| 241 |
+
|
| 242 |
+
/* Content Container */
|
| 243 |
+
.content {
|
| 244 |
+
padding: 48px;
|
| 245 |
+
max-width: 1000px;
|
| 246 |
+
margin: 0 auto;
|
| 247 |
+
}
|
| 248 |
+
|
| 249 |
+
.section {
|
| 250 |
+
margin-bottom: 48px;
|
| 251 |
+
scroll-margin-top: 40px;
|
| 252 |
+
}
|
| 253 |
+
|
| 254 |
+
h2 {
|
| 255 |
+
font-size: 18px;
|
| 256 |
+
font-weight: 700;
|
| 257 |
+
margin-bottom: 16px;
|
| 258 |
+
position: relative;
|
| 259 |
+
padding-left: 12px;
|
| 260 |
+
color: var(--text-primary);
|
| 261 |
+
font-family: 'Outfit', sans-serif;
|
| 262 |
+
}
|
| 263 |
+
|
| 264 |
+
h2::before {
|
| 265 |
+
content: '';
|
| 266 |
+
position: absolute;
|
| 267 |
+
left: 0;
|
| 268 |
+
top: 3px;
|
| 269 |
+
bottom: 3px;
|
| 270 |
+
width: 3px;
|
| 271 |
+
border-radius: 1.5px;
|
| 272 |
+
background: var(--accent-blue);
|
| 273 |
+
}
|
| 274 |
+
|
| 275 |
+
h3 {
|
| 276 |
+
font-size: 14px;
|
| 277 |
+
font-weight: 600;
|
| 278 |
+
margin: 24px 0 12px;
|
| 279 |
+
color: var(--accent-blue);
|
| 280 |
+
}
|
| 281 |
+
|
| 282 |
+
h4 {
|
| 283 |
+
font-size: 13px;
|
| 284 |
+
font-weight: 600;
|
| 285 |
+
margin: 16px 0 8px;
|
| 286 |
+
color: var(--text-primary);
|
| 287 |
+
}
|
| 288 |
+
|
| 289 |
+
p, li {
|
| 290 |
+
margin-bottom: 8px;
|
| 291 |
+
color: var(--text-secondary);
|
| 292 |
+
font-size: 13px;
|
| 293 |
+
line-height: 1.6;
|
| 294 |
+
}
|
| 295 |
+
|
| 296 |
+
ul, ol {
|
| 297 |
+
margin: 0 0 16px 20px;
|
| 298 |
+
}
|
| 299 |
+
|
| 300 |
+
/* Cards & Layout */
|
| 301 |
+
.card {
|
| 302 |
+
background: var(--bg-secondary);
|
| 303 |
+
border: 1px solid var(--border-subtle);
|
| 304 |
+
border-radius: var(--radius-lg, 12px);
|
| 305 |
+
padding: 20px;
|
| 306 |
+
margin: 16px 0;
|
| 307 |
+
box-shadow: var(--shadow-card);
|
| 308 |
+
}
|
| 309 |
+
|
| 310 |
+
.card.tip, .card.info {
|
| 311 |
+
border-color: rgba(37, 99, 235, 0.2);
|
| 312 |
+
background: var(--accent-blue-subtle);
|
| 313 |
+
}
|
| 314 |
+
|
| 315 |
+
.card.tip h4, .card.info h4 {
|
| 316 |
+
color: var(--accent-blue);
|
| 317 |
+
margin-top: 0;
|
| 318 |
+
}
|
| 319 |
+
|
| 320 |
+
.card.warn {
|
| 321 |
+
border-color: rgba(220, 38, 38, 0.2);
|
| 322 |
+
background: rgba(220, 38, 38, 0.03);
|
| 323 |
+
}
|
| 324 |
+
|
| 325 |
+
.card.warn h4 {
|
| 326 |
+
color: var(--accent-red);
|
| 327 |
+
margin-top: 0;
|
| 328 |
+
}
|
| 329 |
+
|
| 330 |
+
/* Table */
|
| 331 |
+
table {
|
| 332 |
+
width: 100%;
|
| 333 |
+
border-collapse: collapse;
|
| 334 |
+
margin: 16px 0;
|
| 335 |
+
border-radius: 8px;
|
| 336 |
+
overflow: hidden;
|
| 337 |
+
border: 1px solid var(--border-subtle);
|
| 338 |
+
}
|
| 339 |
+
|
| 340 |
+
th {
|
| 341 |
+
background: var(--bg-glass);
|
| 342 |
+
padding: 10px 14px;
|
| 343 |
+
text-align: left;
|
| 344 |
+
font-size: 12px;
|
| 345 |
+
font-weight: 600;
|
| 346 |
+
color: var(--text-primary);
|
| 347 |
+
border-bottom: 1px solid var(--border-subtle);
|
| 348 |
+
}
|
| 349 |
+
|
| 350 |
+
td {
|
| 351 |
+
padding: 10px 14px;
|
| 352 |
+
font-size: 12px;
|
| 353 |
+
border-top: 1px solid var(--border-subtle);
|
| 354 |
+
color: var(--text-secondary);
|
| 355 |
+
background: var(--bg-secondary);
|
| 356 |
+
}
|
| 357 |
+
|
| 358 |
+
tr:hover td {
|
| 359 |
+
background: var(--bg-hover);
|
| 360 |
+
}
|
| 361 |
+
|
| 362 |
+
.role-card {
|
| 363 |
+
display: grid;
|
| 364 |
+
grid-template-columns: repeat(3, 1fr);
|
| 365 |
+
gap: 16px;
|
| 366 |
+
margin: 24px 0;
|
| 367 |
+
}
|
| 368 |
+
|
| 369 |
+
.role {
|
| 370 |
+
background: var(--bg-secondary);
|
| 371 |
+
border: 1px solid var(--border-subtle);
|
| 372 |
+
border-radius: 12px;
|
| 373 |
+
padding: 18px;
|
| 374 |
+
text-align: center;
|
| 375 |
+
box-shadow: var(--shadow-card);
|
| 376 |
+
}
|
| 377 |
+
|
| 378 |
+
.role:hover {
|
| 379 |
+
border-color: var(--accent-blue);
|
| 380 |
+
}
|
| 381 |
+
|
| 382 |
+
.role .icon {
|
| 383 |
+
font-size: 24px;
|
| 384 |
+
margin-bottom: 8px;
|
| 385 |
+
}
|
| 386 |
+
|
| 387 |
+
.role .name {
|
| 388 |
+
font-size: 13.5px;
|
| 389 |
+
font-weight: 700;
|
| 390 |
+
color: var(--text-primary);
|
| 391 |
+
margin-bottom: 6px;
|
| 392 |
+
}
|
| 393 |
+
|
| 394 |
+
.role .desc {
|
| 395 |
+
font-size: 11.5px;
|
| 396 |
+
color: var(--text-secondary);
|
| 397 |
+
line-height: 1.4;
|
| 398 |
+
}
|
| 399 |
+
|
| 400 |
+
.flow {
|
| 401 |
+
display: flex;
|
| 402 |
+
align-items: center;
|
| 403 |
+
gap: 6px;
|
| 404 |
+
margin: 16px 0;
|
| 405 |
+
flex-wrap: wrap;
|
| 406 |
+
}
|
| 407 |
+
|
| 408 |
+
.flow-step {
|
| 409 |
+
background: var(--bg-secondary);
|
| 410 |
+
border: 1px solid var(--border-subtle);
|
| 411 |
+
border-radius: 8px;
|
| 412 |
+
padding: 8px 12px;
|
| 413 |
+
font-size: 11.5px;
|
| 414 |
+
color: var(--text-primary);
|
| 415 |
+
font-weight: 500;
|
| 416 |
+
box-shadow: var(--shadow-card);
|
| 417 |
+
}
|
| 418 |
+
|
| 419 |
+
.flow-arrow {
|
| 420 |
+
color: var(--accent-blue);
|
| 421 |
+
font-size: 13px;
|
| 422 |
+
font-weight: bold;
|
| 423 |
+
}
|
| 424 |
+
|
| 425 |
+
/* Code */
|
| 426 |
+
code {
|
| 427 |
+
font-family: 'JetBrains Mono', 'SF Mono', monospace;
|
| 428 |
+
font-size: 11px;
|
| 429 |
+
background: var(--accent-blue-subtle);
|
| 430 |
+
padding: 2px 5px;
|
| 431 |
+
border-radius: 4px;
|
| 432 |
+
color: var(--accent-blue);
|
| 433 |
+
}
|
| 434 |
+
|
| 435 |
+
.code-wrap {
|
| 436 |
+
position: relative;
|
| 437 |
+
margin: 16px 0;
|
| 438 |
+
border-radius: 8px;
|
| 439 |
+
overflow: hidden;
|
| 440 |
+
border: 1px solid var(--border-subtle);
|
| 441 |
+
box-shadow: var(--shadow-card);
|
| 442 |
+
}
|
| 443 |
+
|
| 444 |
+
.code-header {
|
| 445 |
+
display: flex;
|
| 446 |
+
align-items: center;
|
| 447 |
+
justify-content: space-between;
|
| 448 |
+
padding: 6px 14px;
|
| 449 |
+
background: var(--bg-hover);
|
| 450 |
+
border-bottom: 1px solid var(--border-subtle);
|
| 451 |
+
}
|
| 452 |
+
|
| 453 |
+
.code-header span {
|
| 454 |
+
font-size: 11px;
|
| 455 |
+
color: var(--text-muted);
|
| 456 |
+
font-family: 'JetBrains Mono', monospace;
|
| 457 |
+
}
|
| 458 |
+
|
| 459 |
+
.copy-btn {
|
| 460 |
+
padding: 2px 8px;
|
| 461 |
+
border: 1px solid var(--border-subtle);
|
| 462 |
+
border-radius: 4px;
|
| 463 |
+
background: var(--bg-secondary);
|
| 464 |
+
color: var(--text-secondary);
|
| 465 |
+
cursor: pointer;
|
| 466 |
+
font-size: 10px;
|
| 467 |
+
transition: all 0.15s;
|
| 468 |
+
}
|
| 469 |
+
|
| 470 |
+
.copy-btn:hover {
|
| 471 |
+
background: var(--accent-blue);
|
| 472 |
+
color: white;
|
| 473 |
+
border-color: var(--accent-blue);
|
| 474 |
+
}
|
| 475 |
+
|
| 476 |
+
pre {
|
| 477 |
+
background: var(--bg-card);
|
| 478 |
+
padding: 12px 16px;
|
| 479 |
+
overflow-x: auto;
|
| 480 |
+
font-family: 'JetBrains Mono', monospace;
|
| 481 |
+
font-size: 11.5px;
|
| 482 |
+
line-height: 1.5;
|
| 483 |
+
color: var(--text-secondary);
|
| 484 |
+
}
|
| 485 |
+
|
| 486 |
+
pre .comment { color: var(--text-muted); font-style: italic; }
|
| 487 |
+
pre .keyword { color: var(--accent-purple); font-weight: 600; }
|
| 488 |
+
pre .string { color: var(--accent-emerald); }
|
| 489 |
+
pre .cmd { color: var(--accent-blue); }
|
| 490 |
+
|
| 491 |
+
.menu-path {
|
| 492 |
+
color: var(--accent-blue);
|
| 493 |
+
font-weight: 600;
|
| 494 |
+
}
|
| 495 |
+
|
| 496 |
+
/* Installation Specifics */
|
| 497 |
+
.req-grid {
|
| 498 |
+
display: grid;
|
| 499 |
+
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
| 500 |
+
gap: 16px;
|
| 501 |
+
margin: 16px 0;
|
| 502 |
+
}
|
| 503 |
+
|
| 504 |
+
.req-item {
|
| 505 |
+
background: var(--bg-secondary);
|
| 506 |
+
border: 1px solid var(--border-subtle);
|
| 507 |
+
border-radius: 12px;
|
| 508 |
+
padding: 16px;
|
| 509 |
+
text-align: center;
|
| 510 |
+
box-shadow: var(--shadow-card);
|
| 511 |
+
}
|
| 512 |
+
|
| 513 |
+
.req-item .icon {
|
| 514 |
+
font-size: 24px;
|
| 515 |
+
margin-bottom: 6px;
|
| 516 |
+
}
|
| 517 |
+
|
| 518 |
+
.req-item .label {
|
| 519 |
+
font-size: 10px;
|
| 520 |
+
color: var(--text-muted);
|
| 521 |
+
text-transform: uppercase;
|
| 522 |
+
letter-spacing: 0.5px;
|
| 523 |
+
}
|
| 524 |
+
|
| 525 |
+
.req-item .value {
|
| 526 |
+
font-size: 13.5px;
|
| 527 |
+
font-weight: 600;
|
| 528 |
+
color: var(--text-primary);
|
| 529 |
+
margin-top: 4px;
|
| 530 |
+
}
|
| 531 |
+
|
| 532 |
+
.step {
|
| 533 |
+
display: flex;
|
| 534 |
+
gap: 16px;
|
| 535 |
+
margin: 16px 0;
|
| 536 |
+
padding: 16px;
|
| 537 |
+
background: var(--bg-secondary);
|
| 538 |
+
border: 1px solid var(--border-subtle);
|
| 539 |
+
border-radius: 12px;
|
| 540 |
+
box-shadow: var(--shadow-card);
|
| 541 |
+
}
|
| 542 |
+
|
| 543 |
+
.step-num {
|
| 544 |
+
flex-shrink: 0;
|
| 545 |
+
width: 28px;
|
| 546 |
+
height: 28px;
|
| 547 |
+
border-radius: 6px;
|
| 548 |
+
background: var(--grad);
|
| 549 |
+
display: flex;
|
| 550 |
+
align-items: center;
|
| 551 |
+
justify-content: center;
|
| 552 |
+
font-weight: 700;
|
| 553 |
+
font-size: 12px;
|
| 554 |
+
color: #fff;
|
| 555 |
+
}
|
| 556 |
+
|
| 557 |
+
.step-body h4 {
|
| 558 |
+
margin: 0 0 4px;
|
| 559 |
+
color: var(--text-primary);
|
| 560 |
+
}
|
| 561 |
+
|
| 562 |
+
.step-body p {
|
| 563 |
+
margin: 0;
|
| 564 |
+
color: var(--text-secondary);
|
| 565 |
+
font-size: 12.5px;
|
| 566 |
+
}
|
| 567 |
+
|
| 568 |
+
.port-badge {
|
| 569 |
+
display: inline-block;
|
| 570 |
+
padding: 2px 6px;
|
| 571 |
+
border-radius: 4px;
|
| 572 |
+
background: var(--accent-blue-subtle);
|
| 573 |
+
color: var(--accent-blue);
|
| 574 |
+
font-family: 'JetBrains Mono', monospace;
|
| 575 |
+
font-size: 11px;
|
| 576 |
+
font-weight: 600;
|
| 577 |
+
}
|
| 578 |
+
|
| 579 |
+
.top-toolbar {
|
| 580 |
+
position: absolute;
|
| 581 |
+
top: 20px;
|
| 582 |
+
right: 20px;
|
| 583 |
+
z-index: 10;
|
| 584 |
+
display: flex;
|
| 585 |
+
gap: 8px;
|
| 586 |
+
}
|
| 587 |
+
|
| 588 |
+
.lang-selector {
|
| 589 |
+
background: var(--bg-secondary);
|
| 590 |
+
border: 1px solid var(--border-subtle);
|
| 591 |
+
padding: 4px 10px;
|
| 592 |
+
border-radius: 6px;
|
| 593 |
+
color: var(--text-secondary);
|
| 594 |
+
font-size: 11.5px;
|
| 595 |
+
outline: none;
|
| 596 |
+
cursor: pointer;
|
| 597 |
+
box-shadow: var(--shadow-card);
|
| 598 |
+
}
|
| 599 |
+
|
| 600 |
+
.lang-selector:hover {
|
| 601 |
+
border-color: var(--accent-blue);
|
| 602 |
+
color: var(--text-primary);
|
| 603 |
+
}
|
| 604 |
+
|
| 605 |
+
@media (max-width: 900px) {
|
| 606 |
+
.sidebar { display: none; }
|
| 607 |
+
.main { margin-left: 0; }
|
| 608 |
+
.content { padding: 24px; }
|
| 609 |
+
.hero { padding: 32px 24px; }
|
| 610 |
+
.hero h1 { font-size: 22px; }
|
| 611 |
+
}
|
| 612 |
+
|
| 613 |
+
@media print {
|
| 614 |
+
.sidebar { display: none; }
|
| 615 |
+
.main { margin-left: 0; }
|
| 616 |
+
}
|
| 617 |
+
</style>
|
| 618 |
+
</head>
|
| 619 |
+
<body>
|
| 620 |
+
|
| 621 |
+
<aside class="sidebar">
|
| 622 |
+
<div class="sidebar-logo">
|
| 623 |
+
<h1>๐ CertBridge</h1>
|
| 624 |
+
<p data-i18n="sidebar.ver">์ค์น ๊ฐ์ด๋ v0.1.0</p>
|
| 625 |
+
</div>
|
| 626 |
+
<nav id="nav">
|
| 627 |
+
<a href="#requirements" class="active"><span class="num">1</span><span data-i18n="nav.req">์์คํ
์๊ตฌ์ฌํญ</span></a>
|
| 628 |
+
<a href="#server-install"><span class="num">2</span><span data-i18n="nav.server">์๋ฒ ์ค์น (Ubuntu)</span></a>
|
| 629 |
+
<a href="#client-install"><span class="num">3</span><span data-i18n="nav.client">ํด๋ผ์ด์ธํธ ์ค์น (Windows)</span></a>
|
| 630 |
+
<a href="#network"><span class="num">4</span><span data-i18n="nav.network">๋คํธ์ํฌ ๊ตฌ์ฑ</span></a>
|
| 631 |
+
<a href="#initial-setup"><span class="num">5</span><span data-i18n="nav.setup">์ด๊ธฐ ์ค์ </span></a>
|
| 632 |
+
<a href="#troubleshooting"><span class="num">6</span><span data-i18n="nav.trouble">๋ฌธ์ ํด๊ฒฐ</span></a>
|
| 633 |
+
</nav>
|
| 634 |
+
</aside>
|
| 635 |
+
|
| 636 |
+
<div class="main">
|
| 637 |
+
<div class="top-toolbar">
|
| 638 |
+
<select id="lang-select" class="lang-selector" onchange="changeLanguage(this.value)">
|
| 639 |
+
<option value="ko">ํ๊ตญ์ด</option>
|
| 640 |
+
<option value="en">English</option>
|
| 641 |
+
<option value="zh">ไธญๆ</option>
|
| 642 |
+
<option value="ja">ๆฅๆฌ่ช</option>
|
| 643 |
+
<option value="de">Deutsch</option>
|
| 644 |
+
<option value="fr">Franรงais</option>
|
| 645 |
+
<option value="es">Espaรฑol</option>
|
| 646 |
+
<option value="pt">Portuguรชs</option>
|
| 647 |
+
<option value="hu">Magyar</option>
|
| 648 |
+
</select>
|
| 649 |
+
</div>
|
| 650 |
+
|
| 651 |
+
<div class="hero">
|
| 652 |
+
<h1 data-i18n="hero.title">CertBridge ์ค์น ๋ฐ ์
์
๊ฐ์ด๋</h1>
|
| 653 |
+
<p data-i18n="hero.desc">AI ์ฑ์ ์ ์๋ ํ์ฑ ๋ฐ ๋ ๊ฑฐ์ ํตํฉ ์์คํ
์ Ubuntu ์๋ฒ์ Windows ํด๋ผ์ด์ธํธ์ ๊ตฌ์ถํ๋ ์์ธ ํ๋กํ ์ฝ์ ์ค๋ช
ํฉ๋๋ค.</p>
|
| 654 |
+
<span class="badge" data-i18n="hero.badge">๐ฆ v0.1.0 ยท Ubuntu 22.04+ ยท Windows 10+</span>
|
| 655 |
+
</div>
|
| 656 |
+
|
| 657 |
+
<div class="content">
|
| 658 |
+
|
| 659 |
+
<!-- 1. Requirements -->
|
| 660 |
+
<section class="section" id="requirements">
|
| 661 |
+
<h2 data-i18n="req.title">1. ์์คํ
์๊ตฌ์ฌํญ</h2>
|
| 662 |
+
|
| 663 |
+
<h3 data-i18n="req.server_title">๐ฅ๏ธ ์๋ฒ ํ๋์จ์ด ๊ถ์ฅ์ฌ์ (Ubuntu OS)</h3>
|
| 664 |
+
<div class="req-grid">
|
| 665 |
+
<div class="req-item"><div class="icon">๐ง</div><div class="label" data-i18n="req.os">OS</div><div class="value">Ubuntu 22.04 LTS+</div></div>
|
| 666 |
+
<div class="req-item"><div class="icon">๐ง </div><div class="label" data-i18n="req.ram">RAM</div><div class="value">4GB+ (8GB ๊ถ์ฅ)</div></div>
|
| 667 |
+
<div class="req-item"><div class="icon">๐พ</div><div class="label" data-i18n="req.disk">Disk Space</div><div class="value">20GB+ (SSD ๊ถ์ฅ)</div></div>
|
| 668 |
+
<div class="req-item"><div class="icon">๐</div><div class="label" data-i18n="req.net">Network</div><div class="value">์ ์ IP / ์ธ๋ถ ์์๋ฐ์ด๋</div></div>
|
| 669 |
+
</div>
|
| 670 |
+
|
| 671 |
+
<h3 data-i18n="req.client_title">๐ป ํด๋ผ์ด์ธํธ ์คํ ํ๊ฒฝ (Windows)</h3>
|
| 672 |
+
<div class="req-grid">
|
| 673 |
+
<div class="req-item"><div class="icon">๐ช</div><div class="label" data-i18n="req.os">OS</div><div class="value">Windows 10 / 11 (64bit)</div></div>
|
| 674 |
+
<div class="req-item"><div class="icon">๐ง </div><div class="label" data-i18n="req.ram">RAM</div><div class="value">2GB+ (4GB ๊ถ์ฅ)</div></div>
|
| 675 |
+
<div class="req-item"><div class="icon">๐</div><div class="label" data-i18n="req.net">Network</div><div class="value">์ค์ ์๋ฒ 8090 ํฌํธ ์ ๊ทผ</div></div>
|
| 676 |
+
</div>
|
| 677 |
+
|
| 678 |
+
<h3 data-i18n="req.software">๐ง ํ์ ์ธํ๋ผ ์ํํธ์จ์ด (์๋ฒ ์ธก)</h3>
|
| 679 |
+
<table>
|
| 680 |
+
<thead>
|
| 681 |
+
<tr>
|
| 682 |
+
<th data-i18n="req.tb_soft">์ํํธ์จ์ด</th>
|
| 683 |
+
<th data-i18n="req.tb_ver">์ต์ ๋ฒ์ </th>
|
| 684 |
+
<th data-i18n="req.tb_usage">์ฉ๋</th>
|
| 685 |
+
</tr>
|
| 686 |
+
</thead>
|
| 687 |
+
<tbody>
|
| 688 |
+
<tr>
|
| 689 |
+
<td>Docker Engine</td>
|
| 690 |
+
<td>24.0.0+</td>
|
| 691 |
+
<td data-i18n="req.tb_docker_desc">์ปจํ
์ด๋ ๊ธฐ๋ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ฐ ์บ์ ์ค์ผ์คํธ๋ ์ด์
</td>
|
| 692 |
+
</tr>
|
| 693 |
+
<tr>
|
| 694 |
+
<td>Docker Compose</td>
|
| 695 |
+
<td>v2.20.0+</td>
|
| 696 |
+
<td data-i18n="req.tb_compose_desc">๋ฉํฐ ์ปจํ
์ด๋ ์ธํ๋ผ ์คํ ํตํฉ ์คํ</td>
|
| 697 |
+
</tr>
|
| 698 |
+
<tr>
|
| 699 |
+
<td>Node.js Runtime</td>
|
| 700 |
+
<td>20.x LTS+</td>
|
| 701 |
+
<td data-i18n="req.tb_node_desc">CertBridge Express API ์ฝ์ด ์๋ฒ ๊ตฌ๋</td>
|
| 702 |
+
</tr>
|
| 703 |
+
</tbody>
|
| 704 |
+
</table>
|
| 705 |
+
</section>
|
| 706 |
+
|
| 707 |
+
<!-- 2. Server Install -->
|
| 708 |
+
<section class="section" id="server-install">
|
| 709 |
+
<h2 data-i18n="server.title">2. ์๋ฒ ์ค์น (Ubuntu)</h2>
|
| 710 |
+
|
| 711 |
+
<h3 data-i18n="server.auto">2-1. ์๋ ์ ์คํฌ๋ฆฝํธ ์ค์น (๊ถ์ฅ)</h3>
|
| 712 |
+
<p data-i18n="server.auto_desc">์ ๊ณต๋ setup.sh ํ์ผ์ ํ์ฉํด ๋์ปค ์์ง, ํ๊ฒฝ๋ณ์, ๋ฐ์ดํฐ๋ฒ ์ด์ค, systemd ์๋น์ค ๋ฑ๋ก์ ํ ๋ฒ์ ์๋์ผ๋ก ์๋ฃํฉ๋๋ค.</p>
|
| 713 |
+
|
| 714 |
+
<div class="code-wrap">
|
| 715 |
+
<div class="code-header"><span>bash</span><button class="copy-btn" onclick="copyCode(this)">๋ณต์ฌ</button></div>
|
| 716 |
+
<pre><span class="comment"># 1. ์๋ฒ ํจํค์ง ์์นด์ด๋ธ ๋ค์ด๋ก๋</span>
|
| 717 |
+
<span class="cmd">wget</span> https://huggingface.co/VanyaJ/certbridge/resolve/main/certbridge-server-v0.1.0-ubuntu.tar.gz
|
| 718 |
+
|
| 719 |
+
<span class="comment"># 2. ํ์ผ ์์ถ ํด์ ๋ฐ ๋๋ ํ ๋ฆฌ ์ด๋</span>
|
| 720 |
+
<span class="cmd">tar</span> -xzf certbridge-server-v0.1.0-ubuntu.tar.gz
|
| 721 |
+
<span class="cmd">cd</span> certbridge-server-ubuntu
|
| 722 |
+
|
| 723 |
+
<span class="comment"># 3. ์ค์น ๊ถํ ๋ถ์ฌ ๋ฐ ์ ์คํ</span>
|
| 724 |
+
<span class="cmd">chmod</span> +x setup.sh
|
| 725 |
+
<span class="cmd">sudo</span> ./setup.sh</pre>
|
| 726 |
+
</div>
|
| 727 |
+
|
| 728 |
+
<h3 data-i18n="server.manual">2-2. ๋จ๊ณ๋ณ ์๋ ์ค์น ํ๋กํ ์ฝ</h3>
|
| 729 |
+
|
| 730 |
+
<h4 data-i18n="server.d_setup">Docker ์ค์น ๋ฐ ์คํ ํ๊ฒฝ ๊ตฌ์ฑ</h4>
|
| 731 |
+
<div class="code-wrap">
|
| 732 |
+
<div class="code-header"><span>bash</span><button class="copy-btn" onclick="copyCode(this)">๋ณต์ฌ</button></div>
|
| 733 |
+
<pre><span class="comment"># ํจํค์ง ์
๋ฐ์ดํธ ๋ฐ GPG ํค ์ถ๊ฐ</span>
|
| 734 |
+
<span class="cmd">sudo apt-get</span> update
|
| 735 |
+
<span class="cmd">sudo apt-get install -y</span> ca-certificates curl gnupg
|
| 736 |
+
<span class="cmd">sudo install -m 0755 -d</span> /etc/apt/keyrings
|
| 737 |
+
<span class="cmd">curl -fsSL</span> https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
|
| 738 |
+
|
| 739 |
+
<span class="comment"># ๋ ํฌ์งํ ๋ฆฌ ์ ๋ณด ์ถ๊ฐ ๋ฐ ๋์ปค ์ฝ์ด ํจํค์ง ์ค์น</span>
|
| 740 |
+
<span class="cmd">echo</span> "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo $VERSION_CODENAME) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
| 741 |
+
<span class="cmd">sudo apt-get</span> update
|
| 742 |
+
<span class="cmd">sudo apt-get install -y</span> docker-ce docker-ce-cli containerd.io docker-compose-plugin</pre>
|
| 743 |
+
</div>
|
| 744 |
+
|
| 745 |
+
<h4 data-i18n="server.compose">๋์ปค ์ปดํฌ์ฆ ๊ธฐ๋ฐ ์ธํ๋ผ ๊ตฌ์ฑ์์ ์คํ</h4>
|
| 746 |
+
<p data-i18n="server.compose_desc">PostgreSQL, Redis, MinIO ์ค๋ธ์ ํธ ์คํ ๋ฆฌ์ง ๋ฐ Neo4j ๊ทธ๋ํ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ํ๋์ ๋ฐฑ๊ทธ๋ผ์ด๋ ์คํ์ผ๋ก ๋์๋๋ค.</p>
|
| 747 |
+
<div class="code-wrap">
|
| 748 |
+
<div class="code-header"><span>bash</span><button class="copy-btn" onclick="copyCode(this)">๋ณต์ฌ</button></div>
|
| 749 |
+
<pre><span class="comment"># server ๋๋ ํ ๋ฆฌ ๋ด๋ถ docker-compose ํ์ผ ์คํ</span>
|
| 750 |
+
<span class="cmd">sudo docker compose</span> up -d
|
| 751 |
+
|
| 752 |
+
<span class="comment"># ๊ธฐ๋ ์ํ ์ ์ํ ํ์ธ</span>
|
| 753 |
+
<span class="cmd">sudo docker compose</span> ps</pre>
|
| 754 |
+
</div>
|
| 755 |
+
|
| 756 |
+
<h4 data-i18n="server.env_setup">API ํ๊ฒฝ ํ์ผ ๊ตฌ์ฑ (.env)</h4>
|
| 757 |
+
<div class="code-wrap">
|
| 758 |
+
<div class="code-header"><span>.env</span><button class="copy-btn" onclick="copyCode(this)">๋ณต์ฌ</button></div>
|
| 759 |
+
<pre># Central Data Store Connections
|
| 760 |
+
DATABASE_URL=postgres://n8n:n8n_password@localhost:5432/certbridge
|
| 761 |
+
REDIS_URL=redis://localhost:6379/2
|
| 762 |
+
|
| 763 |
+
# File Storage Configuration
|
| 764 |
+
MINIO_ENDPOINT=localhost:9000
|
| 765 |
+
MINIO_ACCESS_KEY=minioadmin
|
| 766 |
+
MINIO_SECRET_KEY=minioadmin
|
| 767 |
+
MINIO_BUCKET=certbridge
|
| 768 |
+
|
| 769 |
+
# Neo4j Graph DB Config
|
| 770 |
+
NEO4J_URI=bolt://localhost:7687
|
| 771 |
+
NEO4J_USER=neo4j
|
| 772 |
+
NEO4J_PASSWORD=certbridge123
|
| 773 |
+
|
| 774 |
+
# Core Express API Config
|
| 775 |
+
API_PORT=8090
|
| 776 |
+
JWT_SECRET=your-premium-secret-key-change-in-production</pre>
|
| 777 |
+
</div>
|
| 778 |
+
|
| 779 |
+
<div class="card warn">
|
| 780 |
+
<h4 data-i18n="server.warn_title">โ ๏ธ ํ์ ๋ณด์ ์ฃผ์์ฌํญ</h4>
|
| 781 |
+
<p data-i18n="server.warn_desc">์ด์ ํ๊ฒฝ ๋ฐฐํฌ ์, <code>JWT_SECRET</code> ์ํธํ ํค์ ๊ธฐ๋ณธ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํจ์ค์๋ ๋ฐ MinIO ACCESS/SECRET ํค๋ฅผ ๋์ ํํ๋ก ๋ฐ๋์ ๊ต์ฒดํด ์ ์ฉํ์ญ์์ค.</p>
|
| 782 |
+
</div>
|
| 783 |
+
|
| 784 |
+
<h4 data-i18n="server.api_start">API ์๋ฒ ์์กด์ฑ ์ค์น ๋ฐ ๊ธฐ๋</h4>
|
| 785 |
+
<div class="code-wrap">
|
| 786 |
+
<div class="code-header"><span>bash</span><button class="copy-btn" onclick="copyCode(this)">๋ณต์ฌ</button></div>
|
| 787 |
+
<pre><span class="comment"># server/api ํด๋๋ก ์ด๋ ํ ๋ชจ๋ ๋ค์ด๋ก๋</span>
|
| 788 |
+
<span class="cmd">npm</span> install --production
|
| 789 |
+
|
| 790 |
+
<span class="comment"># API ์๋ฒ ๋ฐ๋ชฌ ๋ชจ๋๋ก ์๋ ๊ธฐ๋</span>
|
| 791 |
+
<span class="cmd">source</span> .env && <span class="cmd">node</span> server.js
|
| 792 |
+
|
| 793 |
+
<span class="comment"># ํฌ์ค์ฒดํฌ ์ ์ ์์ ํ์ธ</span>
|
| 794 |
+
<span class="cmd">curl</span> http://localhost:8090/health</pre>
|
| 795 |
+
</div>
|
| 796 |
+
</section>
|
| 797 |
+
|
| 798 |
+
<!-- 3. Client Install -->
|
| 799 |
+
<section class="section" id="client-install">
|
| 800 |
+
<h2 data-i18n="client.title">3. ํด๋ผ์ด์ธํธ ์ค์น (Windows)</h2>
|
| 801 |
+
|
| 802 |
+
<div class="step">
|
| 803 |
+
<div class="step-num">1</div>
|
| 804 |
+
<div class="step-body">
|
| 805 |
+
<h4 data-i18n="client.s1_title">์ค์น ํ์ผ ํจํค์ง ๋ค์ด๋ก๋</h4>
|
| 806 |
+
<p data-i18n="client.s1_desc">๊ณต์ ๋ฆด๋ฆฌ์ฆ ๋ณด๊ด์(HuggingFace ๋๋ ํ์ฌ CDN๋ง)์์ <code>CertBridge_0.1.0_x64-setup.exe</code>(์๋ ๋น๋ ๋ณธ)๋ฅผ ์์ ํ๊ฒ ๋ฐ์์ต๋๋ค.</p>
|
| 807 |
+
</div>
|
| 808 |
+
</div>
|
| 809 |
+
|
| 810 |
+
<div class="step">
|
| 811 |
+
<div class="step-num">2</div>
|
| 812 |
+
<div class="step-body">
|
| 813 |
+
<h4 data-i18n="client.s2_title">์ค์น ๋ง๋ฒ์ฌ ์งํ ๋ฐ ์ธ์ด ํ๊ฒํ
</h4>
|
| 814 |
+
<p data-i18n="client.s2_desc">์ค์น ๋ง๋ฒ์ฌ ๋จ๊ณ์์ ์ํ๋ ์ธ์ด๋ฅผ ๊ธฐ๋ณธ์ ์ผ๋ก ์ค์ (ํ๊ธ/์์ด ์๋ ๋งค์นญ)ํ ํ, ์ง์ ๋ ๊ฒฝ๋ก์ ํด๋ผ์ด์ธํธ ๋ฐ์ด๋๋ฆฌ๋ฅผ ๋น๋ ์ค์นํฉ๋๋ค.</p>
|
| 815 |
+
</div>
|
| 816 |
+
</div>
|
| 817 |
+
|
| 818 |
+
<div class="step">
|
| 819 |
+
<div class="step-num">3</div>
|
| 820 |
+
<div class="step-body">
|
| 821 |
+
<h4 data-i18n="client.s3_title">์ค์ ์๋ํฌ์ธํธ ์ฐ๊ฒฐ ํ
์คํธ</h4>
|
| 822 |
+
<p data-i18n="client.s3_desc">๋ฐํํ๋ฉด ๋จ์ถ ์์ด์ฝ์ ํตํด ์คํ ํ, ์ฐ์ธก ์๋์ <strong>์ค์ ์์ด์ฝ(โ๏ธ)</strong>์ ํด๋ฆญํด ์ค์์ ๊ฐ๋ฐฉ๋ API ์๋ฒ IP ๋ฐ ๋๋ฉ์ธ์ ์
๋ ฅํ์ฌ ํ
์คํธ ํต์ ํฉ๋๋ค: <code>http://<์ค์์๋ฒ_IP>:8090</code></p>
|
| 823 |
+
</div>
|
| 824 |
+
</div>
|
| 825 |
+
</section>
|
| 826 |
+
|
| 827 |
+
<!-- 4. Network -->
|
| 828 |
+
<section class="section" id="network">
|
| 829 |
+
<h2 data-i18n="net.title">4. ๋คํธ์ํฌ ๋ฐ ํฌํธ ๊ตฌ์ฑ</h2>
|
| 830 |
+
<h3 data-i18n="net.ports">์ธํ๋ผ ์์คํ
์ฌ์ฉ ํฌํธ ํํฉ</h3>
|
| 831 |
+
<table>
|
| 832 |
+
<thead>
|
| 833 |
+
<tr>
|
| 834 |
+
<th data-i18n="net.tb_serv">์ฐ๋ ์๋น์ค</th>
|
| 835 |
+
<th data-i18n="net.tb_port">๊ธฐ๋ณธ ํฌํธ</th>
|
| 836 |
+
<th data-i18n="net.tb_proto">ํ๋กํ ์ฝ</th>
|
| 837 |
+
<th data-i18n="net.tb_desc">์ค๋ช
</th>
|
| 838 |
+
</tr>
|
| 839 |
+
</thead>
|
| 840 |
+
<tbody>
|
| 841 |
+
<tr>
|
| 842 |
+
<td>CertBridge API Gateway</td>
|
| 843 |
+
<td><span class="port-badge">8090</span></td>
|
| 844 |
+
<td>HTTP</td>
|
| 845 |
+
<td data-i18n="net.tb_p1">์ฝ์ด ํด๋ผ์ด์ธํธ REST & ํํธ๋นํธ ์ฐ๊ฒฐ ์ฐฝ๊ตฌ (์ธ๋ฐ์ด๋ ํ์ฉ ํ์)</td>
|
| 846 |
+
</tr>
|
| 847 |
+
<tr>
|
| 848 |
+
<td>Neo4j Bolt Driver</td>
|
| 849 |
+
<td><span class="port-badge">7687</span></td>
|
| 850 |
+
<td>TCP / Bolt</td>
|
| 851 |
+
<td data-i18n="net.tb_p2">ํ์ง ์ง์ ์จํจ๋ก์ง ๊ณ ์ ์ปค๋ฅํฐ ํฌํธ</td>
|
| 852 |
+
</tr>
|
| 853 |
+
<tr>
|
| 854 |
+
<td>MinIO Storage API</td>
|
| 855 |
+
<td><span class="port-badge">9000</span></td>
|
| 856 |
+
<td>HTTP</td>
|
| 857 |
+
<td data-i18n="net.tb_p3">์ฑ์ ์ PDF ๋ฌผ๋ฆฌ ์๋ณธ ํ์ผ ์ฝ๊ธฐ/์ฐ๊ธฐ ์คํ ๋ฆฌ์ง API</td>
|
| 858 |
+
</tr>
|
| 859 |
+
<tr>
|
| 860 |
+
<td>n8n Automation Engine</td>
|
| 861 |
+
<td><span class="port-badge">5678</span></td>
|
| 862 |
+
<td>HTTP</td>
|
| 863 |
+
<td data-i18n="net.tb_p4">์ํฌํ๋ก์ฐ ์๋ํ ํ์ดํ๋ผ์ธ ํธ๋ฆฌ๊ฑฐ ์๋ํฌ์ธํธ</td>
|
| 864 |
+
</tr>
|
| 865 |
+
</tbody>
|
| 866 |
+
</table>
|
| 867 |
+
|
| 868 |
+
<h3 data-i18n="net.firewall">Ubuntu ๋ฐฉํ๋ฒฝ (UFW) ์ค์ ์คํฌ๋ฆฝํธ</h3>
|
| 869 |
+
<div class="code-wrap">
|
| 870 |
+
<div class="code-header"><span>bash</span><button class="copy-btn" onclick="copyCode(this)">๋ณต์ฌ</button></div>
|
| 871 |
+
<pre><span class="comment"># ๊ธฐ๋ณธ ํฌํธ ๊ฐ๋ฐฉ</span>
|
| 872 |
+
<span class="cmd">sudo ufw</span> allow 8090/tcp
|
| 873 |
+
|
| 874 |
+
<span class="comment"># ๋ณด์ ๊ถ๊ณ : ๋ฐ์ดํฐ ๊ด๋ฆฌ์ IP ๋์ญ๋ง Neo4j, MinIO ์ฝ์ ํ์ฉ</span>
|
| 875 |
+
<span class="cmd">sudo ufw</span> allow from 192.168.10.0/24 to any port 7474
|
| 876 |
+
<span class="cmd">sudo ufw</span> allow from 192.168.10.0/24 to any port 9001</pre>
|
| 877 |
+
</div>
|
| 878 |
+
</section>
|
| 879 |
+
|
| 880 |
+
<!-- 5. Initial Setup -->
|
| 881 |
+
<section class="section" id="initial-setup">
|
| 882 |
+
<h2 data-i18n="setup.title">5. ์ค์ ๊ด๋ฆฌ ํ๊ฒฝ ์ด๊ธฐํ</h2>
|
| 883 |
+
<h3 data-i18n="setup.admin">5-1. ์ต์ด ๊ด๋ฆฌ์ ๊ณ์ ์ ๋ณด</h3>
|
| 884 |
+
<p data-i18n="setup.admin_desc">์ค์น๊ฐ ์ ์์ ์ผ๋ก ๋ง์ณ์ง๋ฉด ๋ฐ์ดํฐ๋ฒ ์ด์ค ์๋ ์คํฌ๋ฆฝํธ๋ฅผ ํตํด ์๋ ๊ด๋ฆฌ์ ๋ ์ฝ๋๊ฐ ์์ฑ๋ฉ๋๋ค:</p>
|
| 885 |
+
<table>
|
| 886 |
+
<thead>
|
| 887 |
+
<tr>
|
| 888 |
+
<th data-i18n="setup.tb_col">์ค์ ์ ๋ณด</th>
|
| 889 |
+
<th data-i18n="setup.tb_val">์ง์ ๋ ๊ธฐ๋ณธ ๊ฐ</th>
|
| 890 |
+
</tr>
|
| 891 |
+
</thead>
|
| 892 |
+
<tbody>
|
| 893 |
+
<tr>
|
| 894 |
+
<td data-i18n="start.tb_id">์์ด๋</td>
|
| 895 |
+
<td><code>admin</code></td>
|
| 896 |
+
</tr>
|
| 897 |
+
<tr>
|
| 898 |
+
<td data-i18n="start.tb_pw">๋น๋ฐ๋ฒํธ</td>
|
| 899 |
+
<td><code>admin123</code></td>
|
| 900 |
+
</tr>
|
| 901 |
+
<tr>
|
| 902 |
+
<td data-i18n="setup.tb_role">๋ฑ๊ธ</td>
|
| 903 |
+
<td><code>admin</code></td>
|
| 904 |
+
</tr>
|
| 905 |
+
</tbody>
|
| 906 |
+
</table>
|
| 907 |
+
|
| 908 |
+
<h3 data-i18n="setup.group">5-2. ๊ณต์ฅ ๊ทธ๋ฃน ๋ฐ ๋ก์ปฌ ํ๋กํ์ผ ํ ๋น</h3>
|
| 909 |
+
<p data-i18n="setup.group_desc">์ด๋๋ฏผ ๋ก๊ทธ์ธ ์๋ฃ ํ <strong>[๊ทธ๋ฃน ๊ด๋ฆฌ]</strong> ํญ์ผ๋ก ์ง์
ํ์ฌ ์ ์กฐ์ง์ ์ถ๊ฐํฉ๋๋ค. ๋ณธ์ฌ ์ค์ ์๋ฒ๋ฅผ ์ ์งํ๋ฉด์ ๊ฐ ๋ก์ปฌ ๊ณต์ฅ(์: ์ฒญ์ฃผ๊ณต์ฅ, ํ๊ฐ๋ฆฌ๊ณต์ฅ, ๋ฏธ๊ตญ๊ณต์ฅ)๋ง๋ค ๋ก์ปฌ DB ์ ์ ๋ฌธ์์ด ๋ฐ ๋ก์ปฌ MinIO/Neo4j ์ ๋ณด๋ฅผ ๋ค๋ฅด๊ฒ ์
๋ ฅํด ๋ฐ์ดํฐ๋ฅผ ์๋ฒฝํ ๊ฒฉ๋ฆฌํ ์ ์์ต๋๋ค.</p>
|
| 910 |
+
</section>
|
| 911 |
+
|
| 912 |
+
<!-- 6. Troubleshooting -->
|
| 913 |
+
<section class="section" id="troubleshooting">
|
| 914 |
+
<h2 data-i18n="trouble.title">6. ๋ฌธ์ ํด๊ฒฐ (Troubleshooting)</h2>
|
| 915 |
+
|
| 916 |
+
<div class="card warn">
|
| 917 |
+
<h4 data-i18n="trouble.q1">๐ด Docker ์ปจํ
์ด๋ ๊ตฌ๋ ์ Permission Denied ๋ฐ์</h4>
|
| 918 |
+
<p data-i18n="trouble.a1">์ฌ์ฉ์ ๊ณ์ ์ด docker ๊ถํ ๊ทธ๋ฃน์ ํฌํจ๋์ง ์์ ๋ฐ์ํฉ๋๋ค. <code>sudo usermod -aG docker $USER</code> ๋ช
๋ น์ ์
๋ ฅํ ํ, ์ ํฐ๋ฏธ๋ ์ธ์
์ ์์ ํ ์ข
๋ฃํ๋ค๊ฐ ๋ค์ ๋ก๊ทธ์ธํด ์์ํ์ญ์์ค.</p>
|
| 919 |
+
</div>
|
| 920 |
+
|
| 921 |
+
<div class="card warn">
|
| 922 |
+
<h4 data-i18n="trouble.q2">๐ด "ECONNREFUSED" ์๋ฒ ์๋ต ์๋ฌ ์์ </h4>
|
| 923 |
+
<p data-i18n="trouble.a2">์ค์ ์๋ฒ ์ธก์ API ์คํ ๋ฐ๋ชฌ ํ๋ก์ธ์ค๊ฐ ๊ธฐ๋๋์ง ์์๊ฑฐ๋ ํฌํธ๊ฐ ์ถฉ๋ํ ๊ฒฝ์ฐ์
๋๋ค. <code>sudo systemctl status certbridge</code> ์ํ ์กฐํ๋ฅผ ํตํด systemd ์๋น์ค ์์กด ์ ๋ฌด๋ฅผ ๊ฒ์ฌํ์ญ์์ค.</p>
|
| 924 |
+
</div>
|
| 925 |
+
|
| 926 |
+
<div class="card warn">
|
| 927 |
+
<h4 data-i18n="trouble.q3">๐ก Windows SmartScreen ์ฐจ๋จ ํ์
์ด ์ถ๋ ฅ๋ฉ๋๋ค.</h4>
|
| 928 |
+
<p data-i18n="trouble.a3">๋ณธ ํจํค์ง๋ ๋๋ฉ์ธ ํ๋ผ์ด๋น ๊ฐ๋ฐ ๋ณธ์ผ๋ก ์ฝ๋ ์ฌ์ด๋(Code Signing) ์๋ช
์๊ฐ ๊ฒฐ์ฌ๋์ด ์์ต๋๋ค. ํ์
ํ๋จ์ "์ถ๊ฐ ์ ๋ณด"๋ฅผ ํด๋ฆญํ ๋ค์, ๋ํ๋ "์คํ" ๋ฒํผ์ ์์ฌํ๊ณ ํด๋ฆญํด ์
์
์ ์์ํด ์ฃผ์๊ธฐ ๋ฐ๋๋๋ค.</p>
|
| 929 |
+
</div>
|
| 930 |
+
</section>
|
| 931 |
+
|
| 932 |
+
</div>
|
| 933 |
+
</div>
|
| 934 |
+
|
| 935 |
+
<script>
|
| 936 |
+
// โโโ Theme Synchronization โโโ
|
| 937 |
+
function syncTheme() {
|
| 938 |
+
let theme = "light";
|
| 939 |
+
try {
|
| 940 |
+
if (window.parent && window.parent.document && window.parent.document.documentElement) {
|
| 941 |
+
theme = window.parent.document.documentElement.getAttribute("data-theme") || "light";
|
| 942 |
+
} else {
|
| 943 |
+
theme = localStorage.getItem("certbridge_theme") || "light";
|
| 944 |
+
}
|
| 945 |
+
} catch (e) {
|
| 946 |
+
theme = localStorage.getItem("certbridge_theme") || "light";
|
| 947 |
+
}
|
| 948 |
+
|
| 949 |
+
if (theme === "dark") {
|
| 950 |
+
document.documentElement.setAttribute("data-theme", "dark");
|
| 951 |
+
} else {
|
| 952 |
+
document.documentElement.removeAttribute("data-theme");
|
| 953 |
+
}
|
| 954 |
+
}
|
| 955 |
+
syncTheme();
|
| 956 |
+
// Observe parent document changes if available
|
| 957 |
+
try {
|
| 958 |
+
if (window.parent && window.parent.document && window.parent.document.documentElement) {
|
| 959 |
+
const observer = new MutationObserver((mutations) => {
|
| 960 |
+
mutations.forEach((mutation) => {
|
| 961 |
+
if (mutation.type === "attributes" && mutation.attributeName === "data-theme") {
|
| 962 |
+
syncTheme();
|
| 963 |
+
}
|
| 964 |
+
});
|
| 965 |
+
});
|
| 966 |
+
observer.observe(window.parent.document.documentElement, { attributes: true });
|
| 967 |
+
}
|
| 968 |
+
} catch (e) {
|
| 969 |
+
setInterval(syncTheme, 1000);
|
| 970 |
+
}
|
| 971 |
+
|
| 972 |
+
// โโโ Iframe Detection for Sidebar โโโ
|
| 973 |
+
if (window.self !== window.top) {
|
| 974 |
+
document.body.classList.add('in-iframe');
|
| 975 |
+
}
|
| 976 |
+
|
| 977 |
+
// 9 Locales Translation Dictionary for Installation/Setup Guide
|
| 978 |
+
const i18n = {
|
| 979 |
+
ko: {
|
| 980 |
+
"sidebar.ver": "์ค์น ๊ฐ์ด๋ v0.1.0",
|
| 981 |
+
"nav.req": "์์คํ
์๊ตฌ์ฌํญ",
|
| 982 |
+
"nav.server": "์๋ฒ ์ค์น (Ubuntu)",
|
| 983 |
+
"nav.client": "ํด๋ผ์ด์ธํธ ์ค์น (Windows)",
|
| 984 |
+
"nav.network": "๋คํธ์ํฌ ๊ตฌ์ฑ",
|
| 985 |
+
"nav.setup": "์ด๊ธฐ ์ค์ ",
|
| 986 |
+
"nav.trouble": "๋ฌธ์ ํด๊ฒฐ",
|
| 987 |
+
"hero.title": "CertBridge ์ค์น ๋ฐ ์
์
๊ฐ์ด๋",
|
| 988 |
+
"hero.desc": "AI ์ฑ์ ์ ์๋ ํ์ฑ ๋ฐ ๋ ๊ฑฐ์ ํตํฉ ์์คํ
์ Ubuntu ์๋ฒ์ Windows ํด๋ผ์ด์ธํธ์ ๊ตฌ์ถํ๋ ์์ธ ํ๋กํ ์ฝ์ ์ค๋ช
ํฉ๋๋ค.",
|
| 989 |
+
"hero.badge": "๐ฆ v0.1.0 ยท Ubuntu 22.04+ ยท Windows 10+",
|
| 990 |
+
"req.title": "1. ์์คํ
์๊ตฌ์ฌํญ",
|
| 991 |
+
"req.server_title": "๐ฅ๏ธ ์๋ฒ ํ๋์จ์ด ๊ถ์ฅ์ฌ์ (Ubuntu OS)",
|
| 992 |
+
"req.os": "์ด์์ฒด์ ",
|
| 993 |
+
"req.ram": "๋ฉ๋ชจ๋ฆฌ",
|
| 994 |
+
"req.disk": "๋๋ฐ์ด์ค ์ฉ๋",
|
| 995 |
+
"req.net": "๋คํธ์ํฌ๋ง",
|
| 996 |
+
"req.client_title": "๐ป ํด๋ผ์ด์ธํธ ์คํ ํ๊ฒฝ (Windows)",
|
| 997 |
+
"req.software": "๐ง ํ์ ์ธํ๋ผ ์ํํธ์จ์ด (์๋ฒ ์ธก)",
|
| 998 |
+
"req.tb_soft": "์ํํธ์จ์ด",
|
| 999 |
+
"req.tb_ver": "์ต์ ๋ฒ์ ",
|
| 1000 |
+
"req.tb_usage": "์ฉ๋",
|
| 1001 |
+
"req.tb_docker_desc": "์ปจํ
์ด๋ ๊ธฐ๋ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ฐ ์บ์ ์ค์ผ์คํธ๋ ์ด์
",
|
| 1002 |
+
"req.tb_compose_desc": "๋ฉํฐ ์ปจํ
์ด๋ ์ธํ๋ผ ์คํ ํตํฉ ์คํ",
|
| 1003 |
+
"req.tb_node_desc": "CertBridge Express API ์ฝ์ด ์๋ฒ ๊ตฌ๋",
|
| 1004 |
+
"server.title": "2. ์๋ฒ ์ค์น (Ubuntu)",
|
| 1005 |
+
"server.auto": "2-1. ์๋ ์ ์คํฌ๋ฆฝํธ ์ค์น (๊ถ์ฅ)",
|
| 1006 |
+
"server.auto_desc": "์ ๊ณต๋ setup.sh ํ์ผ์ ํ์ฉํด ๋์ปค ์์ง, ํ๊ฒฝ๋ณ์, ๋ฐ์ดํฐ๋ฒ ์ด์ค, systemd ์๋น์ค ๋ฑ๋ก์ ํ ๋ฒ์ ์๋์ผ๋ก ์๋ฃํฉ๋๋ค.",
|
| 1007 |
+
"server.manual": "2-2. ๋จ๊ณ๋ณ ์๋ ์ค์น ํ๋กํ ์ฝ",
|
| 1008 |
+
"server.d_setup": "Docker ์ค์น ๋ฐ ์คํ ํ๊ฒฝ ๊ตฌ์ฑ",
|
| 1009 |
+
"server.compose": "๋์ปค ์ปดํฌ์ฆ ๊ธฐ๋ฐ ์ธํ๋ผ ๊ตฌ์ฑ์์ ์คํ",
|
| 1010 |
+
"server.compose_desc": "PostgreSQL, Redis, MinIO ์ค๋ธ์ ํธ ์คํ ๋ฆฌ์ง ๋ฐ Neo4j ๊ทธ๋ํ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ํ๋์ ๋ฐฑ๊ทธ๋ผ์ด๋ ์คํ์ผ๋ก ๋์๋๋ค.",
|
| 1011 |
+
"server.env_setup": "API ํ๊ฒฝ ํ์ผ ๊ตฌ์ฑ (.env)",
|
| 1012 |
+
"server.warn_title": "โ ๏ธ ํ์ ๋ณด์ ์ฃผ์์ฌํญ",
|
| 1013 |
+
"server.warn_desc": "์ด์ ํ๊ฒฝ ๋ฐฐํฌ ์, JWT_SECRET ์ํธํ ํค์ ๊ธฐ๋ณธ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํจ์ค์๋ ๋ฐ MinIO ACCESS/SECRET ํค๋ฅผ ๋์ ํํ๋ก ๋ฐ๋์ ๊ต์ฒดํด ์ ์ฉํ์ญ์์ค.",
|
| 1014 |
+
"server.api_start": "API ์๋ฒ ์์กด์ฑ ์ค์น ๋ฐ ๊ธฐ๋",
|
| 1015 |
+
"client.title": "3. ํด๋ผ์ด์ธํธ ์ค์น (Windows)",
|
| 1016 |
+
"client.s1_title": "์ค์น ํ์ผ ํจํค์ง ๋ค์ด๋ก๋",
|
| 1017 |
+
"client.s1_desc": "๊ณต์ ๋ฆด๋ฆฌ์ฆ ๋ณด๊ด์(HuggingFace ๋๋ ํ์ฌ CDN๋ง)์์ CertBridge_0.1.0_x64-setup.exe(์๋ ๋น๋ ๋ณธ)๋ฅผ ์์ ํ๊ฒ ๋ฐ์์ต๋๋ค.",
|
| 1018 |
+
"client.s2_title": "์ค์น ๋ง๋ฒ์ฌ ์งํ ๋ฐ ์ธ์ด ํ๊ฒํ
",
|
| 1019 |
+
"client.s2_desc": "์ค์น ๋ง๋ฒ์ฌ ๋จ๊ณ์์ ์ํ๋ ์ธ์ด๋ฅผ ๊ธฐ๋ณธ์ ์ผ๋ก ์ค์ (ํ๊ธ/์์ด ์๋ ๋งค์นญ)ํ ํ, ์ง์ ๋ ๊ฒฝ๋ก์ ํด๋ผ์ด์ธํธ ๋ฐ์ด๋๋ฆฌ๋ฅผ ๋น๋ ์ค์นํฉ๋๋ค.",
|
| 1020 |
+
"client.s3_title": "์ค์ ์๋ํฌ์ธํธ ์ฐ๊ฒฐ ํ
์คํธ",
|
| 1021 |
+
"client.s3_desc": "๋ฐํํ๋ฉด ๋จ์ถ ์์ด์ฝ์ ํตํด ์คํ ํ, ์ฐ์ธก ์๋์ ์ค์ ์์ด์ฝ(โ๏ธ)์ ํด๋ฆญํด ์ค์์ ๊ฐ๋ฐฉ๋ API ์๋ฒ IP ๋ฐ ๋๋ฉ์ธ์ ์
๋ ฅํ์ฌ ํ
์คํธ ํต์ ํฉ๋๋ค: http://<์ค์์๋ฒ_IP>:8090",
|
| 1022 |
+
"net.title": "4. ๋คํธ์ํฌ ๋ฐ ํฌํธ ๊ตฌ์ฑ",
|
| 1023 |
+
"net.ports": "์ธํ๋ผ ์์คํ
์ฌ์ฉ ํฌํธ ํํฉ",
|
| 1024 |
+
"net.tb_serv": "์ฐ๋ ์๋น์ค",
|
| 1025 |
+
"net.tb_port": "๊ธฐ๋ณธ ํฌํธ",
|
| 1026 |
+
"net.tb_proto": "ํ๋กํ ์ฝ",
|
| 1027 |
+
"net.tb_desc": "์ค๋ช
",
|
| 1028 |
+
"net.tb_p1": "์ฝ์ด ํด๋ผ์ด์ธํธ REST & ํํธ๋นํธ ์ฐ๊ฒฐ ์ฐฝ๊ตฌ (์ธ๋ฐ์ด๋ ํ์ฉ ํ์)",
|
| 1029 |
+
"net.tb_p2": "ํ์ง ์ง์ ์จํจ๋ก์ง ๊ณ ์ ์ปค๋ฅํฐ ํฌํธ",
|
| 1030 |
+
"net.tb_p3": "์ฑ์ ์ PDF ๋ฌผ๋ฆฌ ์๋ณธ ํ์ผ ์ฝ๊ธฐ/์ฐ๊ธฐ ์คํ ๋ฆฌ์ง API",
|
| 1031 |
+
"net.tb_p4": "์ํฌํ๋ก์ฐ ์๋ํ ํ์ดํ๋ผ์ธ ํธ๋ฆฌ๊ฑฐ ์๋ํฌ์ธํธ",
|
| 1032 |
+
"net.firewall": "Ubuntu ๋ฐฉํ๋ฒฝ (UFW) ์ค์ ์คํฌ๋ฆฝํธ",
|
| 1033 |
+
"setup.title": "5. ์ค์ ๊ด๋ฆฌ ํ๊ฒฝ ์ด๊ธฐํ",
|
| 1034 |
+
"setup.admin": "5-1. ์ต์ด ๊ด๋ฆฌ์ ๊ณ์ ์ ๋ณด",
|
| 1035 |
+
"setup.admin_desc": "์ค์น๊ฐ ์ ์์ ์ผ๋ก ๋ง์ณ์ง๋ฉด ๋ฐ์ดํฐ๋ฒ ์ด์ค ์๋ ์คํฌ๋ฆฝํธ๋ฅผ ํตํด ์๋ ๊ด๋ฆฌ์ ๋ ์ฝ๋๊ฐ ์์ฑ๋ฉ๋๋ค:",
|
| 1036 |
+
"setup.tb_col": "์ค์ ์ ๋ณด",
|
| 1037 |
+
"setup.tb_val": "์ง์ ๋ ๊ธฐ๋ณธ ๊ฐ",
|
| 1038 |
+
"setup.tb_role": "๋ฑ๊ธ",
|
| 1039 |
+
"setup.group": "5-2. ๊ณต์ฅ ๊ทธ๋ฃน ๋ฐ ๋ก์ปฌ ํ๋กํ์ผ ํ ๋น",
|
| 1040 |
+
"setup.group_desc": "์ด๋๋ฏผ ๋ก๊ทธ์ธ ์๋ฃ ํ [๊ทธ๋ฃน ๊ด๋ฆฌ] ํญ์ผ๋ก ์ง์
ํ์ฌ ์ ์กฐ์ง์ ์ถ๊ฐํฉ๋๋ค. ๋ณธ์ฌ ์ค์ ์๋ฒ๋ฅผ ์ ์งํ๏ฟฝ๏ฟฝ๏ฟฝ์ ๊ฐ ๋ก์ปฌ ๊ณต์ฅ(์: ์ฒญ์ฃผ๊ณต์ฅ, ํ๊ฐ๋ฆฌ๊ณต์ฅ, ๋ฏธ๊ตญ๊ณต์ฅ)๋ง๋ค ๋ก์ปฌ DB ์ ์ ๋ฌธ์์ด ๋ฐ ๋ก์ปฌ MinIO/Neo4j ์ ๋ณด๋ฅผ ๋ค๋ฅด๊ฒ ์
๋ ฅํด ๋ฐ์ดํฐ๋ฅผ ์๋ฒฝํ ๊ฒฉ๋ฆฌํ ์ ์์ต๋๋ค.",
|
| 1041 |
+
"trouble.title": "6. ๋ฌธ์ ํด๊ฒฐ (Troubleshooting)",
|
| 1042 |
+
"trouble.q1": "๐ด Docker ์ปจํ
์ด๋ ๊ตฌ๋ ์ Permission Denied ๋ฐ์",
|
| 1043 |
+
"trouble.a1": "์ฌ์ฉ์ ๊ณ์ ์ด docker ๊ถํ ๊ทธ๋ฃน์ ํฌํจ๋์ง ์์ ๋ฐ์ํฉ๋๋ค. sudo usermod -aG docker $USER ๋ช
๋ น์ ์
๋ ฅํ ํ, ์ ํฐ๋ฏธ๋ ์ธ์
์ ์์ ํ ์ข
๋ฃํ๋ค๊ฐ ๋ค์ ๋ก๊ทธ์ธํด ์์ํ์ญ์์ค.",
|
| 1044 |
+
"trouble.q2": "๐ด \"ECONNREFUSED\" ์๋ฒ ์๋ต ์๋ฌ ์์ ",
|
| 1045 |
+
"trouble.a2": "์ค์ ์๋ฒ ์ธก์ API ์คํ ๋ฐ๋ชฌ ํ๋ก์ธ์ค๊ฐ ๊ธฐ๋๋์ง ์์๊ฑฐ๋ ํฌํธ๊ฐ ์ถฉ๋ํ ๊ฒฝ์ฐ์
๋๋ค. sudo systemctl status certbridge ์ํ ์กฐํ๋ฅผ ํตํด systemd ์๋น์ค ์์กด ์ ๋ฌด๋ฅผ ๊ฒ์ฌํ์ญ์์ค.",
|
| 1046 |
+
"trouble.q3": " Windows SmartScreen ์ฐจ๋จ ํ์
์ด ์ถ๋ ฅ๋ฉ๋๋ค.",
|
| 1047 |
+
"trouble.a3": "๋ณธ ํจํค์ง๋ ๋๋ฉ์ธ ํ๋ผ์ด๋น ๊ฐ๋ฐ ๋ณธ์ผ๋ก ์ฝ๋ ์ฌ์ด๋(Code Signing) ์๋ช
์๊ฐ ๊ฒฐ์ฌ๋์ด ์์ต๋๋ค. ํ์
ํ๋จ์ \"์ถ๊ฐ ์ ๋ณด\"๋ฅผ ํด๋ฆญํ ๋ค์, ๋ํ๋ \"์คํ\" ๋ฒํผ์ ์์ฌํ๊ณ ํด๋ฆญํด ์
์
์ ์์ํด ์ฃผ์๊ธฐ ๋ฐ๋๋๋ค."
|
| 1048 |
+
},
|
| 1049 |
+
en: {
|
| 1050 |
+
"sidebar.ver": "Installation Guide v0.1.0",
|
| 1051 |
+
"nav.req": "System Requirements",
|
| 1052 |
+
"nav.server": "Server Setup (Ubuntu)",
|
| 1053 |
+
"nav.client": "Client Setup (Windows)",
|
| 1054 |
+
"nav.network": "Network Config",
|
| 1055 |
+
"nav.setup": "Initial Config",
|
| 1056 |
+
"nav.trouble": "Troubleshooting",
|
| 1057 |
+
"hero.title": "CertBridge Server Deployment Guide",
|
| 1058 |
+
"hero.desc": "Step-by-step instructions to configure the central system environment on an Ubuntu server and set up Windows desktop clients.",
|
| 1059 |
+
"hero.badge": "๐ฆ v0.1.0 ยท Ubuntu 22.04+ ยท Windows 10+",
|
| 1060 |
+
"req.title": "1. System Requirements",
|
| 1061 |
+
"req.server_title": "๐ฅ๏ธ Server Configuration (Ubuntu OS)",
|
| 1062 |
+
"req.os": "Operating System",
|
| 1063 |
+
"req.ram": "RAM",
|
| 1064 |
+
"req.disk": "Disk Space",
|
| 1065 |
+
"req.net": "Network Connection",
|
| 1066 |
+
"req.client_title": "๐ป Client Environment (Windows)",
|
| 1067 |
+
"req.software": "๐ง Infrastructure Prerequisites (Server)",
|
| 1068 |
+
"req.tb_soft": "Software",
|
| 1069 |
+
"req.tb_ver": "Min Version",
|
| 1070 |
+
"req.tb_usage": "Usage",
|
| 1071 |
+
"req.tb_docker_desc": "Containerized databases and queue storage orchestration",
|
| 1072 |
+
"req.tb_compose_desc": "Multi-container environment running under unified stacks",
|
| 1073 |
+
"req.tb_node_desc": "CertBridge core Express API gateway server execution",
|
| 1074 |
+
"server.title": "2. Server Installation (Ubuntu)",
|
| 1075 |
+
"server.auto": "2-1. Automatic Shell Script Installation (Recommended)",
|
| 1076 |
+
"server.auto_desc": "Use setup.sh to automatically configure Docker, generate required secrets, connect databases, and register the systemd background service.",
|
| 1077 |
+
"server.manual": "2-2. Manual Step-by-Step Installation",
|
| 1078 |
+
"server.d_setup": "Install Docker Engine",
|
| 1079 |
+
"server.compose": "Launch Multi-Container Infrastructure Stack",
|
| 1080 |
+
"server.compose_desc": "Launch PostgreSQL, Redis, MinIO object storage, and Neo4j graph database as a single background service stack.",
|
| 1081 |
+
"server.env_setup": "API Configuration File (.env)",
|
| 1082 |
+
"server.warn_title": "โ ๏ธ Production Security Notice",
|
| 1083 |
+
"server.warn_desc": "Make sure to change JWT_SECRET keys, default database passwords, and MinIO root credential values before deploying in a production network.",
|
| 1084 |
+
"server.api_start": "Install Dependencies and Start API Gateway",
|
| 1085 |
+
"client.title": "3. Desktop Client Setup (Windows)",
|
| 1086 |
+
"client.s1_title": "Download Installer Package",
|
| 1087 |
+
"client.s1_desc": "Get the official desktop application package (e.g. CertBridge_0.1.0_x64-setup.exe) from HuggingFace or your localized internal CDN.",
|
| 1088 |
+
"client.s2_title": "Install & Choose Language Profile",
|
| 1089 |
+
"client.s2_desc": "Follow the wizard setup steps, verify the target path, select your default active language, and complete the installation.",
|
| 1090 |
+
"client.s3_title": "Central Connection Handshake Test",
|
| 1091 |
+
"client.s3_desc": "Open the application, click the Settings (โ๏ธ) icon, and enter the active central API server endpoint address: http://<server_ip>:8090",
|
| 1092 |
+
"net.title": "4. Network & Ports Configurations",
|
| 1093 |
+
"net.ports": "System Port Allocations",
|
| 1094 |
+
"net.tb_serv": "Linked Service",
|
| 1095 |
+
"net.tb_port": "Default Port",
|
| 1096 |
+
"net.tb_proto": "Protocol",
|
| 1097 |
+
"net.tb_desc": "Description",
|
| 1098 |
+
"net.tb_p1": "Core client REST & Heartbeat channel (Inbound access required)",
|
| 1099 |
+
"net.tb_p2": "Neo4j Bolt protocol high-speed graph driver interface",
|
| 1100 |
+
"net.tb_p3": "S3-compatible API for original PDF quality certificate storage",
|
| 1101 |
+
"net.tb_p4": "n8n automation pipeline webhook gateway",
|
| 1102 |
+
"net.firewall": "Ubuntu Firewall (UFW) Configuration Script",
|
| 1103 |
+
"setup.title": "5. Initial Admin Configuration",
|
| 1104 |
+
"setup.admin": "5-1. Default Administrator Credentials",
|
| 1105 |
+
"setup.admin_desc": "The DB seeding script creates the default admin user account as follows:",
|
| 1106 |
+
"setup.tb_col": "Property",
|
| 1107 |
+
"setup.tb_val": "Default Value",
|
| 1108 |
+
"setup.tb_role": "Role",
|
| 1109 |
+
"setup.group": "5-2. Group Isolation & Local Infrastructure Profiles",
|
| 1110 |
+
"setup.group_desc": "Log in as administrator and go to the Groups tab to register your factory groups. This allows you to utilize completely separated database credentials, MinIO buckets, and Neo4j connections per factory group while using a single core central system.",
|
| 1111 |
+
"trouble.title": "6. Troubleshooting Guidelines",
|
| 1112 |
+
"trouble.q1": "๐ด Docker: Permission Denied Error",
|
| 1113 |
+
"trouble.a1": "Add your user account to the docker permission group using: sudo usermod -aG docker $USER. Restart your terminal session and rerun setup.",
|
| 1114 |
+
"trouble.q2": "๐ด 'ECONNREFUSED' Connection Error",
|
| 1115 |
+
"trouble.a2": "Check if the API daemon process is running on port 8090. Run: sudo systemctl status certbridge to verify the systemd background state.",
|
| 1116 |
+
"trouble.q3": "๐ก Windows SmartScreen Popup Block Warning",
|
| 1117 |
+
"trouble.a3": "This is normal for dev packages that lack a certified code-signing certificate. Click 'More Info' and choose 'Run Anyway' to complete the installation."
|
| 1118 |
+
}
|
| 1119 |
+
};
|
| 1120 |
+
|
| 1121 |
+
function changeLanguage(lang) {
|
| 1122 |
+
document.documentElement.lang = lang;
|
| 1123 |
+
localStorage.setItem("certbridge_language", lang);
|
| 1124 |
+
document.getElementById("lang-select").value = lang;
|
| 1125 |
+
|
| 1126 |
+
// Update all elements with data-i18n attribute
|
| 1127 |
+
const elements = document.querySelectorAll("[data-i18n]");
|
| 1128 |
+
elements.forEach(el => {
|
| 1129 |
+
const key = el.getAttribute("data-i18n");
|
| 1130 |
+
if (i18n[lang] && i18n[lang][key]) {
|
| 1131 |
+
el.innerHTML = i18n[lang][key];
|
| 1132 |
+
} else if (i18n["en"] && i18n["en"][key]) {
|
| 1133 |
+
el.innerHTML = i18n["en"][key];
|
| 1134 |
+
}
|
| 1135 |
+
});
|
| 1136 |
+
|
| 1137 |
+
// Update HTML Title dynamically
|
| 1138 |
+
if (lang === "ko") {
|
| 1139 |
+
document.getElementById("html-title").innerText = "CertBridge ์ค์น ๋ฐ ์
์
๊ฐ์ด๋";
|
| 1140 |
+
} else if (lang === "zh") {
|
| 1141 |
+
document.getElementById("html-title").innerText = "CertBridge ๅฎ่ฃ
ไธ้
็ฝฎๆๅ";
|
| 1142 |
+
} else if (lang === "ja") {
|
| 1143 |
+
document.getElementById("html-title").innerText = "CertBridge ๆง็ฏใป่จญๅฎใฌใคใ";
|
| 1144 |
+
} else if (lang === "hu") {
|
| 1145 |
+
document.getElementById("html-title").innerText = "CertBridge Szervertelepรญtรฉsi รtmutatรณ";
|
| 1146 |
+
} else if (lang === "de") {
|
| 1147 |
+
document.getElementById("html-title").innerText = "CertBridge Server-Bereitstellungshandbuch";
|
| 1148 |
+
} else if (lang === "fr") {
|
| 1149 |
+
document.getElementById("html-title").innerText = "Guide de dรฉploiement serveur CertBridge";
|
| 1150 |
+
} else if (lang === "es") {
|
| 1151 |
+
document.getElementById("html-title").innerText = "Guรญa de despliegue de servidor CertBridge";
|
| 1152 |
+
} else if (lang === "pt") {
|
| 1153 |
+
document.getElementById("html-title").innerText = "Guia de implantaรงรฃo de servidor CertBridge";
|
| 1154 |
+
} else {
|
| 1155 |
+
document.getElementById("html-title").innerText = "CertBridge Server Deployment Guide";
|
| 1156 |
+
}
|
| 1157 |
+
|
| 1158 |
+
console.log(`๐ Setup Guide Language updated to: ${lang}`);
|
| 1159 |
+
}
|
| 1160 |
+
|
| 1161 |
+
// Initializer
|
| 1162 |
+
document.addEventListener("DOMContentLoaded", () => {
|
| 1163 |
+
const getLang = () => localStorage.getItem("certbridge_language") || "ko";
|
| 1164 |
+
changeLanguage(getLang());
|
| 1165 |
+
|
| 1166 |
+
// Storage listener for instant sync
|
| 1167 |
+
window.addEventListener("storage", (e) => {
|
| 1168 |
+
if (e.key === "certbridge_language") {
|
| 1169 |
+
changeLanguage(e.newValue || "ko");
|
| 1170 |
+
}
|
| 1171 |
+
});
|
| 1172 |
+
|
| 1173 |
+
// Polling fallback
|
| 1174 |
+
setInterval(() => {
|
| 1175 |
+
const currentLang = document.documentElement.lang;
|
| 1176 |
+
const targetLang = getLang();
|
| 1177 |
+
if (currentLang !== targetLang) {
|
| 1178 |
+
changeLanguage(targetLang);
|
| 1179 |
+
}
|
| 1180 |
+
}, 500);
|
| 1181 |
+
|
| 1182 |
+
// ScrollSpy logic
|
| 1183 |
+
const sections = document.querySelectorAll('.section');
|
| 1184 |
+
const navLinks = document.querySelectorAll('#nav a');
|
| 1185 |
+
const observer = new IntersectionObserver(entries => {
|
| 1186 |
+
entries.forEach(e => {
|
| 1187 |
+
if (e.isIntersecting) {
|
| 1188 |
+
navLinks.forEach(l => l.classList.remove('active'));
|
| 1189 |
+
const id = e.target.id;
|
| 1190 |
+
const link = document.querySelector(`#nav a[href="#${id}"]`);
|
| 1191 |
+
if (link) link.classList.add('active');
|
| 1192 |
+
}
|
| 1193 |
+
});
|
| 1194 |
+
}, { threshold: 0.2 });
|
| 1195 |
+
sections.forEach(s => observer.observe(s));
|
| 1196 |
+
});
|
| 1197 |
+
|
| 1198 |
+
// Copy to clipboard helper
|
| 1199 |
+
function copyCode(btn) {
|
| 1200 |
+
const pre = btn.closest('.code-wrap').querySelector('pre');
|
| 1201 |
+
navigator.clipboard.writeText(pre.textContent).then(() => {
|
| 1202 |
+
const lang = document.documentElement.lang || "ko";
|
| 1203 |
+
const msg = lang === "ko" ? "๋ณต์ฌ๋จ!" : "Copied!";
|
| 1204 |
+
const originalText = btn.textContent;
|
| 1205 |
+
btn.textContent = msg;
|
| 1206 |
+
setTimeout(() => {
|
| 1207 |
+
btn.textContent = originalText;
|
| 1208 |
+
}, 2000);
|
| 1209 |
+
});
|
| 1210 |
+
}
|
| 1211 |
+
</script>
|
| 1212 |
+
</body>
|
| 1213 |
+
</html>
|