# Deploying BD Market to woobd.foryoucommunity.com

A step-by-step walkthrough for your cPanel shared hosting, using the two tools you have:
**Setup Node.js App** and **Terminal**.

The zip (`woobd-shared-hosting.zip`) already contains a **finished production build**, so you do
not need to compile anything on the server. You upload it, import the database, point cPanel at it,
and click Restart.

---

## What's in the zip

| Included | Why |
| --- | --- |
| `app/`, `components/`, `lib/`, `prisma/`, `middleware.ts` | The application source |
| `.next/` (without `cache/`) | **Pre-built production bundle** — no build step needed on the server |
| `public/` | Icons, favicon, and the writable `uploads/` folder |
| `package.json`, `package-lock.json` | Dependency manifest — the server installs its own Linux binaries |
| `next.config.js`, `tailwind.config.js`, `postcss.config.js`, `tsconfig.json` | Build/config files |
| `.env` | Pre-filled with your database URL, site URL and a fresh `AUTH_SECRET` |
| `app.js` | **The startup file cPanel needs** (see Step 3) |
| `scripts/ensure-prisma.js` | Generates the Prisma client from any working directory — see Step 4 |
| `scripts/`, `setup.js` | Installer and helper scripts, including the SQL generators |
| `DEPLOY-SHARED-HOSTING.md` | This guide |

| Excluded | Why |
| --- | --- |
| `node_modules/` | Contains Windows binaries. The server installs its own. |
| `.next/cache/` | Regenerable build cache, hundreds of MB |
| `.git/`, `.workbuddy-ai/`, `*.zip` | Not part of the app |
| `prisma/dev.db`, `prod.db` | Local SQLite scratch databases — you are on MySQL |

> **Important:** never copy `node_modules/` from your PC to the server. Prisma's database engine is
> a native binary compiled per-platform — a Windows `.dll` will not load on Linux. Running
> `npm install` on the server is what fetches the correct engine.

---

## Your values

| Thing | Value |
| --- | --- |
| Site URL | `https://woobd.foryoucommunity.com` |
| Database name | `foryouc1_woobd` |
| Database user | `foryouc1_woobd` |
| Database password | `romendev4564` |
| Database host (for Node) | `127.0.0.1` — **not** `localhost` |
| Application root | `woobd.foryoucommunity.com` → `/home/foryouc1/woobd.foryoucommunity.com` |
| Node.js version | `24.20.0` (any 18.17+ works) |

> **Path convention used throughout this guide.** `~/woobd.foryoucommunity.com` means your
> **application root** — the folder that directly contains `package.json`. If you chose a different
> folder in Step 1, substitute that path everywhere. Confirm yours with:
>
> ```bash
> ls -la ~/woobd.foryoucommunity.com/package.json
> ```

---

## Step 1 — Upload and extract

1. cPanel → **File Manager**.
2. Navigate to your **application root** — the folder that will directly contain `package.json`.
   Either of these works:
   - the **subdomain's own folder**, `/home/foryouc1/woobd.foryoucommunity.com/`
   - your **home directory**, `/home/foryouc1`, giving `/home/foryouc1/woobd/`
3. Click **Upload**, choose `woobd-shared-hosting.zip`, wait for it to finish.
4. Right-click the zip → **Extract** → **Extract Files**.
5. The zip contains a single top-level `woobd/` folder. **Move its contents up** so that
   `package.json` sits directly inside your application root.

   | You extracted into | You get | Do this |
   | --- | --- | --- |
   | `woobd.foryoucommunity.com/` | `woobd.foryoucommunity.com/woobd/package.json` | Open `woobd/`, select everything inside, **Move** to `woobd.foryoucommunity.com/`, overwrite, then delete the empty `woobd/` |
   | `/home/foryouc1` | `/home/foryouc1/woobd/package.json` | Nothing — `woobd` is already your application root |
6. Delete the zip afterwards to save space.

> **The one rule that matters:** the application root must contain `package.json` **directly**. If
> `package.json` sits one level deeper, `npm install` finds nothing to install and Prisma cannot
> locate its schema. Verify before continuing — both paths must exist:
>
> ```bash
> ls -la ~/woobd.foryoucommunity.com/package.json ~/woobd.foryoucommunity.com/prisma/schema.prisma
> ```

---

## Step 2 — Create the database tables

The database `foryouc1_woobd` exists but is empty. Pick **one** of these two methods.

### Method A — phpMyAdmin import (easiest, recommended)

1. cPanel → **phpMyAdmin**.
2. In the left sidebar click the database **`foryouc1_woobd`**.
3. Click the **Import** tab at the top.
4. Click **Choose File** and navigate to `~/woobd.foryoucommunity.com/prisma/`:
   - **`schema-with-demo.sql`** → drops and recreates all **27 tables**, then loads **668 demo rows**
     across 23 of them (38 products, categories, brands, blog posts, orders, customers, settings,
     menus and a demo admin account). Choose this if you want a store you can click around in
     immediately.
   - **`schema.sql`** → creates the same **27 tables, empty**. Choose this for a clean store.
5. Scroll down and click **Go**. Wait for the green success message.

> **Pick the right file for your situation.** `schema.sql` uses plain `CREATE TABLE` with no `DROP`,
> so it fails with `#1050 Table already exists` if you have imported before — that is safe, it just
> errors out and changes nothing.
>
> `schema-with-demo.sql` is the opposite: it **wipes** whatever is in the database and reloads the
> demo catalogue. It is safe to re-import while you are still setting up, but **never run it once
> you have real orders or customer accounts**.

### Method B — Terminal

```bash
cd ~/woobd.foryoucommunity.com
source /home/foryouc1/nodevenv/woobd.foryoucommunity.com/24/bin/activate   # use the exact path cPanel shows
npx prisma db push
```

`prisma db push` creates the empty tables only. To also load the demo catalogue afterwards:

```bash
npm run db:seed
```

---

## Step 3 — Create the Node.js app

cPanel → **Setup Node.js App** → **Create Application**. Fill the form exactly like this:

| Field | Value |
| --- | --- |
| **Node.js version** | `24.20.0` |
| **Application mode** | `Production` |
| **Application root** | the folder holding `package.json` — `woobd` **or** `woobd.foryoucommunity.com` |
| **Application URL** | `woobd.foryoucommunity.com` |
| **Application startup file** | `app.js` |
| **Passenger log file** | leave blank (cPanel fills in a sensible default) |

> The **Application root** must match Step 1 exactly. cPanel uses it to name the Node virtualenv
> (`/home/foryouc1/nodevenv/<application-root>/24/`), so if you see `woobd.foryoucommunity.com` in
> that path, that is the root you selected — make sure `package.json` really is directly inside it.

### ⚠️ The startup file must be `app.js`, not Next's CLI

`app.js` is included in the zip specifically for this field. cPanel runs Node apps through
**Phusion Passenger**, which needs a startup file that opens a listening socket on the port it
assigns. Next.js's own CLI (`node_modules/next/dist/bin/next`) opens its own listener and never
reports the port back, so pointing this field at Next produces **502 Bad Gateway**.

`app.js` does four things: loads `.env`, pins the working directory, boots Next in production mode,
and listens on Passenger's port.

### Environment variables

Still on the same screen, scroll to **Environment variables** → **Add Variable** and add these three:

| Name | Value |
| --- | --- |
| `DATABASE_URL` | `mysql://foryouc1_woobd:romendev4564@127.0.0.1:3306/foryouc1_woobd` |
| `AUTH_SECRET` | `236e1cb748f88baaa46131857d3277fa0b067255b47eb8c11c0549b36d392332f53898f32a7af9f336c27772af719050` |
| `NEXT_PUBLIC_SITE_URL` | `https://woobd.foryoucommunity.com` |

These duplicate the `.env` file that ships in the zip — that is intentional. The `.env` is the
fallback; cPanel's panel is the one that survives if the file is ever moved or overwritten. If the
two disagree, cPanel wins.

> **Why `127.0.0.1` and not `localhost`?** PHP reaches MySQL over a local socket, so `localhost`
> works for PHP apps. Node connects over TCP and resolves `localhost` to the IPv6 loopback `::1`,
> which your database user is not granted for. You would get
> `Access denied for user 'foryouc1_woobd'@'::1'`. `127.0.0.1` forces IPv4 and always works.

Now click **CREATE** at the top right.

---

## Step 4 — Install dependencies

Back on the **Setup Node.js App** page, find your new app and click **Run NPM Install**.

This runs `npm install` inside the app's Node virtual environment. It takes 2–5 minutes and pulls
down ~160 packages.

When it finishes, click **RESTART**.

### Or do it in the Terminal

```bash
cd ~/woobd.foryoucommunity.com
source /home/foryouc1/nodevenv/woobd.foryoucommunity.com/24/bin/activate
npm install
```

Use whichever `activate` path cPanel displays on the app row — the `24` is the Node major version.

### About the Prisma client

The app needs Prisma's **Linux** query engine (`libquery_engine-debian-openssl-3.0.x.so.node`), which
is produced by `prisma generate` on the server.

**On cPanel, that happens on the app's first boot, not during `npm install`.** This is deliberate.
cPanel runs npm lifecycle scripts with the working directory set to the Node virtualenv's `lib`
folder — `/home/foryouc1/nodevenv/woobd.foryoucommunity.com/24/lib` — so a `postinstall` hook that
references `scripts/...` by a relative path cannot resolve it. The `postinstall` hook here is written
to detect that and step aside quietly instead of failing your install.

`app.js` then generates the client on first boot, using paths derived from its own location, so the
working directory is irrelevant. Expect the first boot to take about 10 seconds longer than later
ones. You will see this in the log:

```
[prisma] Prisma client not generated — generating.
[prisma] Client generated.
[boot] BD Market ready — listening on port ...
```

Later boots are immediate: `[prisma] Client already present (libquery_engine-debian-openssl-3.0.x.so.node).`

If you ever need to run it by hand:

```bash
cd ~/woobd.foryoucommunity.com
source /home/foryouc1/nodevenv/woobd.foryoucommunity.com/24/bin/activate
npx prisma generate
```

That works because `npx` finds the CLI through the app root's `node_modules`, and the working
directory is the app root, so the schema is found normally.

You can confirm it worked at any time — a healthy client has an engine file:

```bash
ls ~/woobd.foryoucommunity.com/node_modules/.prisma/client/ | grep engine
```

Expect to see `libquery_engine-debian-openssl-3.0.x.so.node`. Seeing only
`query_engine-windows.dll.node` means a Windows `node_modules` was uploaded; delete the folder on the
server and re-run `npm install`.

---

## Step 5 — Verify

Open these in order. Stop at the first one that fails and check Troubleshooting.

**1. Health check** — `https://woobd.foryoucommunity.com/api/health`

A working deployment returns:

```json
{
  "ok": true,
  "database": "connected",
  "settings": 105,
  "authSecretConfigured": true,
  "siteUrl": "https://woobd.foryoucommunity.com",
  "latencyMs": 12
}
```

The `settings` number is just the row count in the `Setting` table — it proves the tables exist and
are readable. Any positive number is fine; `0` means you imported `schema.sql` instead of
`schema-with-demo.sql`, which is also valid, just an empty store.

If `ok` is `false`, the JSON also contains a `problem` and a `hint` naming the exact cause — for
example `database-url-missing`, `schema-not-pushed` (you skipped Step 2), or `database-auth-failed`.
This endpoint never leaks credentials, so it is safe to share the output.

**2. Storefront** — `https://woobd.foryoucommunity.com` — the homepage should load with images and
styling.

**3. Admin** — `https://woobd.foryoucommunity.com/admin`

If you imported `schema-with-demo.sql`:

| Email | Password |
| --- | --- |
| `admin@bdmarket.com.bd` | `admin123` |

**Change this password immediately** — it is published in the project's public documentation.

**4. SEO files** — `/sitemap.xml` returns XML, `/robots.txt` returns text.

**5. Upload test** — Admin → **Media** → upload an image, then confirm it displays. This is the one
test that proves the writable `public/uploads/` path works. If it 404s, see Troubleshooting.

---

## Everyday operations

### After changing code

The zip ships a pre-built `.next`, so nothing needs rebuilding to get started. Once you edit any
source file, rebuild:

```bash
cd ~/woobd.foryoucommunity.com
source /home/foryouc1/nodevenv/woobd.foryoucommunity.com/24/bin/activate
npm run build
```

`npm run build` runs `prisma generate` first, then `next build`. A build needs roughly 1 GB of RAM;
if your plan kills it, build locally and upload just the `.next` folder instead.

Then click **RESTART** on the Setup Node.js App page. Restarting alone is not enough for changes to
appear, and changing a `NEXT_PUBLIC_*` value always requires a rebuild because those are baked in at
build time.

### Viewing logs

```bash
tail -n 100 ~/logs/passenger.log
```

Or set an explicit **Passenger log file** in the app settings, e.g. `/home/foryouc1/logs/woobd.log`.

### Backing up the database

cPanel → **phpMyAdmin** → select `foryouc1_woobd` → **Export** → **Go**. Do this before any upgrade.

### Restarting

**RESTART** on the Setup Node.js App page. Do this after every `.env` or environment-variable change.

---

## Troubleshooting

| Symptom | Cause | Fix |
| --- | --- | --- |
| **502 Bad Gateway** | Node process crashed, or the startup file is wrong | Set **Application startup file** to `app.js`. Then read `~/logs/passenger.log`. |
| **502 after a code change** | `.next` is stale or broken | `cd ~/woobd.foryoucommunity.com && npm run build`, then RESTART |
| **Site is unstyled, no CSS or images** | `.next/static` is missing | The zip should contain it — re-extract, or run `npm run build` |
| **Default cPanel page still shows** | A leftover `index.html`/`index.php` in the subdomain's document root is winning | Delete it from the subdomain's document root, then RESTART |
| **`Environment variable not found: DATABASE_URL`** | `.env` not read and no cPanel variable set | Add `DATABASE_URL` in Setup Node.js App → Environment variables, then RESTART |
| **`schema-not-pushed` from /api/health** | Step 2 was skipped | Import `schema.sql` or run `npx prisma db push` |
| **`Access denied for user 'foryouc1_woobd'@'::1'`** | `localhost` used instead of `127.0.0.1` | Change `DATABASE_URL` host to `127.0.0.1` |
| **`Could not find Prisma Schema that is required for this command`** during `npm install` | `prisma generate` ran with the working directory set to the Node virtualenv's `lib` folder, so it looked for the schema in the wrong place | Handled — `npm install` no longer generates the client. `app.js` does it on first boot. Just RESTART and watch the log |
| **`Cannot find module '.../nodevenv/.../24/lib/scripts/ensure-prisma.js'`** during `npm install` | cPanel resolved the `postinstall` script's *relative* path against the virtualenv `lib` folder, where no `scripts/` exists | Same fix — the hook now steps aside instead of failing the install. Re-upload the zip, or run `npx prisma generate` from the app root |
| **`Query engine library not found`** | Windows `node_modules` was uploaded | Delete `node_modules` on the server and re-run `npm install` |
| **Login fails silently, page just reloads** | Session cookie is `Secure`, so it needs HTTPS | Enable the free Let's Encrypt SSL in cPanel → SSL/TLS Status |
| **Uploaded images 404** | `public/uploads` missing or not writable | `mkdir -p ~/woobd.foryoucommunity.com/public/uploads && chmod 775 ~/woobd.foryoucommunity.com/public/uploads` |
| **Build killed / out of memory** | Shared hosts cap RAM | You do not need to build — the zip already contains `.next` |
| **Log warns `'sharp' package is strongly recommended`** | Next's optional image optimizer is not installed | **Harmless — ignore it.** The storefront renders images with plain `<img>` tags, so `/_next/image` is never requested and `sharp` is never loaded. If you later adopt `next/image`, run `npm i sharp` and RESTART |
| **Changes not appearing after edit** | Build cache | `rm -rf ~/woobd.foryoucommunity.com/.next && npm run build`, then RESTART |

---

## Go-live checklist

- [ ] `/api/health` returns `ok: true`
- [ ] Homepage loads over **HTTPS** with images and styling
- [ ] Demo admin password changed, or demo accounts deleted
- [ ] Admin → Settings → General: site name, email, phone, address
- [ ] Admin → Settings → Store: currency, order prefix
- [ ] Admin → Settings → SEO: meta title, description
- [ ] Shipping zones and rates set (Dhaka vs. outside Dhaka)
- [ ] Payment gateways: leave in **sandbox** until you have live credentials
- [ ] Place a test order end to end, then confirm it appears in Admin → Orders
- [ ] Upload an image in Admin → Media and confirm it displays
- [ ] `/sitemap.xml` and `/robots.txt` respond
- [ ] **`https://woobd.foryoucommunity.com/.env` returns 404** (not the file contents)
- [ ] **`https://woobd.foryoucommunity.com/prisma/schema.prisma` returns 404**
- [ ] `https://woobd.foryoucommunity.com` submitted to Google Search Console

> Those two 404 checks matter because the application root may also be the subdomain's document
> root. Passenger normally intercepts every request before Apache can serve a file, and Apache blocks
> dotfiles by default — so this should already be safe. Confirm it rather than assume it.

---

## Security notes

- The database password is written in `.env` inside the zip and in this guide. Once the site is
  live, change it in cPanel → **MySQL Databases** → **Current Users** → **Change Password**, then
  update `DATABASE_URL` in **both** cPanel's Environment variables and
  `~/woobd.foryoucommunity.com/.env`, and RESTART.
- **Where `.env` sits depends on your application root.** If you extracted into the subdomain's own
  folder, `.env` is inside the document root rather than above it. That is still safe — Passenger
  intercepts every request before Apache can serve a file, and Apache denies dotfiles by default —
  but verify it rather than trusting it. That is what the `/.env` and `/prisma/schema.prisma` checks
  in the go-live checklist are for. If either returns file contents instead of 404, stop and fix the
  Passenger configuration before going live.
- `AUTH_SECRET` was generated fresh for this deployment. Never reuse the development default that
  appears in the project's public docs — it would let anyone forge an admin session.
- **Next.js is pinned to `14.2.35`, deliberately.** The project originally pinned `14.2.18`, which is
  affected by CVE-2025-66478 (React2Shell — remote code execution, CVSS 10.0) along with
  CVE-2025-55184 (denial of service) and CVE-2025-55183 (server function source-code exposure).
  `14.2.35` is the patched release for the 14.x line. There is no configuration workaround for these
  — upgrading is the only fix, so do not downgrade this pin. `package.json` uses exact versions
  everywhere (no `^`), so the server installs precisely what was tested.
- **Keep dependencies patched.** Subscribe to the Next.js security advisories and re-run
  `npm install && npm run build` on the server after any upgrade, then RESTART.
