nkbmusic/server/README.md
metatroncubeswdev 178d2d00ab Nanga Kathai: Flutter app, self-hosted backend and song tools
- Flutter app (Android/iOS): home, explore, albums, search, player with
  equalizer, mini player, sign up/sign in with email codes, profile,
  encrypted offline downloads, About page
- server/: one-command deploy of self-hosted Supabase behind HestiaCP/nginx
  (or Caddy), migrations, backups, email templates
- supabase/migrations: schema, row-level security, profiles
- tools/: song scanner and importer

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 10:39:26 -04:00

5.3 KiB
Raw Blame History

Nanga Kathai backend server

Self-hosted Supabase 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

Quick deploy (one command)

On a fresh Ubuntu server, once the DNS A record for app.nkbmusic.com points at it:

# 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=<git 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:

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:

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:

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

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:
    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):

{
  "SUPABASE_URL": "https://app.nkbmusic.com",
  "SUPABASE_PUBLISHABLE_KEY": "<SUPABASE_PUBLISHABLE_KEY from .env>",
  "MEDIA_BASE_URL": "https://app.nkbmusic.com/storage/v1/object/public/audio"
}
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

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

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.