BYOD · Self-hosted

Deploy di platform pilihan Anda.

Booking Studio tidak membawa database bersama. Setiap instalasi dihubungkan dari wizard ke project Supabase milik pengguna, termasuk database PostgreSQL dan object storage.

Cara kerja BYOD

Deployment baru dapat menyala tanpa database bootstrap. Buka /setup, masukkan kunci akses penyiapan yang sama dengan nilai server SETUP_TOKEN, lalu isi URL database Supabase, direct URL, Project URL, dan service role key. Kunci akses boleh berbeda di setiap instalasi, tetapi harus disiapkan pada server sebelum digunakan. Server memvalidasi TLS dan kecocokan project, menjalankan migrasi dengan lock, membuat bucket booking_public dan booking_private, lalu menyimpan credential secara terenkripsi.

Di VPS atau Docker, konfigurasi terenkripsi berada di volume .booking-studio. Di Vercel, wizard menulis environment terenkripsi ke project dan memicu deployment baru. Credential tidak disimpan di browser atau tabel aplikasi.

Persiapan

  1. Buat project Supabase milik Anda dan simpan password database.
  2. Salin Session pooler/direct URL dan Transaction pooler URL dari menu Connect. Tambahkan sslmode=require.
  3. Salin Project URL dan service role key dari pengaturan API. Jangan pernah memakai service role key di browser.
  4. Generate semua secret aplikasi secara terpisah, misalnya openssl rand -base64 48.

Node.js 22 atau 24 direkomendasikan. Untuk notifikasi WhatsApp, siapkan token API perangkat Fonnte (menu Device → Token) pada secret server environment.

Deploy

Vercel

  1. Import repository ke Vercel.
  2. Tambahkan environment pada target Production: secret aplikasi pada tabel di bawah, VERCEL_TOKEN, VERCEL_PROJECT_ID, dan bila perlu VERCEL_TEAM_ID. Token harus memiliki akses minimum untuk environment dan deployment project tersebut.
  3. Deploy, buka /setup, autentikasi memakai setup token, lalu hubungkan Supabase. Wizard menyimpan credential dan membuat deployment production baru dari sumber Git yang sedang aktif, lalu menunggu activation ID yang sama.

Jangan berikan database produksi kepada Preview Deployment. Migrasi Vercel dijalankan oleh npm run build:vercel.

VPS / bare metal

git clone <repository> booking-studio
cd booking-studio
npm ci
cp .env.example .env
npm run build
npm start

Pasang reverse proxy HTTPS (Caddy, Nginx, atau Traefik), jalankan proses dengan systemd/PM2, dan sediakan persistent volume untuk .booking-studio, public/uploads, dan storage. Aplikasi akan menunda migrasi sampai database dipilih di wizard.

Docker Compose

npm run setup:docker
docker compose --env-file .env.docker up -d --build

Compose tidak membuat PostgreSQL tersembunyi. Database dan storage tetap milik pengguna di Supabase. Backup file .env.docker serta volume booking_config; keduanya diperlukan untuk membuka konfigurasi BYOD.

Railway, Render, Fly.io, dan PaaS Node lain

Gunakan build npm ci && npm run build, start npm start, port 3000, serta persistent disk untuk /app/.booking-studio. Jika platform tidak menyediakan disk persisten atau memakai beberapa replica, pasang enam credential BYOD langsung sebagai environment bersama BYOD_ACTIVATION_ID yang stabil, lalu jalankan npm run db:migrate:active saat release.

Environment inti

KeyFungsi
AUTH_SECRETRahasia sesi acak, minimal 32 karakter.
SETUP_TOKENToken untuk membuka wizard pertama di production, minimal 32 karakter.
CREDENTIALS_ENCRYPTION_KEYKunci enkripsi credential dan konfigurasi BYOD, minimal 32 karakter.
CREDENTIALS_ENCRYPTION_KEY_PREVIOUSKosongkan pada instalasi baru; isi kunci lama hanya selama rotasi.
CRON_SECRETRahasia endpoint scheduler, minimal 32 karakter.
UPDATE_DEPLOY_PROVIDEROpsional. Pilih otomatis, Vercel, Netlify, Cloudflare Pages, webhook khusus, atau workflow VPS.
UPDATE_DEPLOY_HOOK_URLURL Deploy/Build Hook platform atau webhook HTTPS khusus; server-only.
UPDATE_DEPLOY_HOOK_TOKENToken rahasia untuk webhook khusus; server-only.
UPDATE_VPS_REPOSITORYRepository GitHub yang menjalankan workflow deployment VPS.
UPDATE_VPS_WORKFLOWNama workflow GitHub untuk deployment VPS.
UPDATE_VPS_BRANCHBranch rilis yang akan diperbarui pada VPS.
UPDATE_VPS_GITHUB_TOKENToken GitHub terbatas untuk memulai workflow deployment VPS; server-only.
APP_URLURL HTTPS publik aplikasi.
BYOD_ALLOW_LOCAL_CONNECTIONSGunakan false; true hanya untuk Supabase lokal yang dipercaya.
FONNTE_TOKENOpsional. Token API perangkat Fonnte dari menu Device → Token; server-only.

Credential BYOD yang dipasang manual: DATABASE_URL, DIRECT_URL, SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY, STORAGE_PUBLIC_BUCKET=booking_public, STORAGE_PRIVATE_BUCKET=booking_private, dan BYOD_ACTIVATION_ID. Gunakan DATABASE_POOL_SIZE=1 untuk serverless dan sesuaikan kapasitas pada server persisten. Nilai eksplisit yang sudah disetel di environment, termasuk Vercel, mengesampingkan default; periksa agar serverless tidak tetap memakai nilai besar seperti 5.

Menggunakan database yang sudah ada

Tidak perlu membuat project fresh. Pasang credential database lama sebagai environment lengkap beserta activation ID stabil, jalankan npm run db:migrate:active, lalu deploy. Jika tabel bisnis sudah berisi data, wizard otomatis ditutup dan pengguna diarahkan ke login. Selalu buat backup sebelum migrasi dan jangan mengubah migration yang pernah diterapkan.

WhatsApp Fonnte

Atur FONNTE_TOKEN sebagai environment rahasia server menggunakan token API perangkat yang disalin dari menu Device → Token Fonnte. Jangan gunakan token akun: endpoint pengelolaan seperti /add-device dan /get-devices memerlukan token akun, sedangkan aplikasi memakai token perangkat untuk QR (/qr), status (/device), dan pengiriman pesan (/send). FONNTE_ACCOUNT_TOKEN tidak diperlukan oleh alur koneksi aplikasi ini. Credential bisnis yang dimasukkan di dashboard menggantikan token server; gunakan tombol **Gunakan token server** untuk menghapus override yang salah. QR hanya diminta setelah admin menekan tombol; saat menunggu scan, status diperiksa melalui endpoint profil perangkat setiap 30 detik agar permintaan QR tidak berulang dan memicu rate limit. Fonnte menyebut API profil perangkat memiliki batas dan menyarankan webhook status untuk kebutuhan real-time. Hubungkan WhatsApp pada Dashboard → Pengaturan untuk menampilkan QR. Token server tidak pernah dikirim ke browser. Untuk multi-tenant dengan nomor pengirim berbeda, setiap bisnis memerlukan token perangkat sendiri. Rujukan: Get QR, Device Profile, Account Token, Device Status Webhook.

Operasional production

  • Jadwalkan GET /api/cron/reminders dan GET /api/cron/notifications dengan header Authorization: Bearer <CRON_SECRET>. Simpan secret di konfigurasi scheduler, bukan di URL atau log. Cron bawaan vercel.json berjalan harian agar kompatibel dengan Vercel Hobby. Hobby hanya mendukung cron sekali sehari; gunakan scheduler eksternal setiap 15 menit. Pro/Enterprise mendukung cron lebih sering sesuai batas plan. Lihat batas cron Vercel.
  • Pantau /api/health. Respons setup_required sehat untuk instalasi baru; 503 berarti konfigurasi rusak atau database aktif tidak terjangkau.
  • Rotasi kunci memakai CREDENTIALS_ENCRYPTION_KEY_PREVIOUS, restart semua proses, verifikasi ciphertext baru, lalu hapus kunci lama.
  • Jalankan npm run check dan npm run validate:production sebelum rilis.

Pembaruan aplikasi satu klik

Dashboard memeriksa manifest version.json pada branch main repositori upstream dengan cache 12 jam. Untuk Vercel, Netlify, atau Cloudflare Pages, buat Deploy/Build Hook yang mengarah ke branch production, simpan URL-nya di UPDATE_DEPLOY_HOOK_URL, lalu redeploy aplikasi. Untuk VPS Docker, gunakan workflow .github/workflows/ota-vps-deploy.yml, simpan secrets VPS di GitHub Environment production, lalu isi pengaturan UPDATE_VPS_* dan pilih UPDATE_DEPLOY_PROVIDER=vps. Workflow memperbarui repository VPS melalui SSH dan Docker Compose; persetujuan deployment dapat diwajibkan melalui GitHub Environment. Pemilik/admin memulai pembaruan dari Dashboard → Pengaturan → Pembaruan aplikasi. Pastikan branch deployment berisi rilis upstream dan proses build/start menjalankan migrasi database. Jika menggunakan fork, sinkronkan kodenya dari upstream terlebih dahulu; tombol update tidak menyalin kode dari repository lain. Untuk platform lain, sambungkan webhook HTTPS khusus dengan token rahasia. Aplikasi tidak menjalankan perintah shell dari request.

Saat menyiapkan rilis, naikkan versi pada package.json dan version.json, isi changelog, dan setel minDatabaseVersion ke nama migrasi Prisma minimum yang dibutuhkan.

Pemecahan masalah

Wizard menampilkan koneksi belum siap

Periksa status Supabase, password yang sudah URL-encode, sslmode=require, allowlist jaringan, dan bahwa direct URL dapat dijangkau dari host migrasi.

Konfigurasi terenkripsi tidak terbaca

Kembalikan CREDENTIALS_ENCRYPTION_KEY yang digunakan saat file dibuat, atau pasang kunci lama sementara sebagai CREDENTIALS_ENCRYPTION_KEY_PREVIOUS. Jangan menghapus volume konfigurasi.

WhatsApp belum terhubung

Pastikan FONNTE_TOKEN adalah token API perangkat dari menu Device → Token, bukan token akun. Token akun (bila disetel sebagai FONNTE_ACCOUNT_TOKEN) hanya untuk API pengelolaan akun dan tidak dapat menggantikan token perangkat. Jika muncul rate limit, tunggu sebelum mencoba lagi; jangan berulang kali meminta QR. Pastikan perangkat dan paket aktif, lalu buat QR sekali lagi. Jika token perangkat dicabut atau kedaluwarsa, salin token baru dan perbarui secret di environment lokal maupun production.

Localhost ditolak saat production

Ini perlindungan SSRF. Gunakan host Supabase publik. Set BYOD_ALLOW_LOCAL_CONNECTIONS=true hanya bila Supabase lokal berada pada jaringan privat yang Anda kelola.