# Deploying ShipRex CMS/API on cPanel (Phusion Passenger)

This app is designed for cPanel's **Setup Node.js App** feature (Phusion
Passenger). Follow these steps top to bottom.

---

## 0. Requirements

- cPanel with **"Setup Node.js App"** (CloudLinux + Passenger) available
- A **Node.js 22+** option in the Node version dropdown (required — the chatbot's
  AI SDK needs Node ≥ 22)
- A **MySQL** database

---

## 1. Create the MySQL database

cPanel → **MySQL® Databases**:

1. Create a database, e.g. `cpaneluser_shiprex`.
2. Create a user and a strong password.
3. **Add the user to the database** with **ALL PRIVILEGES**.

> Note the *real* (prefixed) names — cPanel prefixes them with your account,
> e.g. database `cpaneluser_shiprex`, user `cpaneluser_shiprexapp`.

---

## 2. Upload the code

Pick one:

- **Git** (recommended): cPanel → *Git Version Control* → clone your repo into a
  folder **outside** `public_html`, e.g. `/home/cpaneluser/shiprex-api`.
- **Zip upload**: upload + extract into that folder via *File Manager*.

Do **not** upload `node_modules` or `.env`.

---

## 3. Create the Node.js application

cPanel → **Setup Node.js App** → **Create Application**:

| Field | Value |
|-------|-------|
| **Node.js version** | **22.x or higher** (required by the AI SDK) |
| **Application mode** | Production |
| **Application root** | `shiprex-api` (the folder from step 2) |
| **Application URL** | the domain/subdomain, e.g. `api.shiprex.com` |
| **Application startup file** | `app.js` |

Click **Create**. Passenger writes the required directives into the document
root's `.htaccess` automatically — you don't edit those by hand.

---

## 4. Set environment variables

In the same screen, under **Environment variables**, add everything from
`.env.example` with real values. At minimum:

```
NODE_ENV=production
APP_URL=https://api.shiprex.com
PUBLIC_API_URL=https://api.shiprex.com/api/v1

DB_HOST=localhost
DB_PORT=3306
DB_NAME=cpaneluser_shiprex
DB_USER=cpaneluser_shiprexapp
DB_PASSWORD=********

SESSION_SECRET=<openssl rand -hex 32>
JWT_SECRET=<openssl rand -hex 32>
COOKIE_SECURE=true

CORS_ALLOWED_ORIGINS=https://www.shiprex.com
BOOTSTRAP_API_KEY=<openssl rand -hex 24>

ADMIN_EMAIL=you@shiprex.com
ADMIN_PASSWORD=<a strong password>
```

> cPanel environment variables **override** the `.env` file, so you don't need
> to upload `.env` at all in production. Keeping secrets only in cPanel is safer.

Add the Brevo and AI keys here too when you're ready to enable those features.

---

## 5. Install dependencies

In the Node.js App screen, click **Run NPM Install**.

Or via SSH (enter the app's virtualenv — cPanel shows the exact `source ...`
command on the app screen):

```bash
source /home/cpaneluser/nodevenv/shiprex-api/22/bin/activate
cd /home/cpaneluser/shiprex-api
npm install --omit=dev
```

> The chatbot uses **Gemini** via `@ai-sdk/google` (a normal dependency installed
> by `npm install`). To enable it, set `GOOGLE_API_KEY` (or `GEMINI_API_KEY`) in
> the env. Requires **Node ≥ 22**.

---

## 6. Run migrations + seed

Over SSH, inside the activated virtualenv (step 5):

```bash
npx sequelize-cli db:migrate
npx sequelize-cli db:seed:all
```

This creates all tables and the first admin user (from `ADMIN_EMAIL` /
`ADMIN_PASSWORD`), a sample KB article, and an API client matching
`BOOTSTRAP_API_KEY`.

> No SSH? Temporarily add a one-off script or use cPanel's *Terminal*. Migrations
> only need to run on deploy and after schema changes.

---

## 7. Start / restart

Click **Restart** on the Node.js App screen after any code or env change.

Passenger also restarts when `tmp/restart.txt` changes. The repo includes a
helper:

```bash
npm run cpanel:restart      # touches tmp/restart.txt
```

---

## 8. Verify

- `https://api.shiprex.com/health` → `{ "ok": true, "db": "up" }`
- `https://api.shiprex.com/api/v1/status` → feature flags
- `https://api.shiprex.com/admin` → admin login

---

## 9. Hook up the marketing website

1. In the admin portal → **API & Settings**, create a dedicated API client and
   copy its key (shown once). Or reuse the `BOOTSTRAP_API_KEY`.
2. Store that key in the **marketing site's server-side** environment — never in
   client-side JavaScript.
3. Have the website's backend call `PUBLIC_API_URL` endpoints with the key.
4. Add the website's origin to `CORS_ALLOWED_ORIGINS` if any browser calls are
   made directly.

---

## Troubleshooting

| Symptom | Fix |
|---------|-----|
| 503 / "Incomplete response" | Check the app's **stderr log** (Node.js App screen). Usually a bad `DB_*` value or a missing env var. |
| `ER_ACCESS_DENIED` | DB user not added to the DB, or wrong prefixed name. |
| Admin login redirect loop | `COOKIE_SECURE=true` without HTTPS — install SSL or set it `false` temporarily. |
| FULLTEXT migration error | Ensure MySQL 5.6+ / InnoDB. The chatbot falls back to LIKE search if the index is missing. |
| Chatbot returns the fallback message | `GOOGLE_API_KEY` not set, or Node < 22, or a model/SDK mismatch — check the stderr log for "Gemini generate failed". |
| Changes not taking effect | Click **Restart**, or `npm run cpanel:restart`. |

---

## Continuous deploy (optional)

If you use cPanel Git, add a `.cpanel.yml` to auto-deploy on push. A minimal
example that copies the repo into the app root:

```yaml
---
deployment:
  tasks:
    - export DEPLOYPATH=/home/cpaneluser/shiprex-api
    - /bin/cp -R * $DEPLOYPATH
    - /bin/cp -R .htaccess $DEPLOYPATH 2>/dev/null || true
```

Run `npm install` + migrations manually (or via SSH task) after structural
changes, then **Restart** the app.
