# Deploying to a WHM/cPanel server (root SSH + MariaDB)

This assumes: root SSH access to the box, WHM already manages Apache
(EasyApache 4) and MySQL/MariaDB, and you're pointing a domain or subdomain
at this app.

## 1. Install Node.js (system-wide, outside cPanel's Node Selector)

Since you have root, install Node directly rather than using cPanel's
Passenger-based "Setup Node.js App" — this lets PM2 keep the process alive
indefinitely and run the real background cron worker.

```bash
curl -fsSL https://rpm.nodesource.com/setup_20.x | bash -
dnf install -y nodejs   # or `yum install -y nodejs` on older CloudLinux
node -v                  # confirm v20.x
npm install -g pm2
```

## 2. Check the server's OpenSSL version (for Prisma's binaryTargets)

```bash
openssl version
```

- `OpenSSL 3.x` → keep `rhel-openssl-3.0.x` in `prisma/schema.prisma`
- `OpenSSL 1.1.x` → use `rhel-openssl-1.1.x` instead
- `OpenSSL 1.0.x` (older CloudLinux 7) → use `rhel-openssl-1.0.x`

Edit the `binaryTargets` array in `prisma/schema.prisma` to match, then
leave `"native"` in the list too — harmless if you build directly on the
server (which the steps below assume).

## 3. Create the MariaDB database

Via WHM: **SQL Services → MySQL Databases** — create a database and a user,
add the user to the database with **All Privileges**. cPanel-style setups
prefix both names with your account username automatically
(`myuser_tempmail`, `myuser_dbuser`).

Or via shell:

```bash
mysql -u root -p
```
```sql
CREATE DATABASE myuser_tempmail CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'myuser_dbuser'@'localhost' IDENTIFIED BY 'a-strong-password';
GRANT ALL PRIVILEGES ON myuser_tempmail.* TO 'myuser_dbuser'@'localhost';
FLUSH PRIVILEGES;
```

## 4. Upload the project

```bash
mkdir -p /home/myuser/apps
cd /home/myuser/apps
# upload/extract tempmail-app.zip here, or git clone it
cd tempmail-app
cp .env.example .env
```

Leave `.env` as-is (placeholders) — the install wizard in step 6 fills in
`DATABASE_URL`, `NEXTAUTH_SECRET`, `CRON_SECRET`, and `INSTALL_COMPLETE` for
you. Only pre-fill `INBOUND_WEBHOOK_SIGNING_KEY` / `INBOUND_MX_HOST(_FALLBACK)`
by hand now if you'd rather not use the wizard's optional "Mail Provider" step.

## 5. Install & build

```bash
npm install
npm run build          # runs `prisma generate && next build`
```

> Keep devDependencies installed in production — `ts-node`, `typescript`,
> and `prisma` are all needed at runtime here (the purge worker runs under
> `ts-node`, and the install wizard shells out to `npx prisma db push` when
> you run it). Don't run `npm ci --omit=dev` / `npm prune --production`.

## 6. Start under PM2, then run the install wizard in your browser

```bash
pm2 start ecosystem.config.js
pm2 save
pm2 startup            # run the printed command once (as root) so PM2
                        # itself, and both apps, survive server reboots
```

Check status any time with `pm2 status` / `pm2 logs tempmail-web`.

Once the Apache reverse proxy in step 7 is wired up, visit your domain —
you'll land on `/install`. Walk through it: database connection (create the
DB first via WHM's MySQL Databases, or the shell block in step 3), admin
account, optional mail provider config, then "Install Now." It runs
`prisma db push` against your database, creates the tables, creates your
admin account, writes the rest of `.env`, and restarts both PM2 processes
automatically so the new config takes effect — then redirects you to
`/login`.

**Run this immediately after step 7** — until you complete it, `/install` is
reachable by anyone who finds the domain (same tradeoff WordPress's install
wizard has). It locks itself permanently after the first successful run.

If you'd rather skip the wizard entirely, the manual path still works — see
the README's "Alternative — fully manual setup" section (fill in `.env` by
hand, run `npx prisma db push` and `npm run seed` yourself).

## 7. Reverse-proxy the domain through Apache

Follow the instructions at the top of `deploy/apache-reverse-proxy.conf` —
it installs into cPanel's persistent per-domain include directory so it
survives cPanel's automatic vhost regeneration, then reload Apache.

**Firewall note:** port `3050` (the internal Next.js port) should only be
reachable from `127.0.0.1`, never from the public internet. If you run
CSF/firewalld, don't open that port externally — Apache is the only thing
that should talk to it, over localhost.

Let cPanel's AutoSSL issue the certificate for the domain as normal; Apache
terminates TLS and proxies to Node over plain HTTP internally, which is why
`ecosystem.config.js` binds Next.js to `127.0.0.1`-only traffic implicitly
(nothing in this stack listens on a public interface except Apache).

## 8. Inbound mail webhook + purge job

- Point your mail provider's inbound webhook at `https://yourdomain.com/api/inbound-mail`.
- The purge job is **already running continuously** as the `tempmail-purge`
  PM2 process (real `node-cron`, every 15 minutes) — you do not need to set
  up a WHM Cron Job for this. `app/api/cron/purge/route.ts` still exists as
  a manual/backup trigger if you ever want to force an immediate purge:
  ```bash
  curl -X POST https://yourdomain.com/api/cron/purge \
    -H "Authorization: Bearer $CRON_SECRET"
  ```

## 9. Redeploying after code changes

```bash
cd /home/myuser/apps/tempmail-app
git pull            # or re-upload changed files
npm install          # only if dependencies changed
# only if schema.prisma changed:
npx prisma db push --accept-data-loss --schema=prisma/schema.prisma
npm run build
pm2 restart ecosystem.config.js
```
