Added website

This commit is contained in:
fuomag9
2025-11-15 11:07:33 +01:00
parent d071fbf90e
commit ffd7ded175
7 changed files with 473 additions and 0 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 696 KiB

+154
View File
@@ -0,0 +1,154 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Caddy Proxy Manager a luxurious, dark-mode control center for Caddy Server deployments." />
<title>Caddy Proxy Manager · Control Every Edge</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="styles.css" />
<script defer src="scripts.js"></script>
</head>
<body>
<div class="aurora" aria-hidden="true"></div>
<header class="hero" id="top">
<nav class="nav">
<div class="logo">Caddy Proxy Manager</div>
<div class="nav-links">
<a href="#features">Features</a>
<a href="#showcase">Showcase</a>
<a href="#architecture">Architecture</a>
<a href="#deployment">Deploy</a>
<a href="https://github.com/fuomag9/caddy-proxy-manager" target="_blank" rel="noreferrer">GitHub</a>
</div>
</nav>
<div class="hero-content">
<p class="eyebrow">Web UI for Caddy Server</p>
<h1>Modern interface for Caddy's automatic HTTPS.</h1>
<p class="lede">
Caddy Proxy Manager provides a web-based control panel for managing reverse proxies,
certificates, and configurations. Built with Next.js and featuring a clean dark interface.
</p>
<div class="cta-group">
<a class="cta primary" href="https://github.com/fuomag9/caddy-proxy-manager" target="_blank" rel="noreferrer">View on GitHub</a>
<a class="cta secondary" href="#deployment">Get Started</a>
</div>
<div class="metrics">
<div>
<span class="metric-value">Docker</span>
<span class="metric-label">Quick deployment</span>
</div>
<div>
<span class="metric-value">Full</span>
<span class="metric-label">Audit history</span>
</div>
<div>
<span class="metric-value">Auto</span>
<span class="metric-label">TLS with ACME</span>
</div>
</div>
</div>
</header>
<main>
<section class="panel" id="features">
<div class="section-heading">
<p class="eyebrow">Key Features</p>
<h2>Streamlined Caddy management.</h2>
<p class="lede">Manage your Caddy server configuration through an intuitive web interface with built-in security and audit logging.</p>
</div>
<div class="feature-grid">
<article class="card">
<h3>Reverse Proxy Management</h3>
<p>Configure reverse proxies, set custom headers, and manage domain routing through an easy-to-use web interface.</p>
</article>
<article class="card">
<h3>Certificate Management</h3>
<p>Automatic ACME certificate provisioning with Cloudflare DNS-01 support, plus manual certificate imports for custom setups.</p>
</article>
<article class="card">
<h3>Audit Logging</h3>
<p>Complete audit trail of all configuration changes with timestamps and user attribution for accountability.</p>
</article>
<article class="card">
<h3>Built-in Security</h3>
<p>Strong password requirements, secure session management, rate limiting, and HSTS headers protect your installation.</p>
</article>
</div>
</section>
<section class="panel glass" id="showcase">
<div class="section-heading">
<p class="eyebrow">Screenshots</p>
<h2>See the interface.</h2>
</div>
<div class="showcase-grid">
<!-- Replace placeholder images by copying your screenshots into docs/assets/screenshots and updating the src paths below. -->
<figure>
<img src="assets/screenshots/dashboard-main.png" alt="Primary dashboard overview" loading="lazy" />
<figcaption>Dashboard overview showing proxy hosts, certificates, and system status.</figcaption>
</figure>
<figure>
<img src="assets/screenshots/certificates.png" alt="Certificate lifecycle manager" loading="lazy" />
<figcaption>Certificate management with ACME automation and manual imports.</figcaption>
</figure>
<figure>
<img src="assets/screenshots/proxy-editor.png" alt="Proxy host editor" loading="lazy" />
<figcaption>Proxy host configuration with validation and testing.</figcaption>
</figure>
</div>
</section>
<section class="panel split" id="architecture">
<div>
<p class="eyebrow">Technology Stack</p>
<h2>Next.js, React, Drizzle ORM, and Caddy.</h2>
<p class="lede">Built with modern web technologies and integrates directly with Caddy's Admin API for real-time configuration management.</p>
</div>
<ul class="pillars">
<li>
<span>Next.js App Router</span>
<p>Server-side rendering with React Server Components for fast page loads and smooth interactions.</p>
</li>
<li>
<span>SQLite Database</span>
<p>Drizzle ORM with SQLite for storing proxy configurations, certificates, and audit logs.</p>
</li>
<li>
<span>Caddy Admin API</span>
<p>Direct integration with Caddy's JSON API for applying configuration changes in real-time.</p>
</li>
</ul>
</section>
<section class="panel" id="deployment">
<div class="section-heading">
<p class="eyebrow">Quick Setup</p>
<h2>Deploy with Docker Compose.</h2>
<p class="lede">Get started quickly with Docker Compose. The setup includes persistent storage and environment-based configuration.</p>
</div>
<div class="code-block">
<pre><code> # Clone and enter
git clone https://github.com/fuomag9/caddy-proxy-manager.git
cd caddy-proxy-manager
# Configure secrets
cp .env.example .env
# ADMIN_USERNAME=your-admin
# ADMIN_PASSWORD=your-strong-password
# SESSION_SECRET=$(openssl rand -base64 32)
# Launch the stack
docker compose up -d
</code></pre>
</div>
</section>
</main>
<footer>
<p>© <span id="year"></span> Caddy Proxy Manager. Crafted with intent.</p>
</footer>
</body>
</html>
+22
View File
@@ -0,0 +1,22 @@
const yearEl = document.getElementById('year');
if (yearEl) {
yearEl.textContent = new Date().getFullYear();
}
const navLinks = document.querySelectorAll('a[href^="#"]');
navLinks.forEach((link) => {
link.addEventListener('click', (event) => {
const targetId = link.getAttribute('href');
if (!targetId || targetId === '#') {
return;
}
const target = document.querySelector(targetId);
if (!target) {
return;
}
event.preventDefault();
target.scrollIntoView({ behavior: 'smooth' });
});
});
+296
View File
@@ -0,0 +1,296 @@
:root {
color-scheme: dark;
--bg: #03050a;
--bg-panel: rgba(8, 11, 20, 0.85);
--bg-panel-strong: rgba(18, 22, 33, 0.9);
--text: #f5f7fb;
--muted: #9aa8c7;
--accent: #8f8cff;
--accent-strong: #5d5bff;
--border: rgba(255, 255, 255, 0.08);
--gradient: radial-gradient(circle at top left, rgba(128, 118, 255, 0.45), transparent 55%),
radial-gradient(circle at top right, rgba(33, 212, 253, 0.35), transparent 60%);
}
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
background: var(--bg);
color: var(--text);
min-height: 100vh;
line-height: 1.6;
}
img {
max-width: 100%;
border-radius: 18px;
border: 1px solid rgba(255, 255, 255, 0.05);
background: rgba(255, 255, 255, 0.02);
object-fit: cover;
}
h1,
h2,
h3,
h4,
h5 {
font-weight: 600;
line-height: 1.2;
margin: 0 0 0.6em;
}
p {
margin: 0 0 1em;
color: var(--muted);
}
code,
pre {
font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
}
.aurora {
position: fixed;
inset: 0;
background-image: var(--gradient);
filter: blur(120px);
opacity: 0.8;
z-index: 0;
}
.hero {
position: relative;
isolation: isolate;
padding: 3rem clamp(1.25rem, 5vw, 5rem) 2rem;
overflow: hidden;
}
.nav {
display: flex;
justify-content: space-between;
align-items: center;
gap: 1.5rem;
padding-bottom: 2rem;
border-bottom: 1px solid var(--border);
}
.logo {
font-weight: 600;
letter-spacing: 0.08em;
text-transform: uppercase;
}
.nav-links {
display: flex;
gap: 1.5rem;
flex-wrap: wrap;
}
.nav a {
color: var(--muted);
text-decoration: none;
font-size: 0.95rem;
transition: color 0.3s ease;
}
.nav a:hover {
color: var(--text);
}
.hero-content {
max-width: 880px;
margin: 3rem auto 0;
text-align: left;
}
.eyebrow {
text-transform: uppercase;
letter-spacing: 0.25em;
font-size: 0.78rem;
color: var(--accent);
margin-bottom: 0.8rem;
}
.lede {
font-size: 1.05rem;
}
.cta-group {
display: flex;
gap: 1rem;
flex-wrap: wrap;
margin: 2rem 0 2.5rem;
}
.cta {
padding: 0.85rem 1.8rem;
border-radius: 999px;
text-decoration: none;
font-weight: 600;
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.cta.primary {
color: var(--bg);
background: linear-gradient(135deg, var(--accent), var(--accent-strong));
box-shadow: 0 10px 30px rgba(140, 137, 255, 0.45);
}
.cta.secondary {
color: var(--text);
border: 1px solid var(--border);
background: rgba(255, 255, 255, 0.05);
}
.cta:hover {
transform: translateY(-3px);
}
.metrics {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
gap: 1.5rem;
padding-top: 1rem;
border-top: 1px solid var(--border);
}
.metric-value {
font-size: 1.8rem;
font-weight: 600;
display: block;
}
main {
position: relative;
z-index: 1;
padding: 0 clamp(1.25rem, 5vw, 5rem) 5rem;
}
.panel {
margin: 3rem auto;
padding: clamp(2rem, 4vw, 3rem);
border-radius: 32px;
background: var(--bg-panel);
border: 1px solid var(--border);
box-shadow: 0 25px 60px rgba(0, 0, 0, 0.45);
}
.panel.glass {
background: rgba(8, 11, 20, 0.65);
backdrop-filter: blur(16px);
}
.section-heading {
text-align: left;
max-width: 720px;
}
.feature-grid,
.details-grid {
margin-top: 2rem;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 1.5rem;
}
.card,
.details-grid article {
padding: 1.5rem;
background: var(--bg-panel-strong);
border-radius: 22px;
border: 1px solid var(--border);
}
.showcase-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
gap: 1.5rem;
margin-top: 2rem;
}
figcaption {
font-size: 0.9rem;
color: var(--muted);
margin-top: 0.75rem;
}
.split {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
align-items: start;
gap: 2.5rem;
}
.pillars {
list-style: none;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
gap: 1.5rem;
}
.pillars li {
padding: 1.5rem;
border-radius: 20px;
background: rgba(20, 24, 36, 0.85);
border: 1px solid var(--border);
}
.pillars span {
display: block;
font-weight: 600;
margin-bottom: 0.5rem;
}
.code-block {
margin: 2rem 0;
border-radius: 24px;
background: rgba(10, 14, 24, 0.9);
border: 1px solid var(--border);
overflow: hidden;
}
.code-block pre {
margin: 0;
padding: 2rem;
white-space: pre-wrap;
color: #d7e1ff;
}
.panel.cta {
text-align: center;
background: linear-gradient(135deg, rgba(93, 91, 255, 0.9), rgba(33, 212, 253, 0.75));
border: none;
}
.panel.cta p,
.panel.cta h2,
.panel.cta .cta {
color: #05070f;
}
footer {
text-align: center;
padding: 2rem;
color: var(--muted);
}
@media (max-width: 768px) {
.nav {
flex-direction: column;
}
.nav-links {
justify-content: center;
}
.hero-content {
text-align: left;
margin-top: 2rem;
}
}