feat: move to V2
CI / build-and-test (push) Canceled after 0s

This commit is contained in:
2026-10-29 11:21:52 +01:00
parent 6342b8451e
commit 314717ba3a
244 changed files with 11615 additions and 15292 deletions
+40 -81
View File
@@ -1,97 +1,56 @@
# KoolTap Production Deployment
# Production on Coolify
## Option A: Docker (recommended)
KoolTap is deployed with Coolify's Docker Compose build pack, from `docker-compose.coolify.yml`.
The production setup uses PostgreSQL and configurable secrets.
## Once
### 1. Set environment variables
1. Create a **PostgreSQL** database resource in Coolify and turn on its scheduled backups.
2. Create a **Docker Compose** resource from this repository with `docker-compose.coolify.yml`.
3. Give the services their domains, on one site so the session cookie reaches the API:
- `api` → `https://api.example.com:3001`
- `dashboard` → `https://example.com:3000`
4. Set the environment variables:
Create `.env` in the project root:
| Variable | |
|---|---|
| `DATABASE_URL` | The database resource's internal connection URL |
| `API_URL` | `https://api.example.com` (baked into the dashboard at build time) |
| `DASHBOARD_URL` | `https://example.com` (CORS and links) |
| `RESEND_API_KEY`, `RESEND_FROM_EMAIL` | Email; without a key nothing is sent |
| `TRUST_PROXY` | 1 behind Coolify's proxy, 2 with Cloudflare proxying too |
| `MIN_APP_VERSION` | Optional: make older terminal apps update |
```env
# Database
DB_PASSWORD=<generate-a-strong-password>
`JWT_SECRET` is generated by Coolify (`SERVICE_BASE64_64_JWT`).
5. Deploy. The API applies the database migrations before it starts.
6. Create the first venue and its admin, in the API container's terminal:
# JWT secret — generate with: openssl rand -hex 64
JWT_SECRET=<64-char-hex-string>
```bash
node dist/cli/setup.js "My Venue" admin@myvenue.com '<a strong password>'
```
# URLs — set your actual domain/port
DASHBOARD_URL=https://dashboard.yourdomain.com
API_URL=https://api.yourdomain.com
DASHBOARD_PORT=3000
API_PORT=3001
```
It does nothing when there is a venue already. Superadmins belong to no venue:
`node dist/cli/superadmin.js <email> --create "<name>" <password>` adds one, `superadmin.js <email>` promotes a user,
and `--revoke <venue id>` makes a superadmin an admin of that venue.
### 2. Build and start
## Switching over from 1.x
```bash
docker compose -f docker-compose.prod.yml up --build -d
```
2.0 starts with an empty database: nothing comes over from the 1.x backoffice.
### 3. Create the venue and admin (first time only)
1. Before switching, let every tablet sync and settle (or write down) the open tabs. Export what you want to keep.
2. Deploy 2.0 on a new, empty database and set up the venues, users and products.
3. A 1.x tablet that syncs with it gets `426` and shows "update the app"; its unsent sales stay on the tablet.
4. Update the app on each tablet to 2.0. It keeps its settings (PIN, theme, language, rows) and starts unpaired, with
empty tabs and history: pair it with a code from Settings and it loads the venue's catalog and open tabs.
Migrations run automatically when the API container starts.
## Backups
```bash
docker compose -f docker-compose.prod.yml exec api node prisma/setup.js "My Venue" admin@myvenue.com '<strong password>'
```
Back up the database (Coolify does this) **and** the `images` volume, which holds the product pictures.
`setup.js` does nothing when a venue already exists. `--force` wipes ALL data and starts over.
## Every deploy
### 4. Set up a reverse proxy (nginx/Caddy)
Push; Coolify builds both images and restarts. Migrations run on start. If one fails the API doesn't start and the
superadmin page's System tab lists it; fix it and redeploy.
Example Caddyfile:
```
dashboard.yourdomain.com {
reverse_proxy dashboard:3000
}
## Health
api.yourdomain.com {
reverse_proxy api:3001
}
```
---
## Option B: Manual (Node.js + PostgreSQL)
### 1. Install PostgreSQL
Create database and user:
```sql
CREATE DATABASE kooltap;
CREATE USER kooltap WITH PASSWORD 'your-password';
GRANT ALL PRIVILEGES ON DATABASE kooltap TO kooltap;
```
### 2. Configure environment
```env
DATABASE_URL="postgresql://kooltap:your-password@localhost:5432/kooltap"
JWT_SECRET="<random-64-char-string>"
PORT=3001
CORS_ORIGIN="https://dashboard.yourdomain.com"
```
### 3. Build and run
```bash
cd apps/api
pnpm install
npx prisma generate
npx prisma migrate deploy
pnpm build
node dist/main
```
---
## Security Checklist
- [ ] JWT secrets are 64+ random hex characters
- [ ] DB_PASSWORD is strong and unique
- [ ] HTTPS is terminated at reverse proxy
- [ ] CORS_ORIGIN is set to the exact dashboard URL (no wildcard)
- [ ] API is not exposed directly to the internet (reverse proxy only)
- [ ] Rate limiting is configured
- [ ] Audit logs are monitored
`GET /api/v1/health` answers 503 when the database is unreachable; the compose file uses it as the healthcheck.