# Deploy dashboards (Debian VPS) Stack: static Vite builds → Nginx → Let's Encrypt (HTTP-01). Host: `45.149.76.52` · App path: `/opt/meshkee/dashboards` · Web root: `/var/www/meshkee/{super-admin,business,customer}` | Host | App | |------|-----| | `manage.meshkee.com` | Super Admin | | `business.` | Business dashboard | | `customer.` | Customer dashboard | API: `https://api.meshkee.com/api/v1` (separate server). ## New tenant SSL (automatic) 1. Add business + domain in Super Admin (apex, e.g. `sanihome.ir`) 2. Add Arvan **A** records (DNS-only): `business` + `customer` → dashboards VPS IP 3. Within ~2 hours, `/opt/meshkee/dashboards/scripts/ssl-sync.sh` expands the cert via `GET https://api.meshkee.com/api/v1/internal/ssl/hosts` (`X-SSL-Sync-Token`) Manual: `sudo /opt/meshkee/dashboards/scripts/ssl-sync.sh` ## Redeploy frontends From your laptop (rsync source tree, then build on server): ```bash rsync -az --delete \ --exclude node_modules --exclude .git --exclude '**/dist' --exclude '.env' \ -e 'ssh -i ~/.ssh/id_ed25519' \ ./ root@45.149.76.52:/opt/meshkee/dashboards/ ssh root@45.149.76.52 'cd /opt/meshkee/dashboards && npm ci && npm run build && \ rsync -a --delete apps/super-admin/dist/ /var/www/meshkee/super-admin/ && \ rsync -a --delete apps/business/dist/ /var/www/meshkee/business/ && \ rsync -a --delete apps/customer/dist/ /var/www/meshkee/customer/ && \ find /var/www/meshkee -type f -exec chmod a+r {} + && \ find /var/www/meshkee -type d -exec chmod a+rx {} +' ``` > **Note:** Source files like `favicon.png` must be world-readable (`644`). If they are `700`, Nginx returns **403** and browsers fall back to a default icon (often the Vite lightning bolt). Build env on server (`apps/*/.env`): - All: `VITE_API_BASE_URL=https://api.meshkee.com/api/v1` - Super Admin: `VITE_ADMIN_DOMAIN=manage.meshkee.com` - Business/Customer: leave `VITE_BUSINESS_DOMAIN` unset ## Backend SSL sync (API server) Env on API (`/opt/meshkee/app/.env`): ``` SSL_SYNC_TOKEN= DASHBOARD_ADMIN_HOST=manage.meshkee.com ``` Endpoint: `GET /api/v1/internal/ssl/hosts` → `{ "hosts": ["manage.meshkee.com", "business.…", "customer.…"] }`