# Nanga Kathai backend server Self-hosted [Supabase](https://supabase.com/docs/guides/self-hosting/docker) in Docker, pinned to `self-hosted/v0.8.3`, plus Nanga Kathai's config. One server runs: | Service | What it does for NK | |---|---| | Postgres | Songs, singers, likes, playlists, approvals, consent records | | Auth | Email sign-in with a 6-digit code | | REST API | What the app reads and writes (access rules in the schema) | | Storage | Song files, covers, singer photos, on the server's disk | | Studio | Admin dashboard in the browser (password protected) | | Caddy | HTTPS with automatic Let's Encrypt certificates | ## Ports and reverse proxy (live server) Everything runs in **one** Docker Compose project (`~/APPS/nk-backend/supabase-project`). Only two ports are opened, and only on `127.0.0.1`; HestiaCP's nginx handles HTTPS and forwards to them: | Domain | Hestia reverse proxy to | What it is | |---|---|---| | `app.nkbmusic.com` | `http://127.0.0.1:18000` | API for the app + Supabase Studio | | `admin.nkbmusic.com` | `http://127.0.0.1:18080` | NK Admin website (container `nk-admin`; publish with `sh admin/deploy-admin.sh`, see [admin/README.md](../admin/README.md)) | Internal only (never proxied): Postgres `127.0.0.1:15432`, pooler `127.0.0.1:16543`. Change ports with `API_GW_HTTP_PORT`, `NK_ADMIN_PORT`, `NK_DB_PORT`, `NK_POOLER_PORT` in the project's `.env`. ## Updating the live server The code lives at https://git.metatroncube.in/MetatroncubeSoftwareSolutions/nkbmusic and the server runs from a clone of it in `~/APPS/nanga_kathai`. After pushing changes: ```sh ssh dev@72.62.169.43 sh ~/APPS/nanga_kathai/server/update.sh ``` That pulls the latest code, applies new migrations and config, and restarts what changed. Passwords, keys and songs are kept. ## Quick deploy (one command) On a fresh Ubuntu server, once the DNS A record for `app.nkbmusic.com` points at it: ```sh # copy the repo to the server first, e.g. from your PC: # ssh user@SERVER_IP mkdir -p nanga_kathai # scp -r server supabase user@SERVER_IP:~/nanga_kathai/ cd ~/APPS/nanga_kathai/server NK_DIR=$HOME/APPS/nk-backend sh deploy.sh app.nkbmusic.com you@example.com ``` Then set the domain's reverse proxy (HestiaCP or nginx) to **`http://127.0.0.1:18000`**. HTTPS stays with the existing web server; Supabase is never exposed directly. It installs Supabase, asks for your SMTP details, starts everything, creates the tables and buckets, makes your email an admin, schedules backups and prints the app's `env.json`. Run it again after any update; secrets are kept. No sudo needed (only docker and git). On a fresh server with nothing on ports 80/443, use `sudo NK_PROXY=caddy sh deploy.sh ...` instead: it also installs Docker and a firewall, and Caddy gets the certificate itself. Once the code is on GitHub, add `REPO_URL=` to clone it first. The sections below are the same steps done by hand (in Caddy mode). ## 1. Server - Ubuntu 24.04 (or 22.04) VPS: **4 GB RAM, 2 CPU minimum** (8 GB / 4 CPU recommended). - Disk: 40 GB for the system and database, plus room for songs. A few hundred songs at three qualities is roughly 5–10 GB, so **80 GB** is a comfortable start. - A domain or subdomain for the API, e.g. `app.nkbmusic.com`. Create a DNS **A record** pointing it at the server's IP **before** installing, so Caddy can get a certificate. Open only SSH and web ports: ```sh sudo ufw allow 22,80,443/tcp && sudo ufw allow 443/udp && sudo ufw enable ``` Install Docker if it isn't installed yet, then log out and back in: ```sh curl -fsSL https://get.docker.com | sh sudo usermod -aG docker $USER ``` ## 2. Install Copy this repository to the server (git clone, or copy the `server/` and `supabase/` folders), then: ```sh cd nanga_kathai/server sh install.sh app.nkbmusic.com ``` This fetches the official Supabase Docker files, generates all secrets and keys into `~/nk-backend/supabase-project/.env`, adds the NK config and pulls the images. ## 3. Email (needed for sign-in codes) Edit `~/nk-backend/supabase-project/.env` and fill in a real SMTP account. Any transactional email provider works (Amazon SES, Brevo, Zoho Mail, Google Workspace SMTP relay): ``` SMTP_ADMIN_EMAIL=no-reply@nkbmusic.com SMTP_HOST=... SMTP_PORT=587 SMTP_USER=... SMTP_PASS=... SMTP_SENDER_NAME=Nanga Kathai ``` ## 4. Start and set up the database ```sh cd ~/nk-backend/supabase-project sh run.sh start # waits until every service is healthy docker compose ps # all "Up (healthy)" sh ~/nanga_kathai/server/apply-migrations.sh ``` `apply-migrations.sh` creates the NK tables, access rules and storage buckets. It remembers what it has applied, so run it again whenever new files appear in `supabase/migrations/`. ## 5. Make yourself admin 1. Sign in once from the app with your email. 2. Open the dashboard at `https://app.nkbmusic.com`. The user is `nkadmin`; the password is `DASHBOARD_PASSWORD` in `.env`. 3. In the SQL editor run: ```sql update profiles set role = 'admin' where id = (select id from auth.users where email = 'you@example.com'); ``` ## 6. Point the app at the server `env.json` in the app folder (git-ignored): ```json { "SUPABASE_URL": "https://app.nkbmusic.com", "SUPABASE_PUBLISHABLE_KEY": "", "MEDIA_BASE_URL": "https://app.nkbmusic.com/storage/v1/object/public/audio" } ``` ```sh flutter build apk --release --dart-define-from-file=env.json ``` Only the **publishable** key goes in the app. Never put `SUPABASE_SECRET_KEY`, `SERVICE_ROLE_KEY` or the Postgres password in the app. ## 7. Backups ```sh crontab -e 30 2 * * * sh $HOME/nanga_kathai/server/backup.sh >> $HOME/nk-backups/backup.log 2>&1 ``` This keeps 14 days of database dumps and song files in `~/nk-backups`. Copy that folder off the server regularly. A backup that lives only on the same server is lost with the server. ## Everyday commands ```sh cd ~/nk-backend/supabase-project sh run.sh logs auth # logs for one service sh run.sh stop / start sh update.sh # upgrade Supabase (read its notes first, back up before) ``` ## Notes - Free legacy songs sit in the public `audio` bucket, so anyone with a song's URL can download it. When premium songs arrive they go in a private bucket with short-lived signed URLs. - If streaming traffic grows, the song files can move to Cloudflare R2 (no bandwidth fees). The app only needs a new `MEDIA_BASE_URL`. - Postgres ports 5432/6543 are bound to `127.0.0.1`. To connect from your PC, use an SSH tunnel: `ssh -L 5432:localhost:5432 user@server`.