# PlayTube on cPanel — complete install guide

Three supported paths. **Method A (Node web wizard)** and **Method C (PHP GUI installer)**
need no command line. **Method B (terminal script)** is one command. All end at the same
place: a locked, production-ready install.

> cPanel shared hosting rarely ships FFmpeg or PostgreSQL extensions choice — PlayTube detects
> what's missing and degrades gracefully (progressive video fallback, clear checklist).

---

## 0. What you need in cPanel

1. **PostgreSQL database** — cPanel → *PostgreSQL Databases* → create database `user_playtube`,
   create user, add user to database (ALL privileges). Note host (usually `localhost`), port
   (`5432`) and credentials. Connection string form:
   `postgresql://USER:PASSWORD@localhost:5432/USER_playtube`
2. **Node.js app** — cPanel → *Setup Node.js App* → *Create Application*:
   - Node.js version: **20 or newer**
   - Application mode: **Production**
   - Application root: e.g. `playtube`
   - Application URL: your domain/subdomain (HTTPS — required for PWA install)
   - Application startup file: **`cpanel-server.js`**
   - (Optional) Environment variables: you can set `DATABASE_URL`, `SITE_URL`, `AUTH_SECRET`
     here instead of `.env` — the wizard reads both.
3. **Upload the code** — either cPanel → *Git™ Version Control* (clone this repo; `.cpanel.yml`
   auto-deploys on push) or upload a ZIP into the application root and extract it.
4. **SSL** — cPanel → *SSL/TLS Status* → AutoSSL so the domain serves HTTPS.

## Method A — web installer (recommended)

1. In *Setup Node.js App* press **Run NPM Install**, then **Run JS Script → build**
   (or leave the build to `.cpanel.yml` if you deployed with Git).
2. Press **Restart**, then open **`https://YOUR_DOMAIN/setup`**.
3. Follow the 6 steps:
   1. **Requirements** — Node, secrets, DB, storage, FFmpeg, lock status.
   2. **Database & site** — paste `DATABASE_URL`, `SITE_URL`, optional `STORAGE_DIR`,
      generate an `AUTH_SECRET` → *Test connection* → *Save to .env* → **Restart the app**
      (cPanel → Restart, or `touch tmp/restart.txt`) → *Re-check*.
   4. **Tables** — *Create tables* (runs `drizzle-kit push --force` on the server).
   5. **Admin** — create the admin account (sign-in + `/admin` access).
   6. **Demo data** (optional) — seed channels/videos/shorts so the homepage isn't empty.
   7. **Finish** — writes `install.lock`. The wizard locks itself afterwards.
4. Sign in with the admin account. Done.

## Method B — one-shot terminal script

cPanel → *Terminal* (or SSH), from the application root:

```bash
bash scripts/cpanel-install.sh \
  --db 'postgresql://USER:PASSWORD@localhost:5432/USER_playtube' \
  --site 'https://tube.example.com' \
  --admin-email 'admin@example.com' --admin-password 'ChangeMe123!' \
  --admin-name 'Site Admin' --admin-handle 'admin'
```

It installs dependencies, writes `.env`, creates tables, builds, creates the admin and the
`install.lock`, then touches `tmp/restart.txt`. Omit flags to be prompted. Re-running is safe.

Individual operations are also available:

```bash
node scripts/setup-cli.mjs status
node scripts/setup-cli.mjs migrate
node scripts/setup-cli.mjs create-admin --email a@b.c --password '...' --name 'Admin' --handle admin
node scripts/setup-cli.mjs lock --site 'https://tube.example.com'
node scripts/setup-cli.mjs unlock
```

## Method C — PHP GUI installer (no Node app required yet)

If the Node.js app isn't running yet (or you prefer PHP), use the single-file GUI installer:

1. Upload **`cpanel/installer.php`** from this repo to your hosting as `installer.php`:
   - next to `package.json` if the app root is web-accessible, **or**
   - into `public_html` (then set “App root” to `/home/USERNAME/playtube` inside the wizard).
2. Open **`https://YOUR_DOMAIN/installer.php`** in a browser and follow the 6 steps:
   requirements → config → dependencies/build → tables → admin → finish.
3. Long steps (`npm ci`, migrate, build) run as **background jobs with live logs**, so slow
   shared hosting won't time out. If your host disables `proc_open`, the installer shows the
   exact Terminal commands instead (Manual mode).
4. Database tools use `pdo_pgsql` when available and automatically fall back to Node for
   connection tests and admin login checks.
5. Finishing writes the same `install.lock` the other methods use. Afterwards, **delete
   `installer.php`** from your hosting.

Re-running later requires an admin email + password (verified against the database with
bcrypt, over PDO or Node).

## After installing

- **Restart Passenger** after any `.env`/code change: *Setup Node.js App → Restart* (or
  `touch tmp/restart.txt` in the app root).
- **Storage**: uploads live in `STORAGE_DIR` (default `./storage`). Keep it outside `public/`;
  back it up. For S3/Cloudinary set `S3_UPLOAD_ENDPOINT` + `S3_PUBLIC_BASE_URL` in `.env`.
- **FFmpeg**: shared cPanel almost never provides it — the app serves uploads progressively
  instead of HLS. For adaptive 144p→2160p streaming use a VPS with `apt install ffmpeg`.
- **Email (optional)**: `RESEND_API_KEY` + `MAIL_FROM` enable verification/reset emails;
  without them the links are shown in the UI so flows still complete.
- **Google login (optional)**: `GOOGLE_CLIENT_ID`/`GOOGLE_CLIENT_SECRET`, redirect URI
  `https://YOUR_DOMAIN/api/auth/google/callback`.
- **Re-running setup**: sign in as admin → `/setup` → *Unlock & re-run setup*.
- **PWA install for your users**: HTTPS + `/install` page + header *Install app* button work
  out of the box once `SITE_URL` is correct.

## cPanel login page stuck ("cPanel is connecting…", port 2083)

This is a cPanel problem, not a PlayTube problem — you haven't reached the Terminal yet.

1. Click the **right** "Enter Here" (firewall path), then the left one; also try
   `https://DOMAIN:2083` and `http://DOMAIN:2082` directly. Wait 1–2 min, reload,
   try incognito or another network (ISP/router firewall can block 2083).
2. **VPS:** SSH in and check the usual freeze causes:
   ```bash
   df -h                 # disk 100% full freezes cPanel — clear /usr/local/cpanel/logs
   free -m && top        # memory / CPU exhaustion
   systemctl status cphs # cPanel login service
   scripts/restartsrv cphs        # or: systemctl restart cphs
   tail -50 /usr/local/cpanel/logs/error.log
   ```
3. **Shared hosting:** contact the provider — they restart cPanel from the server console.

**Install PlayTube while the cPanel UI is down (Method B needs only SSH):**

- Get the code onto the server with `git clone` or **FTP** (port 21/22 works without
  the cPanel UI). Upload `cpanel/installer.php` to `public_html` while you're at it.
- VPS root can create the Postgres database directly:
  ```bash
  sudo -u postgres createuser -d playtube
  sudo -u postgres createdb -O playtube playtube
  sudo -u postgres psql -c "ALTER USER playtube WITH PASSWORD 'YourStrongPass';"
  ```
- Run `bash scripts/cpanel-install.sh --db 'postgresql://playtube:pass@localhost:5432/playtube' --site 'https://DOMAIN' --admin-email ... --admin-password ...`.
- No cPanel Node.js app yet + you have root: install Node 20+ (NodeSource), run the
  script, then keep it running with `pm2 start cpanel-server.js --name playtube`.
  When cPanel recovers, confirm SSL and *Setup Node.js App → Restart*.

## Troubleshooting

| Symptom | Fix |
|---|---|
| cPanel login hangs at "cPanel is connecting…" | See the section above — disk full, `scripts/restartsrv cphs`, or provider support |
| `/setup` shows “could not reach setup API” | App isn't running — *Setup Node.js App → Start*, check startup file is `cpanel-server.js` |
| DB connection refused / timeout | Wrong host or password; on cPanel the host is usually `localhost`, user/db carry the `user_` prefix |
| `drizzle-kit push` fails with permission errors | DB user needs CREATE privileges on the database/schema |
| `.env` won't save | File ownership — `chown USER:USER .env` or set vars in *Setup Node.js App → Environment variables* instead |
| 503 after deploy | Rebuild (`Run JS Script → build`) then Restart; check `stderr.log` in the app root |
| Videos play but no quality menu | No FFmpeg on host — expected on shared cPanel; upgrade to VPS for HLS |
| Installer locked but no admin exists | Terminal: `node scripts/setup-cli.mjs unlock`, then re-run `/setup` |

## Security notes

- `install.lock` blocks re-running setup for non-admins. Never delete it on a live site unless
  you are reinstalling.
- `AUTH_SECRET` must be ≥32 random chars — the wizard generates one for you.
- Keep `DATABASE_URL` out of Git: `.env` is git-ignored; only `.env.example` is committed.
