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:
Krystie
2026-04-18 03:57:53 -07:00
parent aedaf4b4b5
commit bb69b96816

View File

@@ -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">
<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>
{/* 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>
<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>
</div>
</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>
</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">
<section className="py-8">
<div className="mx-auto max-w-4xl px-4 sm:px-6 lg:px-8">
<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>
<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>
<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 className="font-semibold text-surface-50">{title}</div>
<div className="text-sm text-surface-400">{desc}</div>
</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>
{/* 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>
<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>
<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>
))}
</div>
</section>
{/* 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>
</div>
</section>