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 |
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) |
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:
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:
# 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
- Sign in once from the app with your email.
- Open the dashboard at
https://app.nkbmusic.com. The user isnkadmin; the password isDASHBOARD_PASSWORDin.env. - 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
audiobucket, 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.