# Korrith — Website & Assessment Platform Marketing site and security-assessment intake for Korrith. npm-workspaces monorepo, Node 22 (see `.nvmrc`). | App | Stack | Port | Purpose | | --- | --- | --- | --- | | `apps/web` | React 18 + Vite + Tailwind + shadcn/ui | 3000 | Public website (static build served by nginx in production) | | `apps/api` | Express 5 + Nodemailer | 3001 | Assessment intake: validates, stores in PocketBase, emails the submitter + admins | | `apps/pocketbase` | PocketBase 0.40.4 (SQLite) | 8090 | Database, auth, admin UI | ## Project structure ``` apps/ web/ # Frontend (src/pages, src/components, nginx.conf + Dockerfile for prod) api/ # Express API (src/routes, src/utils, Dockerfile) pocketbase/ # pb_migrations (schema, append-only), pb_hooks, Dockerfile docker-compose.yml ``` ## Local development 1. `npm install` 2. `cp apps/api/.env.example apps/api/.env` and fill in real values. 3. Download the PocketBase 0.40.4 binary into `apps/pocketbase/pocketbase` (it is gitignored): https://github.com/pocketbase/pocketbase/releases/tag/v0.40.4 4. `npm run dev` — starts web (3000), api (3001) and pocketbase (8090) together. ## Environment variables | Variable | Used by | Description | | --- | --- | --- | | `PB_SUPERUSER_EMAIL` / `PB_SUPERUSER_PASSWORD` | pocketbase (first boot), api | Initial PocketBase admin account; the API uses it to read/write | | `PB_ENCRYPTION_KEY` | pocketbase | 32+ random chars; encrypts settings at rest | | `SMTP_HOST` / `SMTP_PORT` / `SMTP_USER` / `SMTP_PASSWORD` | api | Transactional email (587 = STARTTLS, 465 = SSL) | | `MAIL_FROM` / `MAIL_REPLY_TO` | api | Optional sender identity overrides | | `ADMIN_EMAILS` | api | Optional comma-separated notification recipients | | `CORS_ORIGIN` | api | Default `*` | ## Deploying to a VPS with Coolify 1. Push this repo to GitHub. `.gitignore` already excludes secrets, `node_modules`, build output, the PocketBase binary and its database. 2. In Coolify: **New Resource → from GitHub repo → Docker Compose** build pack (uses the root `docker-compose.yml`). 3. Set the environment variables above in Coolify's UI. 4. Expose the **`web`** service (container port **80**) with your domain. It serves the site and reverse-proxies same-origin paths the frontend depends on: - `/hcgi/api/*` → `api:3001` (Express) - `/hcgi/platform/*` → `pocketbase:8090` (admin UI at `https://your-domain/hcgi/platform/_/`) 5. The `pocketbase-data` volume persists the database. On first boot, migrations build the schema and seed the admin account from the env vars. ### Notes - `apps/pocketbase/pb_migrations` is append-only history — never edit or delete applied migrations; add new ones instead. - The PocketBase Dockerfile uses Docker's `TARGETARCH`, so arm64 VPSes work too. - Building the frontend image needs ~2 GB RAM on the VPS. - Assessment emails are sent only by the Express API (Nodemailer); PocketBase ships with an empty hooks directory in production.