# Deploying to cPanel (Node.js App + PostgreSQL)

This guide is for a cPanel host that has **both** "Setup Node.js App"
(under Software) **and** "PostgreSQL Databases" (under Databases) —
confirm both are present before starting; without either one, this
specific path doesn't apply (see the main README's deployment section
for the Netlify + free-Postgres alternative instead).

## Before you start: one thing to check

Look for a **"Terminal"** icon in cPanel (usually under "Advanced").
It changes which method you use for one step below (setting up the
database schema), but **you can proceed either way** — this guide
covers both.

## 1. Create the PostgreSQL database

1. cPanel → **Databases → PostgreSQL Database Wizard**
2. Create a new database (e.g. `cbt_platform`) — cPanel will likely
   prefix it with your account username, e.g. `youruser_cbt_platform`.
   Note the **full prefixed name**.
3. Create a database user with a strong password — again, cPanel
   usually prefixes the username too (e.g. `youruser_cbtadmin`). Note
   the full username and the password.
4. Grant that user **ALL PRIVILEGES** on the database when prompted.
5. Note the **database host** — for a database used by an app running
   on the *same* cPanel account, this is almost always `localhost`.
   The port is almost always `5432`.

Your connection string (you'll need this in step 3) will look like:
```
postgresql://youruser_cbtadmin:yourpassword@localhost:5432/youruser_cbt_platform
```

## 2. Upload the code

Pick whichever of these your host supports:

- **Git Version Control** (cPanel → Files → Git™ Version Control, if
  present) — point it at your GitHub repo, cPanel clones it directly.
- **File Manager / FTP** — zip the project locally (excluding
  `node_modules` — it'll be installed on the server), upload the zip
  via cPanel's File Manager into a folder **outside** `public_html`
  (e.g. `~/cbt-platform`), then extract it there. Node apps on cPanel
  should not live directly in `public_html` — the Node.js App setup
  in the next step handles routing traffic to it.

## 3. Set up the Node.js App

1. cPanel → **Software → Setup Node.js App → Create Application**
2. **Node.js version:** pick the highest available — this project
   needs **Node 20 or newer**. If your host only offers something
   older (16/18), stop here and tell me what versions are listed —
   there are workarounds but they depend on exactly what's available.
3. **Application mode:** Production
4. **Application root:** the folder you uploaded to (e.g.
   `cbt-platform`)
5. **Application URL:** your domain or a subdomain
   (e.g. `cbt.yourschool.com`)
6. **Application startup file:** `server.cpanel.js` (already included
   in this project specifically for this — see the comment in that
   file for why it's needed instead of just running `next start`
   directly)
7. Click **Create**.

## 4. Set environment variables

Still on the Node.js App page, there's an **environment variables**
section — add these (this is the cPanel-native way; don't rely on a
`.env` file being read automatically here):

| Variable | Value |
|---|---|
| `DATABASE_URL` | the connection string from step 1 |
| `NEXTAUTH_URL` | `https://cbt.yourschool.com` (your actual app URL) |
| `NEXTAUTH_SECRET` | generate with `openssl rand -base64 32` on your own machine |
| `NODE_ENV` | `production` |
| `BUILD_TARGET` | *(leave unset — that's only for the Docker build)* |

Everything else in `.env.example` (AI, payments, S3) is optional at
launch, same as with any deployment target — those features fail
gracefully with a clear error only when actually used.

## 5. Install dependencies and build

On the same Node.js App page, cPanel shows a **"Run NPM Install"**
button — click it. This also runs `prisma generate` automatically
(the project's `postinstall` script does this for you on every
install, on any host).

Then you need to run `next build` once. If your host has a
**Terminal**, this is the easy path — see step 6a. If not, see step
6b.

## 6a. If you have Terminal access

Open cPanel's Terminal, then:

```bash
# cPanel's Node.js App page shows an "Enter to the virtual environment"
# command at the top — run that first so `node`/`npm` point at the
# right version, then:
cd ~/cbt-platform
npm run build
npx prisma migrate deploy
npm run prisma:seed   # optional — demo data; skip for a real launch
```

Then go back to the Node.js App page and click **Restart**.

## 6b. If you do NOT have Terminal access

You can still do both remaining steps (`next build` doesn't strictly
need to run on the server for a non-standalone build — but the
database migration does need to reach the actual production
database, not a local one):

1. **Enable Remote Database Access** so your own computer can reach
   the cPanel Postgres database: cPanel → Databases → **Remote
   Database Access** → add your current IP address (search "what's my
   ip" to find it).
2. On your **own machine**, with this project and its dependencies
   installed locally:
   ```bash
   export DATABASE_URL="postgresql://youruser_cbtadmin:yourpassword@YOUR_SERVER_HOSTNAME:5432/youruser_cbt_platform"
   npx prisma migrate deploy
   npm run prisma:seed   # optional
   ```
   Use your **server's actual hostname or IP** here, not `localhost`
   (`localhost` only works when the command runs on the server
   itself).
3. For the build itself: many cPanel Node.js App setups will run the
   build automatically on restart if you don't have Terminal access;
   if yours doesn't, this specific step genuinely needs either
   Terminal access or asking your host's support to run `npm run
   build` once for you — this is the one part of the process that's
   hard to fully avoid without any shell access at all.
4. Once the database is migrated, go to the Node.js App page and
   click **Restart**.

## 7. Verify it's live

Visit your app URL. You should see the login page. Then work through
`TESTING.md` in this project — same verification steps regardless of
which host you deployed to.

## Realistic limits of this path, stated plainly

- **Shared hosting has real resource limits** (RAM, CPU, sometimes a
  cap on concurrent Node processes) that a VPS or serverless platform
  doesn't. For a single school's exam traffic this is likely fine to
  start, but if you notice slowness during a live exam with many
  students submitting/autosaving at once, that's the honest reason —
  not a bug in the code.
- **Prisma's compiled query engine has to match your server's Linux
  environment.** This project already includes multiple binary
  targets defensively (see `prisma/schema.prisma`'s `generator`
  block) to reduce the risk of a "query engine not found" error, but
  if you hit exactly that error, it means your host's specific OS/
  OpenSSL version needs one more target added — tell me the exact
  error and I'll add it.
- **If something doesn't match what's described here** (a missing
  button, a differently-named option), cPanel's exact layout varies
  by hosting company even though the base software is the same —
  tell me what you see and I'll adjust the instructions to match.
