Replace React/Vite frontend + Fastify API with a single PHP application. - Front controller router in public/index.php (clean URLs via .htaccess) - Session-based auth (no JWT) — register, login, verify email, forgot/reset password, logout - Stripe checkout sessions, billing portal, webhook handler (checkout.session.completed, subscription.updated/deleted) - License IP change via internal licensing server API - PHP classes: DB (PDO), Auth, Mailer (PHPMailer), StripeClient - Views: home, pricing, install, login, register, dashboard, verify-email, forgot-password, reset-password, 404 - Tailwind CSS via CDN — no build step required - Composer dependencies: stripe/stripe-php, phpmailer/phpmailer, vlucas/phpdotenv, ramsey/uuid - CSRF protection on all POST forms - PRG pattern with session flash messages Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
233 lines
12 KiB
PHP
233 lines
12 KiB
PHP
<?php $pageTitle = 'Install NixPanel — Server Installation Guide'; ?>
|
|
|
|
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-16">
|
|
|
|
<div class="mb-12">
|
|
<div class="inline-flex items-center gap-2 bg-brand-900/40 border border-brand-500/30 text-brand-400 text-xs font-medium px-3 py-1.5 rounded-full mb-4">
|
|
Installation Guide
|
|
</div>
|
|
<h1 class="text-4xl font-extrabold text-white mb-4">Install NixPanel</h1>
|
|
<p class="text-gray-400 text-lg max-w-2xl">
|
|
Get your NixServer admin panel and NixClient user panel running on any supported Linux server in under five minutes.
|
|
</p>
|
|
</div>
|
|
|
|
<?php
|
|
$requirements = [
|
|
'Ubuntu 20.04 / 22.04 / 24.04', 'Debian 11 / 12',
|
|
'AlmaLinux 8 / 9', 'Rocky Linux 8 / 9', 'RHEL 8 / 9',
|
|
];
|
|
$minReqs = [
|
|
'Root access (sudo)', 'x86_64 or aarch64 architecture',
|
|
'1 GB RAM (2 GB+ recommended)', '10 GB disk space',
|
|
'Fresh / minimal OS install', 'Internet access from the server',
|
|
];
|
|
?>
|
|
|
|
<!-- Requirements -->
|
|
<div class="mb-12 grid sm:grid-cols-2 gap-6">
|
|
<div class="card">
|
|
<h2 class="text-white font-semibold mb-4">Supported OS</h2>
|
|
<ul class="space-y-2">
|
|
<?php foreach ($requirements as $os): ?>
|
|
<li class="flex items-center gap-2 text-sm text-gray-400">
|
|
<span class="text-emerald-500">✓</span> <?= e($os) ?>
|
|
</li>
|
|
<?php endforeach ?>
|
|
</ul>
|
|
</div>
|
|
<div class="card">
|
|
<h2 class="text-white font-semibold mb-4">Minimum Requirements</h2>
|
|
<ul class="space-y-2">
|
|
<?php foreach ($minReqs as $req): ?>
|
|
<li class="flex items-center gap-2 text-sm text-gray-400">
|
|
<span class="text-emerald-500">✓</span> <?= e($req) ?>
|
|
</li>
|
|
<?php endforeach ?>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Quick install -->
|
|
<div class="mb-14">
|
|
<h2 class="text-2xl font-bold text-white mb-2">Quick Install</h2>
|
|
<p class="text-gray-400 text-sm mb-1">Run this single command as root on a fresh server.</p>
|
|
<?php
|
|
$oneLiner = 'curl -fsSL https://raw.githubusercontent.com/NixReaper/nixpanel-server/main/scripts/install.sh | sudo bash';
|
|
code_block($oneLiner);
|
|
?>
|
|
<div class="mt-4 flex flex-wrap gap-2">
|
|
<?php foreach (['Auto-detects OS', 'Generates random secrets', 'Configures firewall', 'Creates systemd service'] as $b): ?>
|
|
<span class="text-xs font-medium px-2.5 py-1 rounded-full bg-emerald-500/10 text-emerald-400 border border-emerald-500/20"><?= e($b) ?></span>
|
|
<?php endforeach ?>
|
|
</div>
|
|
<p class="mt-4 text-sm text-gray-500">With custom credentials:</p>
|
|
<?php code_block("curl -fsSL https://raw.githubusercontent.com/NixReaper/nixpanel-server/main/scripts/install.sh | sudo bash -s -- \\\n --admin-user admin \\\n --admin-pass \"YourSecurePassword\" \\\n --admin-email \"[email protected]\"") ?>
|
|
</div>
|
|
|
|
<!-- After install -->
|
|
<div class="mb-14 bg-brand-900/20 border border-brand-500/20 rounded-xl p-6">
|
|
<h2 class="text-white font-semibold text-lg mb-3">After Installation</h2>
|
|
<p class="text-gray-400 text-sm mb-4">
|
|
Credentials are printed on screen and saved to
|
|
<code class="text-brand-400 bg-gray-900 px-1.5 py-0.5 rounded text-xs">/root/.nixpanel_credentials</code>.
|
|
</p>
|
|
<div class="grid sm:grid-cols-2 gap-4">
|
|
<div class="bg-gray-900/60 border border-gray-800 rounded-lg p-4">
|
|
<p class="text-xs text-gray-500 mb-1 uppercase tracking-wide font-medium">NixServer — Admin Panel</p>
|
|
<p class="text-white font-mono text-sm">http://<your-ip>:2087</p>
|
|
</div>
|
|
<div class="bg-gray-900/60 border border-gray-800 rounded-lg p-4">
|
|
<p class="text-xs text-gray-500 mb-1 uppercase tracking-wide font-medium">NixClient — User Panel</p>
|
|
<p class="text-white font-mono text-sm">http://<your-ip>:2083</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Manual install -->
|
|
<div class="mb-14">
|
|
<h2 class="text-2xl font-bold text-white mb-1">Manual Installation</h2>
|
|
<p class="text-gray-400 text-sm mb-8">Prefer full control? Install system dependencies first (Node.js 22, MariaDB, Nginx, etc.), then follow these steps.</p>
|
|
|
|
<?php
|
|
$steps = [
|
|
['Clone the repository', "git clone https://github.com/NixReaper/nixpanel-server.git /opt/nixpanel\ncd /opt/nixpanel"],
|
|
['Configure environment variables', "cp .env.example .env\nnano .env # set your passwords and secrets"],
|
|
['Install, migrate, and build', "npm install --workspaces --include-workspace-root\ncd server && npx prisma generate && npx prisma migrate deploy\nADMIN_USERNAME=admin ADMIN_PASSWORD=yourpass npx tsx src/db/seed.ts\ncd ..\nnpm run build --workspace=nixserver\nnpm run build --workspace=nixclient"],
|
|
['Create the systemd service', "cp scripts/nixpanel.service /etc/systemd/system/nixpanel.service\nsystemctl daemon-reload\nsystemctl enable --now nixpanel"],
|
|
];
|
|
foreach ($steps as $i => [$title, $cmd]):
|
|
?>
|
|
<div class="flex gap-5 mb-8">
|
|
<div class="flex-shrink-0 w-8 h-8 rounded-full bg-brand-600 flex items-center justify-center text-white text-sm font-bold"><?= $i + 1 ?></div>
|
|
<div class="flex-1">
|
|
<h3 class="text-white font-semibold text-lg mb-2"><?= e($title) ?></h3>
|
|
<?php code_block($cmd) ?>
|
|
</div>
|
|
</div>
|
|
<?php endforeach ?>
|
|
</div>
|
|
|
|
<!-- What gets installed -->
|
|
<?php
|
|
$software = [
|
|
['Node.js 22 LTS', 'Application runtime'],
|
|
['MariaDB', 'Panel database'],
|
|
['Nginx', 'Web server & reverse proxy'],
|
|
['PHP 8.3 + FPM', 'PHP runtime with common extensions'],
|
|
['Postfix + Dovecot', 'SMTP & IMAP mail server'],
|
|
['vsftpd', 'FTP server'],
|
|
['BIND9', 'DNS server'],
|
|
['Certbot', "Let's Encrypt SSL automation"],
|
|
['Fail2ban', 'Brute-force protection'],
|
|
['UFW / firewalld', 'Firewall (auto-configured)'],
|
|
];
|
|
?>
|
|
<div class="mb-14">
|
|
<h2 class="text-2xl font-bold text-white mb-4">What Gets Installed</h2>
|
|
<div class="card overflow-hidden p-0">
|
|
<table class="w-full text-sm">
|
|
<thead><tr class="border-b border-gray-800">
|
|
<th class="text-left text-gray-500 font-medium px-5 py-3">Package</th>
|
|
<th class="text-left text-gray-500 font-medium px-5 py-3">Purpose</th>
|
|
</tr></thead>
|
|
<tbody>
|
|
<?php foreach ($software as $i => [$pkg, $desc]): ?>
|
|
<tr class="border-b border-gray-800 last:border-0 <?= $i % 2 !== 0 ? 'bg-gray-900/30' : '' ?>">
|
|
<td class="px-5 py-3 text-white font-mono text-xs"><?= e($pkg) ?></td>
|
|
<td class="px-5 py-3 text-gray-400"><?= e($desc) ?></td>
|
|
</tr>
|
|
<?php endforeach ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Ports -->
|
|
<?php
|
|
$ports = [
|
|
['2087', 'NixServer', 'Admin panel (NixServer)'],
|
|
['2083', 'NixClient', 'User panel (NixClient)'],
|
|
['80', 'HTTP', 'Web traffic + ACME challenges'],
|
|
['443', 'HTTPS', 'SSL web traffic'],
|
|
['21', 'FTP', 'FTP control'],
|
|
['25', 'SMTP', 'Inbound mail'],
|
|
['587', 'Submission', 'Outbound mail (authenticated)'],
|
|
['993', 'IMAPS', 'Secure IMAP'],
|
|
['53', 'DNS', 'DNS resolution (TCP + UDP)'],
|
|
];
|
|
?>
|
|
<div class="mb-14">
|
|
<h2 class="text-2xl font-bold text-white mb-2">Firewall Ports</h2>
|
|
<p class="text-gray-400 text-sm mb-4">Auto-configured via UFW (Debian/Ubuntu) or firewalld (RHEL/AlmaLinux/Rocky).</p>
|
|
<div class="card overflow-hidden p-0">
|
|
<table class="w-full text-sm">
|
|
<thead><tr class="border-b border-gray-800">
|
|
<th class="text-left text-gray-500 font-medium px-5 py-3">Port</th>
|
|
<th class="text-left text-gray-500 font-medium px-5 py-3">Name</th>
|
|
<th class="text-left text-gray-500 font-medium px-5 py-3">Description</th>
|
|
</tr></thead>
|
|
<tbody>
|
|
<?php foreach ($ports as $i => [$port, $name, $desc]): ?>
|
|
<tr class="border-b border-gray-800 last:border-0 <?= $i % 2 !== 0 ? 'bg-gray-900/30' : '' ?>">
|
|
<td class="px-5 py-3 font-mono text-brand-400 text-xs"><?= e($port) ?></td>
|
|
<td class="px-5 py-3 text-white"><?= e($name) ?></td>
|
|
<td class="px-5 py-3 text-gray-400"><?= e($desc) ?></td>
|
|
</tr>
|
|
<?php endforeach ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Updating -->
|
|
<div class="mb-14">
|
|
<h2 class="text-2xl font-bold text-white mb-2">Updating NixPanel</h2>
|
|
<?php code_block('sudo bash /opt/nixpanel/scripts/update.sh') ?>
|
|
</div>
|
|
|
|
<!-- Service management -->
|
|
<div class="mb-14">
|
|
<h2 class="text-2xl font-bold text-white mb-4">Managing the Service</h2>
|
|
<div class="grid sm:grid-cols-2 gap-3">
|
|
<?php
|
|
$cmds = [
|
|
'Check status' => 'systemctl status nixpanel',
|
|
'View live logs'=> 'journalctl -u nixpanel -f',
|
|
'Restart' => 'systemctl restart nixpanel',
|
|
'Stop' => 'systemctl stop nixpanel',
|
|
];
|
|
foreach ($cmds as $label => $cmd):
|
|
?>
|
|
<div class="card py-3">
|
|
<p class="text-xs text-gray-500 mb-1"><?= e($label) ?></p>
|
|
<div class="flex items-center justify-between gap-3">
|
|
<code class="text-sm text-gray-300 font-mono"><?= e($cmd) ?></code>
|
|
<button onclick="navigator.clipboard.writeText('<?= e($cmd) ?>')" class="text-xs px-2.5 py-1 rounded bg-gray-700 hover:bg-gray-600 text-gray-300 flex-shrink-0 transition-colors">Copy</button>
|
|
</div>
|
|
</div>
|
|
<?php endforeach ?>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Uninstall -->
|
|
<div>
|
|
<h2 class="text-2xl font-bold text-white mb-2">Uninstalling</h2>
|
|
<p class="text-gray-400 text-sm mb-1">Removes the service, nginx config, install directory, and database. Does not remove Nginx, PHP, or other system packages.</p>
|
|
<?php code_block('sudo bash /opt/nixpanel/scripts/uninstall.sh') ?>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<?php
|
|
function code_block(string $code): void {
|
|
echo '<div class="relative mt-3 rounded-lg bg-gray-950 border border-gray-800 overflow-hidden">';
|
|
echo '<div class="flex items-center justify-between px-4 py-2 border-b border-gray-800 bg-gray-900/60">';
|
|
echo '<span class="text-xs text-gray-500 font-mono">bash</span>';
|
|
echo '<button onclick="navigator.clipboard.writeText(this.dataset.code)" data-code="' . htmlspecialchars($code, ENT_QUOTES) . '" class="text-xs px-2.5 py-1 rounded bg-gray-700 hover:bg-gray-600 text-gray-300 transition-colors">Copy</button>';
|
|
echo '</div>';
|
|
echo '<pre class="px-4 py-4 text-sm text-gray-300 font-mono overflow-x-auto whitespace-pre leading-relaxed">' . htmlspecialchars($code, ENT_QUOTES) . '</pre>';
|
|
echo '</div>';
|
|
}
|
|
?>
|