# Installation

> On a cPanel server, follow **docs/CPANEL-SETUP.md** instead — it covers the subdomain, database, PHP version, cron and SMTP in cPanel terms.

Admin area: `https://panel.example.com/shozi-panel` (change `admin_path` in `config/config.php`). The plain `/admin` path returns 404.

## 1. Requirements
- PHP 8.2+ with `pdo_mysql`, `curl`, `sodium`, `mbstring`, `openssl`
- **MySQL 8.0.1+ / MariaDB 10.6+** (required for the `SKIP LOCKED` queue; SQLite is for tests only)
- A subdomain with HTTPS, e.g. `panel.example.com`
- Outbound access to `api.leaseweb.com` and SSH (port 22) + RDP (3389) to your VPS IPs (Windows install checks)

## 2. Upload and point the web root
Upload the folder (e.g. `/home/panel/cloudpanel`). Set the subdomain's **document root to `public/`**.
Nothing outside `public/` must be web-reachable.

**Nginx**
```nginx
server {
    server_name panel.example.com;
    root /home/panel/cloudpanel/public;
    index index.php;
    location / { try_files $uri /index.php?$query_string; }
    location ~ \.php$ { include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass unix:/run/php/php8.2-fpm.sock; }
    location ~ /\. { deny all; }
}
```
**Apache / cPanel**: `public/.htaccess` is included (mod_rewrite). It also passes the `Authorization` header the WHMCS module uses.

## 3. Configure
```bash
cp config/config.example.php config/config.php
php bin/install.php --key            # paste the output into app_key
```
Edit `config/config.php`: `url`, database DSN/user/pass, `app_key`. **Back up `app_key`** — it decrypts API keys and server passwords; never change it after go-live.

```bash
php bin/install.php --admin-email=you@example.com --admin-password='a-long-password' --admin-name=Shozi
chmod -R 750 storage
```
Re-running `php bin/install.php` after an update applies schema changes safely.

## 4. Worker (required)
The worker places orders, follows delivery, installs OS/Windows, resets passwords, sends email and handles suspensions and cancellations.

**Production (VPS / dedicated host) – systemd lanes** (picks jobs within ~1 s, restarts itself hourly):
```bash
sudo cp docs/systemd/shozi-cloud-worker@.service /etc/systemd/system/   # edit User/paths
sudo systemctl daemon-reload
sudo systemctl enable --now shozi-cloud-worker@0 shozi-cloud-worker@1 shozi-cloud-worker@2 shozi-cloud-worker@3
```
Lane 0 also runs housekeeping and email. Add lanes for more parallel installs; the Leaseweb rate limiter (Settings → *API requests per second, per account*) keeps the total safe.

**Simple / shared hosting – cron:**
```
* * * * * php /home/panel/cloudpanel/bin/worker.php >/dev/null 2>&1
```
Use one of the two, not both. Admin → System health shows whether it runs.

**Several web servers:** set `'session_driver' => 'database'` in `config/config.php`; run the worker lanes on one or more hosts (claims are row-locked).

## 5. Panel setup (Admin area)
1. **Leaseweb accounts** → add one account per Leaseweb entity you buy from (e.g. *Leaseweb Netherlands*, *Leaseweb USA*, *Leaseweb Asia*), each with the API key from that entity's Customer Portal → *Test*. Whitelist the panel's IP on each key.
2. **Locations** → add Leaseweb location codes (e.g. `eu-west-3` Amsterdam, `us-east-1`…) and **bind each to the account that owns that region**. Servers in a location are always ordered and managed with its account's key.
3. **Packages** → name and specs, then per location: tick *Offer*, *Load plans* (reads that location's account) → pick the plan, *Options* → exact disk-upgrade / SLA names. Plan IDs may differ per entity.
4. **Operating systems**
   - *Import order OS list* (package + location) → all Leaseweb OS appear.
   - After the first server is delivered: *Import reinstall images* → pairs each OS with its reinstall image ID (needed for Linux reinstalls). An image without an order name is installed by ordering Ubuntu and reinstalling.
   - Windows templates are pre-created (Server 2025/2022/2019, 11 Pro, 10 Pro). Edit the installer image name / language / optional HTTPS ISO.
   - Tick the allowed OS on each package.
5. **Settings → Email** → SMTP host/port/encryption/user/password, From address. Then **Admin → Email → Send test**. Edit templates there (install, reinstall, password reset, suspension, traffic, forgot-password, staff alert). *Include the server password* can be turned off if you prefer clients to read it in the panel only.
6. **Branding** → names, logos, favicon, colours, copyright, login text and email design. **Settings** → staff alert email, **pin the installer SHA-256**, client permissions (reinstall, snapshots, rDNS, console, password reset, ISO), action limits, *Require two-factor for staff*.
7. **API tokens** → create one restricted to your WHMCS server IP.
8. **Users** → add support agents with the *Support* role (servers and clients only; no catalogue, accounts, settings, tokens or email).

## 6. WHMCS
1. Upload `whmcs/modules/servers/shozicloudpanel/` to `<whmcs>/modules/servers/`.
2. System Settings → Servers → Add: type **Shozi Cloud Panel**, hostname `panel.example.com`, **Access Hash = API token**, tick *Secure*. *Test Connection*. Put the server in a server group.
3. Product → Module Settings → **Shozi Cloud Panel** (the dropdowns load live from the panel):
   1. **Location** – the Leaseweb location this product sells.
   2. **Plan** – panel packages offered in that location (the list filters to the chosen location).
   3. **Default OS** – optional OS slug when the order has no OS choice.
   4. **Additional Disks** – tick to sell Leaseweb disk upgrades.
   5. **Configurable Options** – leave ticked. On *Save Changes* the module creates/refreshes a configurable-option group for the product with **Operating System** (the package's allowed OS) and **Additional Disk** (the disk upgrades Leaseweb offers for that plan, limited by the package's *Disks clients may add*). Set prices in *Configurable Options*; refreshing never overwrites your prices and hides choices that disappear. Admin button *Refresh Configurable Options* does the same from a service.
   6. **WHMCS Welcome Email** – leave off and set the product's Welcome Email to **None**; the panel emails the client when the server is ready.
4. Automatically set up the product on payment. WHMCS marks the service **Active** right away; the panel shows "Assigning server" until it is installed, then copies IP and credentials back into the service (cron hook and service page).
5. Billing cycles map to the Leaseweb term: Monthly, Quarterly, Semi-Annually, Annually, Biennially, Triennially.

**Client panel account.** The first order of a WHMCS client creates the panel account (same email, name, company, phone, country) and emails a *set your password* link. The WHMCS service page shows:
- **Open Control Panel** (single sign-on, one-time link)
- the panel **login URL** and **email**
- **Reset control panel password** (new password shown once on the page) and **Email me a reset link**
Clients can also use *Forgot password* on the panel login page.

> Upgrading the WHMCS module from v1: field order changed (1 Location, 2 Plan, 3 Default OS, 4 Additional Disks, 5 Configurable Options, 6 WHMCS Welcome Email). Open each product's Module Settings once, choose Location and Plan again, and save.

## 6b. Manual ordering (Leaseweb API ordering not active)
Admin → Locations → edit → **Ordering: Manual** (or Settings → *Leaseweb ordering: Manual everywhere*).
- New servers in that location stop at **Assigning server**; nothing is ordered through the API. The client and WHMCS see "it may take a few minutes to be allocated".
- Staff alert email + dashboard banner + server *Admin* tab show exactly what to order: Leaseweb account, location, plan ID, OS to select (Ubuntu for Windows servers — the panel installs Windows afterwards), additional disk, SLA, term, reference.
- After ordering in the Leaseweb Customer Portal, enter the **order ID** (*Track order* — the panel polls until the VPS and IP are delivered) or the **VPS ID** (*Attach VPS*). The panel then installs the OS, emails the client and updates WHMCS. Tick *ordered with the target OS* for Leaseweb images to skip the reinstall.

## 7. Lifecycle mapping
| WHMCS | Panel | Leaseweb |
|---|---|---|
| Create | user created/linked, server queued | order placed (paced), delivery followed, OS/Windows installed |
| Suspend | client controls locked | VPS stopped (also after an install finishes) |
| Unsuspend | controls unlocked | VPS started |
| Terminate | server terminated | service cancelled (waits for delivery if still ordering) |
| Change Package | package/OS list/limits updated | plan **not** resized (do it at Leaseweb if specs change) |

## 8. Migrating services from the old WHMCS module
Admin → New server → **Import existing VPS**: VPS ID, WHMCS service ID, package, OS, current login. Nothing is reinstalled. Then switch the WHMCS product/service to the Shozi Cloud Panel module.

## 9. Recovery
A server in **Needs review** shows the exact reason in its *Admin* tab:
- *Retry failed step* – safe for everything except an uncertain order.
- *Link an existing Leaseweb order* – when Leaseweb accepted an order but the response was lost.
- *Order again* – only after confirming in Leaseweb that no order exists (a second order is billed).
- *Mark as ready manually* – when you finished the install by hand.

## 10. Password reset, SSH keys, snapshots, ISO
- **Leaseweb OS images**: *Access → Reset password*. The panel stops the VPS, calls Leaseweb's reset, waits for the new credential, starts the VPS and emails the password (Leaseweb requires the VPS to be stopped for a reset).
- **Custom Windows**: not available — Leaseweb's password service does not manage this install. The panel explains this to the client (change it inside Windows, or reinstall for new credentials).
- **SSH keys**: clients save keys under Account; selected keys (or *auto-add* keys) are written to `/root/.ssh/authorized_keys` after Linux installs.
- **Snapshots**: Leaseweb cannot reinstall a VPS that has snapshots, so reinstall asks the client to delete them first.
- **ISO** (off by default, *beta*): attach/detach Leaseweb ISOs, then boot from the console. Verify on staging before enabling for clients.

## 11. Upgrading from v1.0
1. Back up the database and `config/config.php`.
2. Upload the new files (keep `config/` and `storage/`), then run `php bin/install.php`. Schema v2 is applied; each location gets the Leaseweb account of the package that used it, and each package's plan is copied to its locations.
3. Open **Locations** and fix the account of any location that belongs to a different Leaseweb entity; open each **Package** and check the plan per location.
4. Configure **Settings → Email** and send a test.
5. Optionally switch from cron to systemd lanes (section 4).

## 12. Staging checklist (do before paid orders)
0. Product settings: pick Location and Plan, save, and check the generated *Operating System* / *Additional Disk* configurable options and their prices.
1. Order one Linux and one Windows server through WHMCS, in locations of **two different Leaseweb entities**.
2. Confirm IP/password appear in WHMCS and the *server ready* email arrives once.
3. Reinstall Linux → Windows and Windows → Linux; confirm the *reinstalled* emails.
4. Reset the password of the Linux server; confirm the VPS restarts and the email arrives.
5. Suspend/unsuspend from WHMCS; confirm the VPS stops/starts and emails go out.
6. Terminate; confirm the Leaseweb service shows as cancelled.
7. On MySQL/MariaDB, run 3–4 worker lanes and order several servers at once; confirm no job runs twice (Admin → Job queue).
8. Pin the installer SHA-256 and enable *Require two-factor for staff*.
9. Set one location to Manual, order through WHMCS, place the Leaseweb order by hand, track it in the panel and confirm WHMCS receives the IP.
10. From the WHMCS service page: *Reset control panel password*, sign in with it, and *Email me a reset link*.
