diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..26627e7 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,24 @@ +# NovaCPX Documentation + +NovaCPX is an open-source Linux web hosting control panel with three-tier management (Admin → Reseller → User). + +## Documents + +| Guide | Audience | Description | +|-------|----------|-------------| +| [Installation Guide](install.md) | Server admins | Requirements, installer usage, file layout, auto-deploy setup | +| [Admin Guide](admin-guide.md) | Server admins | All admin panel features: accounts, DNS, mail, security, Docker, notifications | +| [Reseller Guide](reseller-guide.md) | Resellers | Creating and managing customer accounts, white-label branding | +| [User Guide](user-guide.md) | End users | Files, email, databases, FTP, DNS, SSL, cron, Docker | +| [API Reference](api-reference.md) | Developers | Full REST API documentation for all endpoints | + +## Quick links + +- Admin panel: `https://:8882` +- Reseller panel: `https://:8881` +- User panel: `https://:8880` +- Webmail: `https://:8883` + +## Source + +GitHub: [myronblair/novacpx](https://github.com/myronblair/novacpx) diff --git a/docs/admin-guide.md b/docs/admin-guide.md new file mode 100644 index 0000000..7facfef --- /dev/null +++ b/docs/admin-guide.md @@ -0,0 +1,210 @@ +# NovaCPX — Administrator Guide + +## Accessing the Admin Panel + +The admin panel runs on port **8882**. Navigate to `https://:8882` and log in with your admin credentials. + +The browser will show a self-signed certificate warning on a fresh install. Accept it, or replace the certificate at `/etc/novacpx/ssl/` with a trusted cert and restart Apache. + +## Dashboard + +The dashboard shows real-time server stats (CPU, RAM, disk, uptime), running services with restart/stop controls, and NovaCPX version information. + +Click **Check for Updates** to see if a newer version is available. + +## Accounts + +**Accounts → All Accounts** lists every hosting account on the server. From this page you can: + +- **Search** by domain or username +- **Suspend / Unsuspend** an account (suspending disables the web vhost and sends an email notification to the account holder) +- **Change Password** for any account +- **Terminate** an account permanently (deletes files, databases, DNS zone, email accounts — irreversible) + +### Creating an account + +**Accounts → Create Account** + +| Field | Notes | +|-------|-------| +| Username | Lowercase, alphanumeric. Creates a Linux system user. | +| Domain | Primary domain for the account. A DNS zone and vhost are created automatically. | +| Email | Account holder's email. Receives the welcome notification. | +| Password | Min 8 characters. Also set as the Linux system password. | +| Package | Disk/resource limits applied to the account. | +| PHP version | Per-account PHP-FPM pool version. | +| Reseller | (Optional) Assign account to a reseller. | + +After creation, the welcome email (if notifications are enabled) is sent to the account holder with login credentials. + +## Resellers + +**Accounts → Resellers** manages reseller sub-admin accounts. Resellers can create and manage their own customer accounts, set per-customer Docker quotas, and apply white-label branding. + +To create a reseller, go to **Accounts → Create Account** and select the **Reseller** role. + +## Packages + +Define hosting plans. Each package sets limits on: + +- Disk (MB) +- Email accounts +- MySQL databases +- FTP accounts +- Domains +- Subdomains + +Accounts without a package have no enforced limits. + +## DNS + +### DNS Zones + +Lists all DNS zones on the server. You can add, edit, and delete DNS records directly. Zones are managed by BIND9 and reloaded via `rndc`. + +Supported record types: A, AAAA, CNAME, MX, TXT, NS, SRV, CAA. + +### Nameservers + +Set the global NS1/NS2 hostnames used when creating new zones. After saving, click **Check All** to verify the nameservers are resolving correctly. + +## Services + +### Web Server + +Shows Apache or Nginx configuration. Switch between web servers. The switch script runs in the background — check the page again after ~30 seconds to confirm. + +### PHP Manager + +Install or remove PHP versions (7.4, 8.1, 8.2, 8.3). Each version gets its own PHP-FPM pool. Accounts can be assigned any installed version. + +### MySQL Manager + +Shows MySQL status and running databases. Provides a link to phpMyAdmin if installed. + +### Mail Server + +Shows Postfix/Dovecot status. Switch mail server stack (postfix-dovecot or postfix-dovecot-rspamd). + +### FTP Server + +Shows FTP daemon status. Switch between ProFTPD, vsftpd, and PureFTPD. + +### Nginx Proxy Manager + +Reverse proxy management for additional services. The Nginx Proxy Manager runs as a Docker container. Use **Setup** to configure it. + +### WordPress Manager + +One-click WordPress installs via WP-CLI. Actions: install, update, toggle maintenance mode, clone to staging. + +### Docker + +Full Docker Engine management: + +- **Containers** — run, stop, start, restart, remove, view logs +- **Images** — pull, list, remove +- **Volumes** and **Networks** — list, remove +- **Compose Stacks** — create from YAML, bring up/down, view logs + +## Security + +### SSL Manager + +View SSL certificates for all accounts. Certificates issued via Certbot (Let's Encrypt). The domain must resolve publicly for issuance to succeed. + +### Firewall / Fail2Ban + +Manage UFW rules (allow/deny by port, protocol, and IP). View and unban Fail2Ban jail entries. NovaCPX jails monitor: + +- SSH brute-force (`sshd`) +- Panel login failures (`novacpx-auth`) +- API abuse (`novacpx-api`) +- PHP error flooding (`novacpx-php`) +- Postfix SMTP auth (`postfix-auth`) + +### Audit Log + +Full log of all admin, reseller, and user actions. Filter by username, action type, and date range. Click any row to expand the raw JSON detail payload. + +### 2FA Manager + +Manage TOTP two-factor authentication. Admins can view which accounts have 2FA enabled and reset (revoke) 2FA for a user if they lose their authenticator. + +### Sessions + +View all active login sessions. Revoke individual sessions or all sessions for a specific user. Useful for forcing a logout after a password reset. + +## System + +### Updates + +Check for newer NovaCPX versions on GitHub. If an update is available, click **Update Now** — this runs `git pull` on the server and triggers a deploy. + +### Backups + +Schedule and manage per-account backups: + +- **Backup now** — immediate backup of files + databases +- **Download** — download a backup archive +- **Restore** — restore files and databases from a backup +- **Schedule** — set automatic backup frequency per account +- Optional rclone/S3 remote destination + +### Cloudflare + +Per-account Cloudflare API key management. Pull/push DNS zone records, toggle the CDN proxy per record. + +### Server Options + +Configure which services NovaCPX manages: + +| Setting | Options | +|---------|---------| +| Web server | apache, nginx, openlitespeed, caddy | +| Mail server | postfix-dovecot, postfix-dovecot-rspamd | +| FTP server | proftpd, vsftpd, pureftpd | +| DNS server | bind9, powerdns, nsd, none | +| WHMCS | Enable and configure the billing bridge API key | + +### Notifications + +Configure email alerts sent via CyberMail: + +| Field | Notes | +|-------|-------| +| CyberMail API Key | From platform.cyberpersons.com | +| From Email | Sender address (must be a verified sender domain) | +| From Name | Display name shown in email clients | +| Admin Alert Email | Receives admin copies of all notifications | +| Notifications | Enable or disable all outbound notifications | + +Click **Send Test Email** to verify the configuration. + +Notification triggers: + +- Account created → welcome email to new user + admin alert +- Account suspended → notification to account holder + admin alert +- Disk quota ≥ 85% → daily warning (cron, 06:00) +- SSL certificate expiring ≤ 14 days → expiry notice (cron, 06:00) + +### Settings + +Panel-wide settings: panel name, default PHP version, nameservers, update channel. + +## WHMCS Billing Bridge + +NovaCPX exposes a WHMCS-compatible server module API at `/api/whmcs/`. Enable it in **Server Options** and set the API key. The WHMCS module calls these endpoints to provision, suspend, and terminate accounts automatically. + +Supported actions: `create`, `suspend`, `unsuspend`, `terminate`, `changepackage`, `info`. + +Authenticate with the `X-WHMCS-Key: ` header. + +## Log files + +| File | Contents | +|------|----------| +| `/var/log/novacpx/deploy.log` | Auto-deploy activity | +| `/var/log/novacpx/stats-collector.log` | Server stats cron output | +| `/var/log/novacpx/notify-checks.log` | Disk/SSL notification cron output | +| `/var/log/novacpx/switch-*.log` | Service switch script output | diff --git a/docs/api-reference.md b/docs/api-reference.md new file mode 100644 index 0000000..dd887b0 --- /dev/null +++ b/docs/api-reference.md @@ -0,0 +1,725 @@ +# NovaCPX — API Reference + +## Overview + +All API endpoints are served under `/api//`. + +**Base URL pattern:** `https://:/api//` + +The same API is available on all three panel ports (8880, 8881, 8882). Which actions succeed depends on the role of the authenticated session. + +### Authentication + +All endpoints (except `auth/login`) require an active session cookie `ncpx_session`. Obtain it by calling `auth/login`. + +```http +POST /api/auth/login +Content-Type: application/json + +{"username": "admin", "password": "Nova2026!!"} +``` + +The response sets the `ncpx_session` cookie. Include it in all subsequent requests (`credentials: 'include'` in fetch, or `-b cookies.txt` in curl). + +### Response format + +Every response is JSON: + +```json +{ + "success": true, + "message": "OK", + "data": { ... } +} +``` + +On error: + +```json +{ + "success": false, + "message": "Reason", + "errors": [] +} +``` + +Paginated responses include a `meta` block: + +```json +{ + "success": true, + "data": { "items": [...], "meta": { "total": 100, "page": 1, "per_page": 25, "pages": 4 } } +} +``` + +### Role access + +| Role | Panels | Access | +|------|--------|--------| +| `admin` | 8882 | Everything | +| `reseller` | 8881 | Own accounts + reseller features | +| `user` | 8880 | Own account only | + +### Rate limiting + +| Scope | Limit | +|-------|-------| +| Login (`auth/login`) | 10 requests / minute | +| All other endpoints | 120 requests / minute | + +Exceeded limits return HTTP 429 with `Retry-After` and `X-RateLimit-*` headers. + +--- + +## auth + +### `POST /api/auth/login` + +Authenticate and create a session. + +**Body:** `{username, password}` +**Returns:** `{user: {id, username, role}, portal_url}` +**Access:** Public + +### `GET /api/auth/me` + +Return the current session's user object. + +**Returns:** `{id, username, email, role}` +**Access:** Any authenticated user + +### `POST /api/auth/logout` + +Destroy the current session. + +**Access:** Any authenticated user + +### `POST /api/auth/change-password` + +Change the current user's own password. + +**Body:** `{current_password, new_password, confirm_password}` +**Access:** Any authenticated user + +--- + +## accounts + +### `GET /api/accounts/list` + +List hosting accounts. + +**Query params:** `page`, `per_page`, `search`, `status` +**Returns:** Paginated list with domain_count, email_count, db_count per account +**Access:** Admin (all accounts), Reseller (own accounts) + +### `GET /api/accounts/get?id=` + +Get a single account with its domains and disk usage. + +**Access:** Admin, Reseller (own accounts) + +### `POST /api/accounts/create` + +Create a hosting account. Creates Linux user, home directory, vhost, DNS zone, and optionally sends a welcome email. + +**Body:** + +```json +{ + "username": "john", + "domain": "example.com", + "email": "john@example.com", + "password": "secret", + "package_id": 1, + "php_version": "8.3" +} +``` + +**Access:** Admin, Reseller + +### `POST /api/accounts/suspend` + +Suspend an account (disables vhost, notifies user). + +**Body:** `{id, reason?}` +**Access:** Admin, Reseller (own accounts) + +### `POST /api/accounts/unsuspend` + +Re-enable a suspended account. + +**Body:** `{id}` +**Access:** Admin, Reseller (own accounts) + +### `POST /api/accounts/terminate` + +Permanently delete an account and all its data. + +**Body:** `{id}` +**Access:** Admin only + +### `POST /api/accounts/change-password` + +Reset an account's panel and system password. + +**Body:** `{account_id, password}` +**Access:** Admin only + +### `GET /api/accounts/usage?id=` + +Return disk, email, database, domain, and FTP usage vs. package limits. + +**Access:** Admin, Reseller (own accounts) + +--- + +## domains + +### `GET /api/domains/list?account_id=` + +List domains for an account. + +**Access:** Admin, Reseller (own accounts), User (own account) + +### `POST /api/domains/add` + +Add a domain, subdomain, or redirect to an account. + +**Body:** + +```json +{ + "account_id": 1, + "domain": "example.com", + "type": "addon", + "document_root": "/home/user/public_html/example", + "php_version": "8.3" +} +``` + +`type` values: `addon`, `subdomain`, `redirect` + +For redirects, include `redirect_to` (URL) and `redirect_code` (301 or 302). + +**Access:** Admin, Reseller, User + +### `POST /api/domains/remove` + +Remove a domain (cannot remove the primary domain). + +**Body:** `{account_id, domain_id}` +**Access:** Admin, Reseller, User + +--- + +## email + +### `GET /api/email/list?account_id=` + +List email accounts for an account. + +**Access:** Admin, Reseller, User + +### `POST /api/email/create` + +Create a mailbox. + +**Body:** `{account_id, email, password, quota_mb?}` +**Access:** Admin, Reseller, User (subject to `max_email` package limit) + +### `DELETE /api/email/delete` + +Delete a mailbox. + +**Body:** `{id}` +**Access:** Admin, Reseller, User + +### `POST /api/email/suspend` + +Suspend a mailbox. + +**Body:** `{id}` +**Access:** Admin, Reseller, User + +### `GET /api/webmail/login-url?account_id=&email=` + +Generate a single-sign-on webmail URL (valid 5 minutes). + +**Access:** Admin, Reseller, User + +--- + +## dns + +### `GET /api/dns/list?account_id=` + +List DNS zones for an account. + +**Access:** Admin, Reseller, User + +### `GET /api/dns/records?zone_id=` + +List records in a zone. + +### `POST /api/dns/add-record` + +Add a DNS record. + +**Body:** + +```json +{ + "zone_id": 1, + "type": "A", + "name": "www", + "value": "1.2.3.4", + "ttl": 3600 +} +``` + +**Access:** Admin, Reseller, User + +### `POST /api/dns/update-record` + +Update an existing record. + +**Body:** `{record_id, name, value, ttl}` + +### `POST /api/dns/delete-record` + +Delete a record. + +**Body:** `{record_id}` + +### `POST /api/dkim/generate` + +Generate DKIM key pair for a domain. + +**Body:** `{account_id, domain}` + +--- + +## databases + +### `GET /api/databases/list?account_id=` + +List MySQL databases for an account. + +**Access:** Admin, Reseller, User + +### `POST /api/databases/create` + +Create a database and MySQL user. + +**Body:** `{account_id, db_name, db_user, db_pass}` +**Subject to `max_databases` package limit.** + +### `DELETE /api/databases/delete` + +Drop a database. + +**Body:** `{id}` + +--- + +## ftp + +### `GET /api/ftp/list?account_id=` + +List FTP accounts. + +### `POST /api/ftp/create` + +Create an FTP account. + +**Body:** `{account_id, username, password, home_dir}` +**Subject to `max_ftp` package limit.** + +### `DELETE /api/ftp/delete` + +Delete an FTP account. + +**Body:** `{id}` + +--- + +## ssl + +### `GET /api/ssl/list?account_id=` + +List SSL certificates for an account. + +### `POST /api/ssl/issue` + +Issue a Let's Encrypt certificate. The domain must resolve publicly. + +**Body:** `{account_id, domain}` + +### `POST /api/ssl/delete` + +Remove an SSL certificate record. + +**Body:** `{id}` + +--- + +## files + +The file manager API mirrors the user-facing file manager. All paths are validated against the account's home directory; paths outside it are rejected. + +### `GET /api/files/list?account_id=&path=` + +List directory contents. + +### `GET /api/files/read?account_id=&path=` + +Read a text file (max 1 MB). + +### `POST /api/files/write` + +Write/create a file. + +**Body:** `{account_id, path, content}` + +### `POST /api/files/mkdir` + +Create a directory. + +**Body:** `{account_id, path}` + +### `DELETE /api/files/delete` + +Delete a file or directory. + +**Body:** `{account_id, path}` + +### `POST /api/files/rename` + +Rename or move a file. + +**Body:** `{account_id, from, to}` + +### `POST /api/files/chmod` + +Change file permissions (clamped to 0777 max). + +**Body:** `{account_id, path, mode}` (e.g. `"mode": "0755"`) + +### `POST /api/files/upload` + +Upload a file. Multipart form data: `account_id`, `path`, `file`. + +--- + +## cron + +### `GET /api/cron/list?account_id=` + +List cron jobs for an account. + +### `POST /api/cron/save` + +Create or update a cron job. + +**Body:** `{account_id, id?, schedule, command, enabled}` + +### `DELETE /api/cron/delete` + +Delete a cron job. + +**Body:** `{id}` + +--- + +## packages + +### `GET /api/packages/list` + +List all hosting packages. + +**Access:** Admin, Reseller + +### `POST /api/packages/create` + +Create a package. + +**Body:** + +```json +{ + "name": "Starter", + "disk_mb": 5120, + "max_email": 10, + "max_databases": 5, + "max_ftp": 5, + "max_domains": 10, + "max_subdomains": 20 +} +``` + +### `POST /api/packages/update` + +Update a package. + +**Body:** `{id, ...same fields as create}` + +### `DELETE /api/packages/delete` + +Delete a package (accounts using it are unaffected). + +**Body:** `{id}` + +--- + +## stats + +### `GET /api/stats/account?account_id=` + +Return usage stats for an account. For user role, `account_id` is inferred automatically. + +### `GET /api/stats/server` + +Return historical server stats (CPU, RAM, disk) from the last 24 hours. Populated by the `collect-stats.php` cron every 5 minutes. + +**Access:** Admin only + +--- + +## sessions + +### `GET /api/sessions/list` + +List all active sessions (admin sees all, users see their own). + +### `DELETE /api/sessions/revoke` + +Revoke a specific session. + +**Body:** `{session_id}` +**Access:** Admin + +### `DELETE /api/sessions/revoke-user` + +Revoke all sessions for a specific user. + +**Body:** `{user_id}` +**Access:** Admin + +### `DELETE /api/sessions/revoke-all` + +Revoke all active sessions on the panel. + +**Access:** Admin + +--- + +## system + +All system actions require Admin unless noted. + +### `GET /api/system/version` + +Return panel version, git commit, PHP version, OS. No auth required. + +### `GET /api/system/stats` + +Return live CPU, RAM, disk, uptime, and service status. + +### `GET /api/system/check-update` + +Check GitHub for newer NovaCPX commits. + +### `POST /api/system/apply-update` + +Pull the latest code and trigger a deploy. + +### `GET /api/system/check-os-update` + +List available apt package upgrades. + +### `POST /api/system/apply-os-update` + +Run `apt-get upgrade` and restart any services that went down. + +### `GET /api/system/audit-log` + +Query the audit log. + +**Query params:** `page`, `per_page`, `user`, `action`, `date_from`, `date_to` + +### `GET /api/system/server-options` + +Return current web/mail/FTP/DNS server selections and detection state. + +### `POST /api/system/save-option` + +Save a server option. + +**Body:** `{key, value}` — allowed keys: `web_server`, `mail_server`, `ftp_server`, `dns_server`, `whmcs_api_key`, `whmcs_enabled`, `ns1_hostname`, `ns2_hostname` + +### `GET /api/system/notify-settings` + +Return notification settings (API key masked). + +### `POST /api/system/save-notify-settings` + +Save notification settings. + +**Body:** `{cybermail_api_key?, notify_from_email?, notify_from_name?, notify_admin_email?, notifications_enabled?}` + +### `POST /api/system/test-notify` + +Send a test email. + +**Body:** `{to}` + +### `POST /api/system/service-action` + +Start, stop, or restart a system service. + +**Body:** `{service, action}` — action: `start`, `stop`, `restart` + +--- + +## branding + +### `GET /api/branding/get` + +Return the branding settings for the current reseller. + +**Access:** Reseller (own branding), Admin (pass `reseller_id` param) + +### `POST /api/branding/save` + +Save branding settings. + +**Body:** `{panel_name?, primary_color?, accent_color?, support_email?, support_url?, hide_powered_by?, custom_css?}` + +### `POST /api/branding/upload-logo` + +Upload a logo image. Multipart: `logo` file field. +Accepts PNG, JPG, SVG, WEBP (max 512 KB). + +### `POST /api/branding/delete-logo` + +Remove the current logo and revert to the default SVG. + +--- + +## whmcs + +WHMCS billing bridge. Authenticate with `X-WHMCS-Key: ` header (configured in Server Options). + +### `POST /api/whmcs/create` + +Provision a new hosting account. + +**Body:** `{domain, username, password, email, package_id?}` + +### `POST /api/whmcs/suspend` + +Suspend an account by domain. + +**Body:** `{domain, reason?}` + +### `POST /api/whmcs/unsuspend` + +Unsuspend an account by domain. + +**Body:** `{domain}` + +### `POST /api/whmcs/terminate` + +Terminate an account by domain. + +**Body:** `{domain}` + +### `POST /api/whmcs/changepackage` + +Switch an account to a different package. + +**Body:** `{domain, package_id}` + +### `GET /api/whmcs/info?domain=` + +Return account details for a domain. + +--- + +## docker + +### `GET /api/docker/status` + +Engine status and container/image counts. + +### `GET /api/docker/containers?account_id=` + +List containers for an account (or all containers for admin with no account_id). + +### `POST /api/docker/container-action` + +**Body:** `{container_id, action}` — action: `start`, `stop`, `restart`, `remove` + +### `GET /api/docker/logs?container_id=` + +Return the last 100 log lines from a container. + +### `GET /api/docker/images` + +List pulled images. + +### `POST /api/docker/pull` + +Pull an image. + +**Body:** `{image}` e.g. `"image": "nginx:latest"` + +### `POST /api/docker/run` + +Run a new container. + +**Body:** `{account_id, name, image, ports?, env?, volumes?}` +Container names are namespaced as `novacpx--`. + +### `GET /api/docker/catalog` + +Return the one-click app catalog (9 apps: WordPress, Ghost, Nextcloud, Gitea, Matomo, Vaultwarden, Node.js, Flask, static). + +### `POST /api/docker/launch-app` + +Deploy an app from the catalog. + +**Body:** `{account_id, app_id, ...app-specific config}` + +--- + +## firewall + +### `GET /api/firewall/rules` + +List UFW rules. + +**Access:** Admin + +### `POST /api/firewall/add-rule` + +Add a UFW rule. + +**Body:** `{port, protocol, action, from_ip?}` + +### `POST /api/firewall/delete-rule` + +Remove a rule by number. + +**Body:** `{rule_number}` + +### `GET /api/firewall/fail2ban` + +Return Fail2Ban jail status and banned IPs. + +### `POST /api/firewall/unban` + +Unban an IP from a jail. + +**Body:** `{jail, ip}` diff --git a/docs/install.md b/docs/install.md new file mode 100644 index 0000000..7a02b89 --- /dev/null +++ b/docs/install.md @@ -0,0 +1,169 @@ +# NovaCPX — Installation Guide + +## Requirements + +| Item | Minimum | +|------|---------| +| OS | Ubuntu 20.04 / 22.04 / 24.04, Debian 11 / 12 | +| RAM | 1 GB (2 GB recommended) | +| Disk | 10 GB free | +| CPU | 1 vCPU | +| Access | Root or sudo | +| Ports | 80, 443, 8880, 8881, 8882, 8883, 21, 22, 25, 143, 993, 53 | + +## Quick Install + +```bash +curl -fsSL https://raw.githubusercontent.com/myronblair/novacpx/main/install.sh | bash +``` + +Or download and run manually: + +```bash +wget https://raw.githubusercontent.com/myronblair/novacpx/main/install.sh +bash install.sh +``` + +### Installer flags + +| Flag | Effect | +|------|--------| +| `--nginx` | Use Nginx instead of Apache (default: Apache) | +| `--apache` | Force Apache (default) | +| `--no-mysql` | Skip MySQL installation | +| `--no-postgres` | Skip PostgreSQL installation | + +The installer is **idempotent** — safe to re-run on an existing install. Completed steps are skipped automatically. + +## What the installer does + +1. Detects OS and verifies minimum requirements +2. Installs PHP 7.4, 8.1, 8.2, and 8.3 (ondrej/php PPA on Ubuntu; sury on Debian) +3. Installs and configures the web server (Apache or Nginx) on ports 8880/8881/8882 +4. Installs MySQL and creates the `novacpx` database and `novacpx_user` account +5. Installs PostgreSQL (optional, for customer databases) +6. Installs and configures BIND9 for DNS zone management +7. Installs Postfix + Dovecot for virtual mail hosting +8. Installs ProFTPD for FTP account management +9. Installs OpenDKIM and wires it into Postfix +10. Installs Roundcube webmail on port 8883 +11. Installs Certbot for Let's Encrypt SSL +12. Installs Fail2Ban with 5 jails (sshd + 4 NovaCPX-specific jails) +13. Configures UFW firewall rules +14. Copies panel files to `/srv/novacpx/public/` +15. Sets up systemd services and cron jobs +16. Generates a self-signed SSL certificate for the panel ports +17. Creates the admin user and prints credentials + +## Post-install + +After the installer completes it prints: + +``` +NovaCPX installed successfully! + +Admin panel: https://:8882 +Username: admin +Password: + +User panel: https://:8880 +Reseller panel: https://:8881 +Webmail: https://:8883 +``` + +Log in to the admin panel and: + +1. Set your nameservers under **DNS → Nameservers** +2. Configure your server IP in **Settings** +3. Create your first hosting package under **Packages** +4. Create your first hosting account under **Accounts → Create** + +## File layout + +``` +/srv/novacpx/public/ Web root (all panel files) + admin/ Admin panel frontend + reseller/ Reseller panel frontend + user/ User panel frontend + api/ API backend (PHP) + endpoints/ One file per resource + lib/ Shared PHP classes + assets/ CSS, JS, images + errors/ Custom error pages + +/opt/novacpx/ Binaries and runtime libs + bin/ Cron scripts + lib/ Symlink to /srv/novacpx/public/lib + +/opt/novacpx-src/ Git repository clone +/etc/novacpx/ Config files + config.ini Main config (DB creds, panel secret, ports) + ssl/ Panel TLS certificate +/var/log/novacpx/ Log files +``` + +## Configuration file + +`/etc/novacpx/config.ini`: + +```ini +[database] +host = localhost +name = novacpx +user = novacpx_user +pass = + +[panel] +secret = ; HMAC key for session tokens +port_user = 8880 +port_reseller = 8881 +port_admin = 8882 +port_webmail = 8883 +webroot = /srv/novacpx/public +version = 1.0.0 + +[web] +server = apache ; apache | nginx +php_default = 8.3 + +[deploy] +webhook_secret = +repo_path = /opt/novacpx-src +web_root = /srv/novacpx/public +branch = main +``` + +## Auto-deploy (GitHub webhook) + +The installer sets up an auto-deploy pipeline so pushes to `main` go live within one minute. + +1. The webhook handler lives at `https://:8882/deploy/webhook.php` +2. Add a GitHub webhook: **Settings → Webhooks → Add webhook** + - Payload URL: `https://:8882/deploy/webhook.php` + - Content type: `application/json` + - Secret: value of `webhook_secret` in `config.ini` + - Events: **Just the push event** +3. The cron runner `/usr/local/bin/novacpx-deploy` runs every minute and processes the deploy queue +4. PHP syntax is validated before any files go live; bad commits are auto-rejected + +## Upgrading + +```bash +cd /opt/novacpx-src +git pull origin main +``` + +The deploy runner handles everything else (file sync, DB migrations, PHP-FPM reload). Or just push to your GitHub remote if the webhook is configured. + +## Uninstalling + +There is no automated uninstaller. To remove NovaCPX: + +```bash +rm -rf /srv/novacpx /opt/novacpx /opt/novacpx-src /etc/novacpx +mysql -e "DROP DATABASE novacpx; DROP USER 'novacpx_user'@'localhost';" +rm /etc/apache2/sites-enabled/novacpx.conf # or nginx equivalent +rm /etc/cron.d/novacpx +``` + +Service packages (Apache, Postfix, Dovecot, BIND9, etc.) are shared system services and are left in place. diff --git a/docs/reseller-guide.md b/docs/reseller-guide.md new file mode 100644 index 0000000..68b7cf8 --- /dev/null +++ b/docs/reseller-guide.md @@ -0,0 +1,107 @@ +# NovaCPX — Reseller Guide + +## Accessing the Reseller Panel + +The reseller panel runs on port **8881**. Navigate to `https://:8881` and log in with your reseller credentials. + +Your admin will provide your username and initial password. + +## Overview + +As a reseller you can create and manage hosting accounts for your customers. You only see accounts assigned to you — other resellers' accounts are hidden. The admin can see all accounts. + +## Accounts + +### Creating a customer account + +**Accounts → Create Account** + +| Field | Notes | +|-------|-------| +| Username | Lowercase, alphanumeric. Unique on the server. | +| Domain | Primary domain. DNS zone and web vhost created automatically. | +| Email | Customer's email. Receives welcome notification (if enabled). | +| Password | Min 8 characters. | +| Package | Resource limits. Available packages are defined by your admin. | +| PHP version | PHP-FPM version for this account. | + +### Managing accounts + +From **Accounts**, you can: + +- **Suspend** — disables the customer's website +- **Unsuspend** — re-enables it +- **Change Password** — reset the customer's panel and system password + +You cannot terminate accounts — contact your admin if an account needs to be removed. + +## Domains + +Under each account you can: + +- Add **addon domains** (additional websites on the same account) +- Add **subdomains** +- Add **redirects** +- View the document root for each domain + +## Email + +Manage virtual email addresses for your customers' domains: + +- Create mailboxes (username@domain.com) +- Set passwords +- Suspend / reactivate mailboxes +- Set storage quotas + +Customers access their email via the webmail interface at port 8883, or by configuring an email client with the server's hostname. + +### Webmail SSO + +Customers can be redirected to webmail with a single-sign-on link from the user panel. The SSO token is valid for 5 minutes. + +## DNS + +View and edit DNS records for accounts you manage. Standard record types are supported (A, AAAA, CNAME, MX, TXT, etc.). Changes are applied live via `rndc reload`. + +## Databases + +Create and manage MySQL databases for your customers. Each database is prefixed with the account username to avoid conflicts. + +## FTP + +Create FTP accounts scoped to specific directories of an account. Useful for giving customers access to subdirectories without full SSH. + +## Docker + +If Docker is enabled on the server, you can: + +- View containers running under your customers' accounts +- Set per-customer Docker quotas (max containers, RAM, CPU) +- Launch one-click app catalog deployments on behalf of a customer + +## White Label + +**White Label** lets you brand the reseller panel and user panel with your own identity. + +| Setting | Notes | +|---------|-------| +| Panel Name | Replaces "NovaCPX" in the panel header | +| Logo | Upload a PNG/JPG/SVG (max 512 KB) | +| Favicon | Small icon shown in browser tabs | +| Primary Color | Main accent color (hex) | +| Accent Color | Secondary color (hex) | +| Support Email | Shown in customer-facing error messages | +| Support URL | Link in the panel footer | +| Hide "Powered by NovaCPX" | Suppress the footer attribution | +| Custom CSS | Inject additional CSS into all panel pages | + +Changes take effect immediately for new page loads. + +## Customers logging in + +Your customers log in to the **user panel** at port **8880**. Give them: + +- URL: `https://:8880` +- Their username and password (set when you created their account) + +From the user panel they can manage their own files, email, databases, FTP accounts, DNS records, SSL certificates, and cron jobs. diff --git a/docs/user-guide.md b/docs/user-guide.md new file mode 100644 index 0000000..ec1fa9d --- /dev/null +++ b/docs/user-guide.md @@ -0,0 +1,194 @@ +# NovaCPX — User Guide + +## Accessing the User Panel + +The user panel runs on port **8880**. Navigate to `https://:8880` and log in with the username and password provided by your hosting provider. + +Your browser may warn about the self-signed certificate — accept it to continue. + +## Dashboard + +The dashboard shows a summary of your account: + +- Disk usage vs. your plan limit +- Number of email accounts, databases, domains, and FTP accounts in use +- Recent activity + +## Domains + +**Domains** shows all domains and subdomains on your account. + +### Adding a domain or subdomain + +Click **Add Domain** and choose: + +- **Addon domain** — a fully separate website hosted on your account +- **Subdomain** — a subdomain of your main domain (e.g. `blog.example.com`) +- **Redirect** — forwards visitors to another URL + +Each domain or subdomain gets its own document root directory. + +### Removing a domain + +You can remove addon domains and subdomains. The primary domain of your account cannot be removed. + +## File Manager + +The file manager lets you browse, create, edit, upload, and delete files in your account's home directory. + +### Navigation + +Click any folder to open it. Use the breadcrumb trail at the top to go back up. + +### File operations + +| Action | How | +|--------|-----| +| Edit a file | Click the filename | +| Create a file | Click **New File** | +| Create a folder | Click **New Folder** | +| Upload | Click **Upload** or drag files onto the panel | +| Download | Select a file → **Download** | +| Rename | Select a file → **Rename** | +| Delete | Select a file → **Delete** | +| Change permissions | Select a file → **chmod** | + +Files outside your home directory cannot be accessed. + +## Email + +**Email** manages mailboxes for your domains. + +### Creating a mailbox + +Click **Add Email Account**. Enter the local part (the part before `@`), select the domain, and set a password. An optional storage quota limits how much mail the mailbox can hold. + +### Accessing your email + +- **Webmail** — click **Webmail** in the panel sidebar to open Roundcube in a new tab. You are logged in automatically (single sign-on). +- **Email client (Thunderbird, Outlook, Apple Mail, etc.)** — use these settings: + - Incoming (IMAP): ``, port 993, SSL/TLS + - Outgoing (SMTP): ``, port 587, STARTTLS + - Username: your full email address (e.g. `you@example.com`) + - Password: the mailbox password you set in the panel + +### Suspending a mailbox + +Suspending stops new mail from being delivered but does not delete any messages. + +## Databases + +**Databases** manages MySQL databases for your account. + +### Creating a database + +Click **Create Database**. Enter a database name and password. The username is automatically created to match the database name (prefixed with your account username). + +Connection details: + +| Field | Value | +|-------|-------| +| Host | localhost (from PHP/scripts on the server) | +| Database | as shown in the panel | +| Username | as shown in the panel | +| Password | what you set | +| Port | 3306 | + +## FTP + +**FTP** creates FTP user accounts for uploading files. + +### Creating an FTP account + +Click **Add FTP Account**. Set a username, password, and the directory this account can access. The directory must be within your home directory. + +### Connecting + +Use any FTP client (FileZilla, Cyberduck, etc.): + +- Host: `` +- Port: 21 +- Username: the FTP username you created +- Password: the FTP password +- Protocol: FTP with explicit TLS (FTPES) + +## DNS + +**DNS** lets you manage the DNS records for your domains. + +Common tasks: + +- **Point a domain to a different IP** — edit or add an A record +- **Set up email (Google Workspace, etc.)** — add or change MX records +- **Verify domain ownership** — add a TXT record +- **Set up a CNAME** — point one name to another + +Changes are applied immediately (BIND9 reloads after each change). DNS propagation to the wider internet takes up to 24-48 hours depending on TTL. + +## SSL Certificates + +**SSL** manages HTTPS certificates for your domains. + +Click **Issue Certificate** next to a domain to request a free Let's Encrypt certificate. The domain must be publicly reachable (DNS must resolve to this server's IP) for the certificate to be issued. + +Certificates are renewed automatically 30 days before expiry. You will receive an email warning if a certificate is about to expire and has not been renewed. + +## Cron Jobs + +**Cron** schedules recurring tasks on the server. + +### Adding a cron job + +Click **Add Cron Job**. Enter: + +- **Schedule** — standard cron expression (e.g. `0 * * * *` for every hour) +- **Command** — the shell command or PHP script to run +- **Enabled** — toggle on/off without deleting + +Common schedules: + +| Expression | Runs | +|------------|------| +| `* * * * *` | Every minute | +| `0 * * * *` | Every hour | +| `0 0 * * *` | Daily at midnight | +| `0 0 * * 0` | Weekly on Sunday | +| `0 0 1 * *` | Monthly on the 1st | + +## PHP + +If your account has access to multiple PHP versions, the **PHP** section lets you switch the PHP version used for your account and configure per-account `php.ini` overrides (memory limit, upload size, execution time, etc.). + +## Docker + +If Docker is enabled for your account, **Docker** shows your containers. + +From this page you can: + +- **Start / stop / restart** containers +- **View logs** from a container +- **Launch an app** from the one-click catalog: + - WordPress + - Ghost + - Nextcloud + - Gitea + - Matomo (analytics) + - Vaultwarden (password manager) + - Node.js app + - Flask app + - Static website (Nginx) + +Your Docker quota (max containers, RAM, CPU) is set by your hosting provider. + +## Account Settings + +**Settings** lets you change your own panel password. + +To change your password: + +1. Go to **Settings** +2. Enter your current password +3. Enter and confirm your new password +4. Click **Save** + +Your new password takes effect immediately. If you also use FTP or SSH with this account, those passwords are updated as well.