Replace docs with comprehensive user guide: 75+ templates, how-to-deploy, features, pricing, integrations
- What You Can Do section with all 6 key capabilities - Complete 75+ app template catalog by category - Step-by-step deployment workflow - All 8 platform features documented - Pricing & licensing (Free vs Premium) - Infrastructure integrations (Technitium DNS, Pi-hole, WireGuard, DashCA) - Troubleshooting guide - Premium features: Swarm, Recipes, SSO
This commit is contained in:
@@ -9,377 +9,328 @@ export default function DocsPage() {
|
||||
<div className="flex flex-col min-h-screen bg-surface-950 text-surface-50">
|
||||
<Navbar />
|
||||
|
||||
{/* Hero Section */}
|
||||
{/* Hero */}
|
||||
<section className="relative py-16 sm:py-20 lg:py-24">
|
||||
<div className="absolute inset-0 -z-10">
|
||||
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-96 h-96 bg-brand-500/20 rounded-full blur-3xl opacity-30 animate-pulse" />
|
||||
</div>
|
||||
|
||||
<div className="mx-auto max-w-4xl px-4 sm:px-6 lg:px-8">
|
||||
<h1 className="text-4xl sm:text-5xl lg:text-6xl font-bold mb-6">
|
||||
Getting <span className="text-brand-400">Started</span>
|
||||
How to Use <span className="text-brand-400">DashCaddy</span>
|
||||
</h1>
|
||||
<p className="text-xl text-surface-300 max-w-2xl">
|
||||
Get DashCaddy up and running on your server in just a few minutes.
|
||||
Self-host Docker apps in minutes. DNS, SSL, and routing handled automatically.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Main Content */}
|
||||
<section className="relative py-12 sm:py-16 lg:py-20">
|
||||
{/* Table of Contents */}
|
||||
<section className="py-8">
|
||||
<div className="mx-auto max-w-4xl px-4 sm:px-6 lg:px-8">
|
||||
{/* Table of Contents */}
|
||||
<div className="mb-16 rounded-lg border border-surface-700/50 bg-surface-800/50 p-8">
|
||||
<h2 className="text-2xl font-bold text-surface-50 mb-6">Table of Contents</h2>
|
||||
<ul className="space-y-3">
|
||||
<li>
|
||||
<a href="#prerequisites" className="text-brand-400 hover:text-brand-300 transition-colors flex items-center gap-2">
|
||||
<span>→</span> Prerequisites
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#installation" className="text-brand-400 hover:text-brand-300 transition-colors flex items-center gap-2">
|
||||
<span>→</span> Installation
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#configuration" className="text-brand-400 hover:text-brand-300 transition-colors flex items-center gap-2">
|
||||
<span>→</span> Configuration
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#first-run" className="text-brand-400 hover:text-brand-300 transition-colors flex items-center gap-2">
|
||||
<span>→</span> First Run
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#troubleshooting" className="text-brand-400 hover:text-brand-300 transition-colors flex items-center gap-2">
|
||||
<span>→</span> Troubleshooting
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div className="rounded-lg border border-surface-700/50 bg-surface-800/50 p-8">
|
||||
<h2 className="text-2xl font-bold text-surface-50 mb-6">What You Can Do</h2>
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||
{[
|
||||
{ icon: '🚀', title: 'Deploy 75+ Apps', desc: 'Plex, Nextcloud, Jellyfin, Sonarr, and more' },
|
||||
{ icon: '⚡', title: 'Automatic SSL', desc: 'Every app gets a valid HTTPS certificate' },
|
||||
{ icon: '🌐', title: 'Private DNS', desc: 'Technitium DNS for .sami and .home zones' },
|
||||
{ icon: '🔒', title: 'One-Click CA', desc: 'Install internal root cert on all devices' },
|
||||
{ icon: '📺', title: 'Media Automation', desc: 'ARR Smart Connect: Plex + Radarr + Sonarr in one click' },
|
||||
{ icon: '🐝', title: 'Docker Swarm', desc: 'Deploy across a cluster of servers (Premium)' },
|
||||
].map(({ icon, title, desc }) => (
|
||||
<div key={title} className="flex gap-3 p-4 rounded-lg bg-surface-700/30">
|
||||
<span className="text-2xl">{icon}</span>
|
||||
<div>
|
||||
<div className="font-semibold text-surface-50">{title}</div>
|
||||
<div className="text-sm text-surface-400">{desc}</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* App Templates */}
|
||||
<section className="py-12 sm:py-16">
|
||||
<div className="mx-auto max-w-4xl px-4 sm:px-6 lg:px-8">
|
||||
<h2 className="text-3xl font-bold text-surface-50 mb-8">75+ App Templates</h2>
|
||||
{[
|
||||
{ cat: 'Media Streaming', icon: '🎬', apps: 'Plex, Jellyfin, Emby, Navidrome, Calibre-Web, Kavita, Komga, Audiobookshelf, Airsonic' },
|
||||
{ cat: 'Media Automation', icon: '📺', apps: 'Sonarr, Radarr, Prowlarr, Bazarr, Lidarr, Readarr, Tautulli, Seerr' },
|
||||
{ cat: 'Downloads', icon: '⬇️', apps: 'qBittorrent, Transmission, SABnzbd, NZBGet, JDownloader 2' },
|
||||
{ cat: 'DNS & Networking', icon: '🌐', apps: 'Technitium DNS, BIND9, PowerDNS, CoreDNS, Pi-hole, WireGuard VPN' },
|
||||
{ cat: 'Security', icon: '🔒', apps: 'DashCA, Vaultwarden, Authentik, CrowdSec' },
|
||||
{ cat: 'DevOps', icon: '⚙️', apps: 'Gitea, Jenkins, Drone CI, VS Code Server' },
|
||||
{ cat: 'Productivity', icon: '📋', apps: 'Nextcloud, Outline, BookStack, Standard Notes, Trilium, Mealie, Excalidraw, Actual Budget' },
|
||||
{ cat: 'Database', icon: '🗄️', apps: 'PostgreSQL, Redis, MongoDB, Adminer' },
|
||||
{ cat: 'Photos', icon: '📷', apps: 'Immich, PhotoPrism' },
|
||||
{ cat: 'Home Automation', icon: '🏠', apps: 'Home Assistant, Node-RED' },
|
||||
{ cat: 'Communication', icon: '💬', apps: 'Rocket.Chat, Matrix Synapse, Roundcube, Docker Mailserver' },
|
||||
{ cat: 'Gaming', icon: '🎮', apps: 'Minecraft Server, Valheim Server' },
|
||||
].map(({ cat, icon, apps }) => (
|
||||
<div key={cat} className="mb-6 p-5 rounded-lg border border-surface-700/40 bg-surface-800/20">
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<span>{icon}</span>
|
||||
<span className="font-semibold text-brand-400">{cat}</span>
|
||||
</div>
|
||||
<p className="text-surface-300 text-sm">{apps}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* How Deployment Works */}
|
||||
<section className="py-12 sm:py-16 bg-surface-900/30">
|
||||
<div className="mx-auto max-w-4xl px-4 sm:px-6 lg:px-8">
|
||||
<h2 className="text-3xl font-bold text-surface-50 mb-8">How App Deployment Works</h2>
|
||||
|
||||
<div className="space-y-6">
|
||||
{[
|
||||
{
|
||||
step: '1',
|
||||
title: 'Choose an App',
|
||||
desc: 'Browse by category or search. Each template includes the Docker image, port mappings, volume mounts, and secrets configuration.',
|
||||
},
|
||||
{
|
||||
step: '2',
|
||||
title: 'Configure Routing',
|
||||
desc: 'Pick subdomain mode (plex.yourdomain.com) or subdirectory mode (yourdomain.com/sonarr). Subdomain needs DNS; subdirectory works immediately.',
|
||||
},
|
||||
{
|
||||
step: '3',
|
||||
title: 'Set Secrets',
|
||||
desc: 'DashCaddy auto-generates secure passwords for admin accounts and API keys. You can also provide your own.',
|
||||
},
|
||||
{
|
||||
step: '4',
|
||||
title: 'Deploy',
|
||||
desc: 'DashCaddy pulls the image, creates the container, configures Caddy for reverse proxy, and issues a Let\'s Encrypt SSL certificate. Your app is live in minutes.',
|
||||
},
|
||||
].map(({ step, title, desc }) => (
|
||||
<div key={step} className="flex gap-5">
|
||||
<div className="flex-shrink-0 w-10 h-10 rounded-full bg-brand-500/20 text-brand-400 flex items-center justify-center font-bold text-lg">
|
||||
{step}
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-xl font-semibold text-surface-50 mb-2">{title}</h3>
|
||||
<p className="text-surface-300">{desc}</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Key Features */}
|
||||
<section className="py-12 sm:py-16">
|
||||
<div className="mx-auto max-w-4xl px-4 sm:px-6 lg:px-8">
|
||||
<h2 className="text-3xl font-bold text-surface-50 mb-8">Platform Features</h2>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
{[
|
||||
{
|
||||
icon: '⚡',
|
||||
title: 'Automatic SSL',
|
||||
body: 'Caddy handles HTTPS automatically via Let\'s Encrypt. Every app gets a valid certificate — no manual certbot, no renewals, no expired certs.',
|
||||
},
|
||||
{
|
||||
icon: '🌐',
|
||||
title: 'Private DNS Zones',
|
||||
body: 'Deploy Technitium DNS Server to manage .sami or .home zones. plex.sami, vaultwarden.sami, jellyfin.sami — all resolve internally on your network.',
|
||||
},
|
||||
{
|
||||
icon: '🔒',
|
||||
title: 'DashCA — One-Click CA',
|
||||
body: 'Deploy once, visit http://ca.sami from any device, install the root certificate. All your internal *.sami domains show as fully trusted. Works on Windows, macOS, Linux, iOS, Android.',
|
||||
},
|
||||
{
|
||||
icon: '📺',
|
||||
title: 'ARR Smart Connect',
|
||||
body: 'One-click setup connecting Plex + Radarr + Sonarr + Prowlarr + Seerr. Detects your Plex libraries, wires up Radarr/Sonarr automatically, configures indexers. Minutes instead of days.',
|
||||
},
|
||||
{
|
||||
icon: '🔐',
|
||||
title: 'TOTP 2FA',
|
||||
body: 'The dashboard itself supports optional TOTP two-factor authentication. Enable it in Settings to protect admin access.',
|
||||
},
|
||||
{
|
||||
icon: '🐝',
|
||||
title: 'Docker Swarm (Premium)',
|
||||
body: 'Scale beyond one server. Deploy apps across a cluster of multiple servers from a single DashCaddy control plane.',
|
||||
},
|
||||
{
|
||||
icon: '🍯',
|
||||
title: 'Recipes (Premium)',
|
||||
body: 'One-click app stacks — deploy a complete "media server" or "homelab" in a single action instead of deploying apps one by one.',
|
||||
},
|
||||
{
|
||||
icon: '🔑',
|
||||
title: 'SSO (Premium)',
|
||||
body: 'Connect Authentik as your identity provider. One login for DashCaddy, Nextcloud, Jellyfin, Gitea, and any OAuth2/OIDC-compatible app.',
|
||||
},
|
||||
].map(({ icon, title, body }) => (
|
||||
<div key={title} className="p-6 rounded-lg border border-surface-700/40 bg-surface-800/20">
|
||||
<div className="flex items-center gap-3 mb-3">
|
||||
<span className="text-2xl">{icon}</span>
|
||||
<h3 className="text-lg font-semibold text-surface-50">{title}</h3>
|
||||
</div>
|
||||
<p className="text-surface-300 text-sm leading-relaxed">{body}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Pricing */}
|
||||
<section className="py-12 sm:py-16 bg-surface-900/30">
|
||||
<div className="mx-auto max-w-4xl px-4 sm:px-6 lg:px-8">
|
||||
<h2 className="text-3xl font-bold text-surface-50 mb-8">Pricing & Licensing</h2>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 mb-8">
|
||||
{/* Free */}
|
||||
<div className="rounded-xl border border-surface-600 bg-surface-800/40 p-8">
|
||||
<div className="text-surface-400 text-sm font-medium mb-1">Free</div>
|
||||
<div className="text-3xl font-bold text-surface-50 mb-4">$0 <span className="text-lg font-normal text-surface-400">forever</span></div>
|
||||
<ul className="space-y-3">
|
||||
{[
|
||||
'Deploy unlimited apps',
|
||||
'75+ app templates',
|
||||
'Automatic SSL certificates',
|
||||
'Docker management dashboard',
|
||||
'Subdomain + subdirectory routing',
|
||||
'Built-in DNS integration',
|
||||
'TOTP 2FA on dashboard',
|
||||
].map(f => (
|
||||
<li key={f} className="flex items-start gap-2 text-surface-300 text-sm">
|
||||
<span className="text-green-400 mt-0.5">✓</span>
|
||||
{f}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<Link href="/pricing" className="mt-6 block text-center py-3 px-6 rounded-lg bg-surface-700 hover:bg-surface-600 text-surface-200 font-medium transition-colors">
|
||||
Get Started Free
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{/* Premium */}
|
||||
<div className="rounded-xl border-2 border-brand-500/60 bg-surface-800/60 p-8 relative">
|
||||
<div className="absolute -top-3 left-6 px-3 py-1 bg-brand-500 rounded-full text-xs font-bold text-white">
|
||||
Premium
|
||||
</div>
|
||||
<div className="text-surface-400 text-sm font-medium mb-1">Premium</div>
|
||||
<div className="text-3xl font-bold text-surface-50 mb-1">$25 <span className="text-lg font-normal text-surface-400">/ month</span></div>
|
||||
<p className="text-surface-400 text-sm mb-4">or $99/year — all premium features</p>
|
||||
<ul className="space-y-3 mb-6">
|
||||
{[
|
||||
'Everything in Core',
|
||||
'SSO — Authentik single sign-on',
|
||||
'Recipes — one-click app stacks',
|
||||
'Docker Swarm cluster management',
|
||||
'Priority support',
|
||||
].map(f => (
|
||||
<li key={f} className="flex items-start gap-2 text-surface-300 text-sm">
|
||||
<span className="text-brand-400 mt-0.5">✓</span>
|
||||
{f}
|
||||
</li>
|
||||
))}
|
||||
{['premium_1m: $25/mo', 'premium_3m: $50', 'premium_6m: $65', 'premium_12m: $99/yr'].map((p, i) => (
|
||||
<li key={p} className="flex items-start gap-2 text-surface-400 text-xs ml-4">
|
||||
{p}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<Link href="/pricing" className="block text-center py-3 px-6 rounded-lg bg-brand-500 hover:bg-brand-400 text-white font-semibold transition-colors">
|
||||
Get Premium
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Prerequisites Section */}
|
||||
<section id="prerequisites" className="mb-16">
|
||||
<h2 className="text-3xl font-bold text-surface-50 mb-6 flex items-center gap-3">
|
||||
<span className="text-brand-400">📋</span> Prerequisites
|
||||
</h2>
|
||||
<p className="text-surface-300 mb-6 leading-relaxed">
|
||||
Before you begin, ensure you have the following installed on your server:
|
||||
</p>
|
||||
<div className="rounded-lg border border-surface-700/50 bg-surface-900/50 p-6 space-y-4">
|
||||
<div className="flex items-start gap-4">
|
||||
<div className="text-xl flex-shrink-0">🐳</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-surface-50 mb-1">Docker</h3>
|
||||
<p className="text-sm text-surface-400">Version 20.10+ required. <a href="https://docs.docker.com/get-docker/" className="text-brand-400 hover:text-brand-300">Install Docker</a></p>
|
||||
</div>
|
||||
<div className="p-4 rounded-lg bg-surface-800/40 border border-surface-700/40 text-sm text-surface-300">
|
||||
<strong className="text-surface-100">License model:</strong> One machine at a time. Machine-bound fingerprint. Subscriptions cancel at period end. 7-day grace period on failed payments. Deactivate anytime to move to a new machine. No free trial.
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Infrastructure Integrations */}
|
||||
<section className="py-12 sm:py-16">
|
||||
<div className="mx-auto max-w-4xl px-4 sm:px-6 lg:px-8">
|
||||
<h2 className="text-3xl font-bold text-surface-50 mb-8">Infrastructure Integrations</h2>
|
||||
|
||||
{[
|
||||
{
|
||||
title: 'Technitium DNS Server',
|
||||
icon: '🌐',
|
||||
desc: 'Self-hosted DNS with web UI. Manage private zones (.sami, .home) on your local network. Supports DNSSEC, DNS-over-HTTPS, and DNS-over-TLS.',
|
||||
setup: 'Deploy the template → Access at https://dns1.sami → Create your zone → Add A records → Point your router to your DNS server',
|
||||
},
|
||||
{
|
||||
title: 'Pi-hole',
|
||||
icon: '🛡️',
|
||||
desc: 'Network-wide ad blocking DNS sinkhole. All DNS queries on your network pass through Pi-hole — ads and trackers get blocked at the DNS level.',
|
||||
setup: 'Deploy in one click. Point your router or devices to the Pi-hole IP. No configuration needed.',
|
||||
},
|
||||
{
|
||||
title: 'WireGuard VPN',
|
||||
icon: '🔐',
|
||||
desc: 'Fast, modern VPN tunnel. Deploy the server, generate client config files, share with family or teammates. Full VPN access from anywhere.',
|
||||
setup: 'Deploy the template → Download client configs → Share with users → Connect from any device',
|
||||
},
|
||||
{
|
||||
title: 'DashCA (Internal CA)',
|
||||
icon: '🔒',
|
||||
desc: 'Built-in certificate authority. Install the root certificate once, all your internal *.sami domains are trusted on every device on your network.',
|
||||
setup: 'Deploy DashCA → Visit http://ca.sami from any device → Click Install Certificate → Follow your OS instructions',
|
||||
},
|
||||
].map(({ title, icon, desc, setup }) => (
|
||||
<div key={title} className="mb-8 p-6 rounded-lg border border-surface-700/40 bg-surface-800/20">
|
||||
<div className="flex items-center gap-3 mb-3">
|
||||
<span className="text-2xl">{icon}</span>
|
||||
<h3 className="text-xl font-semibold text-surface-50">{title}</h3>
|
||||
</div>
|
||||
<div className="flex items-start gap-4">
|
||||
<div className="text-xl flex-shrink-0">⚙️</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-surface-50 mb-1">Caddy</h3>
|
||||
<p className="text-sm text-surface-400">Version 2.7+ required. <a href="https://caddyserver.com/docs/install" className="text-brand-400 hover:text-brand-300">Install Caddy</a></p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-start gap-4">
|
||||
<div className="text-xl flex-shrink-0">🟢</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-surface-50 mb-1">Node.js</h3>
|
||||
<p className="text-sm text-surface-400">Version 18+ required. <a href="https://nodejs.org/" className="text-brand-400 hover:text-brand-300">Install Node.js</a></p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-start gap-4">
|
||||
<div className="text-xl flex-shrink-0">🔧</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-surface-50 mb-1">Git</h3>
|
||||
<p className="text-sm text-surface-400">For cloning the repository. <a href="https://git-scm.com/" className="text-brand-400 hover:text-brand-300">Install Git</a></p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="border-t border-surface-700/30 pt-4 mt-4">
|
||||
<h3 className="font-semibold text-surface-50 mb-2">Optional</h3>
|
||||
<div className="flex items-start gap-4">
|
||||
<div className="text-xl flex-shrink-0">🌐</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-surface-50 mb-1">Technitium DNS</h3>
|
||||
<p className="text-sm text-surface-400">For automatic DNS management. If not installed, you can still manage DNS manually.</p>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-surface-300 mb-3">{desc}</p>
|
||||
<div className="text-sm">
|
||||
<span className="text-surface-400">Setup: </span>
|
||||
<span className="text-brand-400">{setup}</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Installation Section */}
|
||||
<section id="installation" className="mb-16">
|
||||
<h2 className="text-3xl font-bold text-surface-50 mb-6 flex items-center gap-3">
|
||||
<span className="text-brand-400">📦</span> Installation
|
||||
</h2>
|
||||
<p className="text-surface-300 mb-8 leading-relaxed">
|
||||
Follow these steps to install DashCaddy on your server:
|
||||
</p>
|
||||
|
||||
{/* Step 1 */}
|
||||
<div className="mb-10">
|
||||
<h3 className="text-xl font-semibold text-surface-50 mb-4">Step 1: Clone the Repository</h3>
|
||||
<div className="rounded-lg border border-surface-700/50 bg-surface-900/50 p-4">
|
||||
<code className="text-sm text-green-400 font-mono block">
|
||||
git clone https://github.com/dashcaddy/dashcaddy.git
|
||||
<br />
|
||||
cd dashcaddy
|
||||
</code>
|
||||
{/* Troubleshooting */}
|
||||
<section className="py-12 sm:py-16 bg-surface-900/30">
|
||||
<div className="mx-auto max-w-4xl px-4 sm:px-6 lg:px-8">
|
||||
<h2 className="text-3xl font-bold text-surface-50 mb-8">Troubleshooting</h2>
|
||||
<div className="space-y-4">
|
||||
{[
|
||||
{
|
||||
q: 'App shows "Configuring" after deployment',
|
||||
a: 'Check the app\'s logs in Dozzle or Portainer. Verify the port isn\'t already in use. Make sure volume mounts have correct permissions.',
|
||||
},
|
||||
{
|
||||
q: 'SSL certificate not issued',
|
||||
a: 'Verify your DNS is pointed to your server\'s IP. Check that ports 80 and 443 are open. Give Caddy 1-2 minutes after first deploy.',
|
||||
},
|
||||
{
|
||||
q: "Can't access app after deployment",
|
||||
a: 'Try the subdomain directly (DNS may need to propagate). Check Caddy routing rules in the dashboard. Verify the container is running in Portainer.',
|
||||
},
|
||||
{
|
||||
q: 'License won\'t activate',
|
||||
a: 'Make sure the machine is connected to the internet. Check the machine\'s clock is set correctly. Try deactivating the old machine first if moving to a new server.',
|
||||
},
|
||||
{
|
||||
q: 'Subscriptions not activating after payment',
|
||||
a: 'The Stripe webhook can take a few minutes to arrive. If it doesn\'t arrive within 10 minutes, contact support with your Stripe payment reference.',
|
||||
},
|
||||
].map(({ q, a }) => (
|
||||
<div key={q} className="p-5 rounded-lg border border-surface-700/40 bg-surface-800/20">
|
||||
<div className="font-semibold text-surface-50 mb-2">{q}</div>
|
||||
<div className="text-surface-300 text-sm">{a}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Step 2 */}
|
||||
<div className="mb-10">
|
||||
<h3 className="text-xl font-semibold text-surface-50 mb-4">Step 2: Install Dependencies</h3>
|
||||
<p className="text-surface-300 mb-4">Install Node.js dependencies:</p>
|
||||
<div className="rounded-lg border border-surface-700/50 bg-surface-900/50 p-4">
|
||||
<code className="text-sm text-green-400 font-mono block">
|
||||
npm install
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Step 3 */}
|
||||
<div className="mb-10">
|
||||
<h3 className="text-xl font-semibold text-surface-50 mb-4">Step 3: Configure Environment Variables</h3>
|
||||
<p className="text-surface-300 mb-4">Copy the example environment file and customize it:</p>
|
||||
<div className="rounded-lg border border-surface-700/50 bg-surface-900/50 p-4 mb-4">
|
||||
<code className="text-sm text-green-400 font-mono block">
|
||||
cp .env.example .env
|
||||
</code>
|
||||
</div>
|
||||
<p className="text-surface-300 mb-4">Then edit <code className="bg-surface-800 px-2 py-1 rounded text-brand-400">.env</code> with your configuration:</p>
|
||||
<div className="rounded-lg border border-surface-700/50 bg-surface-900/50 p-4">
|
||||
<code className="text-sm text-surface-300 font-mono whitespace-pre-wrap">
|
||||
{`# Server
|
||||
PORT=3000
|
||||
NODE_ENV=production
|
||||
|
||||
# Database (optional - defaults to SQLite)
|
||||
DATABASE_URL=sqlite:./data/dashcaddy.db
|
||||
|
||||
# Security
|
||||
JWT_SECRET=your-secure-random-secret-here
|
||||
SESSION_SECRET=another-secure-random-secret
|
||||
|
||||
# Caddy
|
||||
CADDY_PORT=80
|
||||
CADDY_HTTPS_PORT=443
|
||||
CADDY_ADMIN_LISTEN=localhost:2019
|
||||
|
||||
# Technitium DNS (optional)
|
||||
TECHNITIUM_API_URL=http://localhost:5380/api
|
||||
TECHNITIUM_API_KEY=your-api-key
|
||||
|
||||
# Email (optional - for notifications)
|
||||
SMTP_HOST=smtp.example.com
|
||||
SMTP_PORT=587
|
||||
SMTP_USER=your-email@example.com
|
||||
SMTP_PASSWORD=your-password`}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Step 4 */}
|
||||
<div className="mb-10">
|
||||
<h3 className="text-xl font-semibold text-surface-50 mb-4">Step 4: Build and Start</h3>
|
||||
<p className="text-surface-300 mb-4">Build the application:</p>
|
||||
<div className="rounded-lg border border-surface-700/50 bg-surface-900/50 p-4 mb-6">
|
||||
<code className="text-sm text-green-400 font-mono block">
|
||||
npm run build
|
||||
</code>
|
||||
</div>
|
||||
<p className="text-surface-300 mb-4">Start DashCaddy:</p>
|
||||
<div className="rounded-lg border border-surface-700/50 bg-surface-900/50 p-4">
|
||||
<code className="text-sm text-green-400 font-mono block">
|
||||
npm start
|
||||
</code>
|
||||
</div>
|
||||
<p className="text-surface-300 mt-4 text-sm">
|
||||
The application will be available at <code className="bg-surface-800 px-2 py-1 rounded text-brand-400">http://localhost:3000</code>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Step 5 */}
|
||||
<div className="mb-10">
|
||||
<h3 className="text-xl font-semibold text-surface-50 mb-4">Step 5: Configure Caddy</h3>
|
||||
<p className="text-surface-300 mb-4">Update your Caddy configuration to proxy requests to DashCaddy:</p>
|
||||
<div className="rounded-lg border border-surface-700/50 bg-surface-900/50 p-4">
|
||||
<code className="text-sm text-surface-300 font-mono whitespace-pre-wrap">
|
||||
{`dashcaddy.local {
|
||||
reverse_proxy localhost:3000
|
||||
|
||||
# Enable automatic HTTPS
|
||||
encode gzip
|
||||
|
||||
# Security headers
|
||||
header Strict-Transport-Security "max-age=31536000"
|
||||
header X-Content-Type-Options "nosniff"
|
||||
header X-Frame-Options "DENY"
|
||||
}`}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Configuration Section */}
|
||||
<section id="configuration" className="mb-16">
|
||||
<h2 className="text-3xl font-bold text-surface-50 mb-6 flex items-center gap-3">
|
||||
<span className="text-brand-400">⚙️</span> Configuration
|
||||
</h2>
|
||||
<p className="text-surface-300 mb-8 leading-relaxed">
|
||||
Key environment variables for DashCaddy configuration:
|
||||
</p>
|
||||
|
||||
<div className="space-y-6">
|
||||
<div className="rounded-lg border border-surface-700/50 bg-surface-900/50 p-6">
|
||||
<h3 className="font-semibold text-brand-400 mb-2 font-mono">PORT</h3>
|
||||
<p className="text-surface-300 text-sm mb-2">The port DashCaddy runs on. Default: <code className="bg-surface-800 px-1 rounded">3000</code></p>
|
||||
</div>
|
||||
|
||||
<div className="rounded-lg border border-surface-700/50 bg-surface-900/50 p-6">
|
||||
<h3 className="font-semibold text-brand-400 mb-2 font-mono">JWT_SECRET</h3>
|
||||
<p className="text-surface-300 text-sm mb-2">Secret key for JWT tokens. Generate a secure random string:</p>
|
||||
<code className="bg-surface-800 px-2 py-1 rounded text-brand-400 text-xs">openssl rand -hex 32</code>
|
||||
</div>
|
||||
|
||||
<div className="rounded-lg border border-surface-700/50 bg-surface-900/50 p-6">
|
||||
<h3 className="font-semibold text-brand-400 mb-2 font-mono">DATABASE_URL</h3>
|
||||
<p className="text-surface-300 text-sm">Connection string for your database. Defaults to SQLite if not provided.</p>
|
||||
</div>
|
||||
|
||||
<div className="rounded-lg border border-surface-700/50 bg-surface-900/50 p-6">
|
||||
<h3 className="font-semibold text-brand-400 mb-2 font-mono">CADDY_ADMIN_LISTEN</h3>
|
||||
<p className="text-surface-300 text-sm mb-2">Caddy admin API endpoint. Default: <code className="bg-surface-800 px-1 rounded">localhost:2019</code></p>
|
||||
</div>
|
||||
|
||||
<div className="rounded-lg border border-surface-700/50 bg-surface-900/50 p-6">
|
||||
<h3 className="font-semibold text-brand-400 mb-2 font-mono">TECHNITIUM_API_URL</h3>
|
||||
<p className="text-surface-300 text-sm">URL to your Technitium DNS API. Optional for DNS management features.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* First Run Section */}
|
||||
<section id="first-run" className="mb-16">
|
||||
<h2 className="text-3xl font-bold text-surface-50 mb-6 flex items-center gap-3">
|
||||
<span className="text-brand-400">🚀</span> First Run
|
||||
</h2>
|
||||
<div className="rounded-lg border border-brand-500/30 bg-brand-950/50 p-8">
|
||||
<ol className="space-y-4 list-decimal list-inside text-surface-300">
|
||||
<li>Access the dashboard at <code className="bg-surface-800 px-2 py-1 rounded text-brand-400">http://dashcaddy.local</code></li>
|
||||
<li>Create your admin account with a strong password</li>
|
||||
<li>Enable TOTP 2FA for enhanced security</li>
|
||||
<li>Configure your Technitium DNS API key (optional)</li>
|
||||
<li>Deploy your first application from the app templates library</li>
|
||||
<li>Monitor your apps in real-time from the dashboard</li>
|
||||
</ol>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Troubleshooting Section */}
|
||||
<section id="troubleshooting" className="mb-16">
|
||||
<h2 className="text-3xl font-bold text-surface-50 mb-6 flex items-center gap-3">
|
||||
<span className="text-brand-400">🔧</span> Troubleshooting
|
||||
</h2>
|
||||
|
||||
<div className="space-y-6">
|
||||
<div className="rounded-lg border border-surface-700/50 bg-surface-900/50 p-6">
|
||||
<h3 className="font-semibold text-surface-50 mb-3 flex items-center gap-2">
|
||||
<span className="text-red-400">❌</span> Docker daemon not running
|
||||
</h3>
|
||||
<p className="text-surface-300 text-sm mb-3">Make sure the Docker daemon is started:</p>
|
||||
<code className="bg-surface-800 px-2 py-1 rounded text-green-400 text-xs block">sudo systemctl start docker</code>
|
||||
</div>
|
||||
|
||||
<div className="rounded-lg border border-surface-700/50 bg-surface-900/50 p-6">
|
||||
<h3 className="font-semibold text-surface-50 mb-3 flex items-center gap-2">
|
||||
<span className="text-red-400">❌</span> Port 3000 already in use
|
||||
</h3>
|
||||
<p className="text-surface-300 text-sm mb-3">Change the PORT in your .env file or stop the process using that port:</p>
|
||||
<code className="bg-surface-800 px-2 py-1 rounded text-green-400 text-xs block">lsof -i :3000</code>
|
||||
</div>
|
||||
|
||||
<div className="rounded-lg border border-surface-700/50 bg-surface-900/50 p-6">
|
||||
<h3 className="font-semibold text-surface-50 mb-3 flex items-center gap-2">
|
||||
<span className="text-red-400">❌</span> Cannot connect to Caddy admin API
|
||||
</h3>
|
||||
<p className="text-surface-300 text-sm mb-3">Verify Caddy is running and the admin API is accessible:</p>
|
||||
<code className="bg-surface-800 px-2 py-1 rounded text-green-400 text-xs block">curl http://localhost:2019/config/</code>
|
||||
</div>
|
||||
|
||||
<div className="rounded-lg border border-surface-700/50 bg-surface-900/50 p-6">
|
||||
<h3 className="font-semibold text-surface-50 mb-3 flex items-center gap-2">
|
||||
<span className="text-red-400">❌</span> Database connection errors
|
||||
</h3>
|
||||
<p className="text-surface-300 text-sm mb-3">Check that your DATABASE_URL is correct and the database is accessible. For SQLite, ensure the data directory exists:</p>
|
||||
<code className="bg-surface-800 px-2 py-1 rounded text-green-400 text-xs block">mkdir -p ./data</code>
|
||||
</div>
|
||||
|
||||
<div className="rounded-lg border border-surface-700/50 bg-surface-900/50 p-6">
|
||||
<h3 className="font-semibold text-surface-50 mb-3 flex items-center gap-2">
|
||||
<span className="text-red-400">❌</span> SSL certificate issues
|
||||
</h3>
|
||||
<p className="text-surface-300 text-sm mb-3">DashCaddy uses Caddy's internal CA for certificate generation. If you have issues, check the Caddy logs:</p>
|
||||
<code className="bg-surface-800 px-2 py-1 rounded text-green-400 text-xs block">journalctl -u caddy -f</code>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Next Steps */}
|
||||
<section className="mb-16">
|
||||
<div className="rounded-lg border border-surface-700/50 bg-surface-800/50 p-8">
|
||||
<h2 className="text-2xl font-bold text-surface-50 mb-6">Next Steps</h2>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<Link
|
||||
href="/features"
|
||||
className="flex items-start gap-4 p-4 rounded-lg border border-brand-500/20 bg-brand-950/30 hover:bg-brand-950/50 transition-colors"
|
||||
>
|
||||
<span className="text-2xl flex-shrink-0">✨</span>
|
||||
<div>
|
||||
<h3 className="font-semibold text-surface-50 mb-1">Explore Features</h3>
|
||||
<p className="text-sm text-surface-400">Learn about all the powerful features DashCaddy offers.</p>
|
||||
</div>
|
||||
</Link>
|
||||
|
||||
<a
|
||||
href="#"
|
||||
className="flex items-start gap-4 p-4 rounded-lg border border-surface-700/50 bg-surface-800/50 hover:bg-surface-800 transition-colors"
|
||||
>
|
||||
<span className="text-2xl flex-shrink-0">📚</span>
|
||||
<div>
|
||||
<h3 className="font-semibold text-surface-50 mb-1">API Reference</h3>
|
||||
<p className="text-sm text-surface-400">Full API documentation for developers.</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<Link
|
||||
href="/pricing"
|
||||
className="flex items-start gap-4 p-4 rounded-lg border border-surface-700/50 bg-surface-800/50 hover:bg-surface-800 transition-colors"
|
||||
>
|
||||
<span className="text-2xl flex-shrink-0">💎</span>
|
||||
<div>
|
||||
<h3 className="font-semibold text-surface-50 mb-1">View Pricing</h3>
|
||||
<p className="text-sm text-surface-400">Check out our free and premium plans.</p>
|
||||
</div>
|
||||
</Link>
|
||||
|
||||
<a
|
||||
href="mailto:support@dashcaddy.net"
|
||||
className="flex items-start gap-4 p-4 rounded-lg border border-surface-700/50 bg-surface-800/50 hover:bg-surface-800 transition-colors"
|
||||
>
|
||||
<span className="text-2xl flex-shrink-0">💬</span>
|
||||
<div>
|
||||
<h3 className="font-semibold text-surface-50 mb-1">Get Support</h3>
|
||||
<p className="text-sm text-surface-400">Contact our support team for help.</p>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user