VPS पर Docker से Supabase self-host कैसे करें
अपने VPS पर official Supabase Docker stack चलाना सीखें: demo secrets क्यों बदलें, 14 services क्या करती हैं, कितनी RAM चाहिए और सुरक्षित backups व updates कैसे करें।
आप क्या बना रहे हैं
Supabase को स्वयं होस्ट करने का अर्थ है अपने सर्वर पर आधिकारिक Docker Compose stack चलाना। इसमें Postgres, उसके सामने REST API, auth service, file storage, realtime websockets और Studio dashboard शामिल होते हैं। आप एक repository को clone करते हैं, एक .env file को संपादित करते हैं और लगभग fourteen containers शुरू करते हैं। ये सभी मिलकर आपके नियंत्रण वाले Supabase project की तरह काम करते हैं।
इंस्टॉल करना आसान है। समस्या आमतौर पर .env file से शुरू होती है। इसमें repository में प्रकाशित demo secrets होते हैं। इन defaults के साथ शुरू किया गया stack उसे खोजने वाले किसी भी व्यक्ति के लिए खुला होता है। इस गाइड में उन secrets की जानकारी दी गई है जिन्हें आपको बदलना आवश्यक है, प्रत्येक service का उपयोग बताया गया है, stack को वास्तव में कितनी memory चाहिए यह समझाया गया है, और database को हटाए बिना इसे update करने का तरीका बताया गया है।
यदि Compose आपके लिए नया है, तो पहले VPS पर Docker Compose की मूल बातें पढ़ें। नीचे दिए गए सभी चरणों में यह माना गया है कि docker compose version पहले से version प्रदर्शित करता है।
स्टैक में वास्तव में क्या शामिल है
Supabase एक ही प्रोग्राम नहीं है। Compose फ़ाइल एक नेटवर्क पर अलग-अलग सेवाओं का सेट शुरू करती है। हर सेवा की भूमिका समझने से container नामों की लंबी सूची को debug करना आसान हो जाता है।
dbलोड किए गए Supabase extensions वाला PostgreSQL है। बाकी सभी सेवाएँ इससे जुड़ती हैं। यदि यह container अस्वस्थ है, तो बाकी सब भी विफल हो जाता है।kongAPI gateway है। यह port 8000 पर सुनता है और/rest/v1/,/auth/v1/और/storage/v1/को सही backend तक route करता है। आपको केवल इसी container को बाहरी रूप से expose करना चाहिए।restPostgREST है। यह आपके Postgres schema को पढ़कर उसे REST API के रूप में उपलब्ध कराता है। इसलिए नई table बिना code लिखे नया endpoint बन जाती है।authGoTrue है। यह उन JSON web tokens (JWT) को जारी करता है जो आपके users की पहचान करते हैं।storageऔरimgproxyfile uploads और image resizing संभालते हैं।realtimedatabase changes को websockets के माध्यम से stream करता है।studioऔरmetadashboard और उसके पीछे का admin API हैं।analytics(Logflare) औरvectorlogs एकत्र करते हैं, औरsupavisorPostgres connection pooler है।
इसी वजह से नीचे दिए गए resource numbers ऐसे हैं। आप केवल database नहीं चला रहे हैं। आप database के साथ एक दर्जन support services चला रहे हैं।
आकार निर्धारण: 8 GB RAM की योजना बनाएं
नई इंस्टॉल के बाद, जुलाई 2026 तक, आपके अपने डेटा या नेटवर्क ट्रैफ़िक से पहले यह stack लगभग 2.5 से 3 GB resident memory का उपयोग करता है। Analytics service और Studio Node.js process, memory के दो सबसे बड़े अलग-अलग उपभोक्ता हैं। 2 GB server containers शुरू कर देगा, लेकिन इसके बाद kernel out of memory killer किसी एक container को बंद कर देगा, आमतौर पर analytics या db। इसका संकेत यह है कि कोई container exit code 137 के साथ बार-बार restart होता रहता है।
जिस भी कार्य पर आप निर्भर करते हैं, उसके लिए 8 GB RAM और 4 vCPU दें। यदि आप स्वीकार करते हैं कि एक heavy query और Studio session एक ही समय पर धीमे चलेंगे, तो अकेले development instance के लिए 4 GB पर्याप्त है। Disk भी महत्वपूर्ण है, क्योंकि Postgres, storage volume और log data सभी project directory के अंतर्गत रहते हैं। 40 GB से शुरू करें और इसकी निगरानी करें।
Install: आधिकारिक repository को clone करें
समर्थित प्रक्रिया में मुख्य repository से docker directory को आपकी अपनी project directory में copy किया जाता है। यह अलगाव महत्वपूर्ण है, क्योंकि बाद में चलाया गया git pull आपके .env को overwrite नहीं कर सकता।
git clone --depth 1 https://github.com/supabase/supabase
mkdir supabase-project
cp -rf supabase/docker/* supabase-project
cp supabase/docker/.env.example supabase-project/.env
cd supabase-project
docker compose pulldocker compose pull कई gigabytes की images download करता है। इसके अंत में हर service Pulled के रूप में marked होनी चाहिए। यहां manifest unknown error का अर्थ है कि pinned image tag को upstream से हटा दिया गया है। इसका समाधान tags को manually edit करना नहीं, बल्कि repository की नई copy pull करना है।
पहली बार शुरू करने से पहले जिन secrets को बदलना आवश्यक है
Stack शुरू करने से पहले यह करें, बाद में नहीं। इनमें से कई values पहली boot पर data में लिखी जाती हैं। इसलिए बाद में इन्हें बदलने के लिए database reset करना पड़ता है।
Repository में एक generator मौजूद है, जो सभी values सही तरीके से बनाता है। इसमें वे दो API keys भी शामिल हैं, जिन्हें आपके नए JWT secret से sign करना आवश्यक है।
sh utils/generate-keys.sh --update-envयह script JWT_SECRET, ANON_KEY, SERVICE_ROLE_KEY, SECRET_KEY_BASE, REALTIME_DB_ENC_KEY, VAULT_ENC_KEY, PG_META_CRYPTO_KEY और Logflare tokens के लिए नई values .env में लिखती है। इसे openssl की आवश्यकता होती है, जो किसी भी सामान्य Ubuntu image में मौजूद होता है।
यह दो values set नहीं करतीं। इन्हें आपको .env में manually edit करना होगा:
POSTGRES_PASSWORD। केवल letters और digits का उपयोग करें। यहां punctuation का उपयोग करने पर कई services द्वारा strings को जोड़कर बनाए गए connection strings टूट जाते हैं। Failure parsing error के बजाय authentication error जैसा दिखाई देता है। इससे troubleshooting गलत स्थान पर शुरू होती है।DASHBOARD_USERNAMEऔरDASHBOARD_PASSWORD। ये Studio के लिए basic authentication credentials हैं। Shipped default password वास्तव मेंthis_password_is_insecure_and_should_be_updatedहै।
समझें कि ANON_KEY और SERVICE_ROLE_KEY मनमाने ढंग से क्यों नहीं बनाए जा सकते। दोनों JWTs हैं, जिन्हें JWT_SECRET से sign किया गया है। Gateway हर request पर उस signature को verify करता है। इसलिए आपके secret से मेल न खाने वाली key को {"message":"Invalid authentication credentials"} के साथ reject कर दिया जाता है। यह self-hosting failure का सबसे सामान्य कारण है: operator ने JWT_SECRET बदल दिया, लेकिन demo keys रखीं। हमेशा तीनों values एक साथ generate करें।
SERVICE_ROLE_KEY को root password की तरह सुरक्षित रखें। यह row level security को पूरी तरह bypass करता है। इसे केवल server side code में रखें और कहीं भी नहीं।
SITE_URL और API_EXTERNAL_URL को उस address पर set करें, जहां आपके users वास्तव में पहुंचेंगे, उदाहरण के लिए https://supabase.example.com। Auth इन्हीं values से email confirmation और OAuth callback links बनाता है। इसलिए इन्हें http://localhost:8000 पर छोड़ने से आपके हर user को उसके अपने machine पर भेज दिया जाएगा।
अब अपनी values जांचें:
sh run.sh secretsइसे शुरू करें और इसके स्वस्थ होने की पुष्टि करें
sh run.sh start
docker compose psrun.sh start, docker compose up -d --wait को wrap करता है, इसलिए health checks पास होने तक यह वापस नहीं आता। हर service को running (healthy) या running दिखाना चाहिए। पहली बार boot होने में 2 से 4 मिनट लगते हैं, क्योंकि Postgres किसी भी अन्य connection के पहले अपनी initialisation scripts चलाता है।
यदि कोई container restart हो रहा है, तो उसके logs को service name से पढ़ें:
docker compose logs db
docker compose logs authStudio अब port 8000 पर उपलब्ध है और यह आपके द्वारा सेट किया गया dashboard username और password मांगेगा।
सार्वजनिक इंटरनेट पर port 8000 उपलब्ध न कराएं
Kong का port 8000 plain HTTP पर संचार करता है। प्रत्येक API key और प्रत्येक user password नेटवर्क पर clear text में भेजा जाता है। Studio credentials basic authentication का उपयोग करते हैं, जो encryption के बजाय base64 encoding है।
इसके सामने reverse proxy रखें और वहीं TLS (transport layer security) समाप्त करें। Kong को loopback address से bind करें, ताकि कोई अन्य सेवा उस तक पहुंच न सके। docker-compose.yml में kong port mapping अब 127.0.0.1:8000:8000 हो जाती है और proxy उसी पर forward करता है। प्रमाणपत्र से संबंधित जानकारी कई Compose apps के सामने Traefik में दी गई है।
बाकी ports को firewall पर भी बंद करें। Docker अपने iptables rules लिखकर ports प्रकाशित करता है, जिन्हें साधारण ufw configuration नहीं देखती। यह समस्या Docker containers आपके ufw rules को क्यों अनदेखा करते हैं में समझाई गई है।
डायरेक्टरी का नहीं, डेटाबेस का बैकअप लें
Postgres का डेटा ./volumes/db/data पर bind mount में रहता है। कंटेनर के चलने के दौरान उस डायरेक्टरी को कॉपी करने पर कॉपी असंगत हो जाती है, क्योंकि Postgres लिखे जाने वाले डेटा को buffer करता है और डिस्क पर मौजूद फ़ाइलें केवल checkpoint के समय सुसंगत होती हैं। इसे restore करना आम तौर पर सफल होगा, लेकिन कभी-कभी अंतिम transactions चुपचाप खो जाएँगे। बैकअप के लिए यह सबसे खराब failure mode है।
इसके बजाय dump बनाएँ। pg_dumpall कंटेनर के अंदर चलता है और एक सुसंगत snapshot बनाता है:
docker exec -t supabase-db pg_dumpall -U postgres > supabase-$(date +%F).sqlइस पर भरोसा करने से पहले जाँच लें कि फ़ाइल खाली नहीं है। इसके बाद इन dumps को निर्धारित समय-सारणी के अनुसार server से बाहर भेजें। encrypted offsite backups with restic इसी काम के लिए है। उसी समय अपने .env का भी बैकअप लें। JWT_SECRET खोने पर जारी किए गए सभी tokens invalid हो जाएँगे और संग्रहीत encrypted secrets पढ़े नहीं जा सकेंगे।
Uploaded files ./volumes/storage में रहती हैं। ये सामान्य files होती हैं, इसलिए इनकी plain copy पर्याप्त है।
डेटा खोए बिना अपडेट करें
Supabase image versions को docker-compose.yml में pin करता है, इसलिए जब तक आप स्वयं अपडेट नहीं करते, कुछ भी नहीं बदलता। हर बार पहले dump लें।
docker compose pull
sh run.sh recreaterecreate stack को रोकता है और नई images के साथ फिर शुरू करता है। आपका डेटा सुरक्षित रहता है, क्योंकि वह containers के अंदर नहीं, बल्कि host पर मौजूद bind mounts में रहता है। बड़े version jump से पहले repository में CHANGELOG.md पढ़ें, क्योंकि Postgres के major upgrades स्वचालित नहीं होते और इनके लिए dump तथा restore आवश्यक हैं।
Compose file में हुए बदलाव लागू करने के लिए upstream repository को फिर से clone करें और उसकी docker directory को अपने project में copy करें। ऐसा करते समय .env को overwrite न करें।
पूर्ण reset, जो database सहित सब कुछ नष्ट कर देता है, एक अलग script है और यह confirmation मांगती है:
sh reset.shFAQ
मेरी API calls "Invalid authentication credentials" क्यों लौटाती हैं?
आपके ANON_KEY या SERVICE_ROLE_KEY पर वर्तमान में .env में मौजूद JWT_SECRET से हस्ताक्षर नहीं किए गए थे। Gateway हर request पर signature सत्यापित करता है और मेल न होने पर उसे अस्वीकार कर देता है। sh utils/generate-keys.sh --update-env के साथ तीनों को एक साथ फिर से बनाएं, फिर sh run.sh recreate चलाएं ताकि services नई values पढ़ सकें।
क्या मैं 2 GB VPS पर self-hosted Supabase चला सकता हूं?
विश्वसनीय रूप से नहीं। July 2026 तक stack idle अवस्था में लगभग 3 GB memory लेता है, क्योंकि यह लगभग fourteen services चलाता है। इसलिए 2 GB server पर out of memory killer containers को बंद कर देता है और आपको docker compose ps में exit code 137 दिखाई देता है। Production के लिए 8 GB का उपयोग करें। Solo development के लिए 4 GB को न्यूनतम मानें।
क्या self-hosted Supabase में edge functions शामिल हैं?
हां। Compose file में Deno आधारित functions runtime शामिल है। यह ./volumes/functions के अंतर्गत रखी गई किसी भी चीज़ को serve करता है। इसमें hosted platform का global deployment network शामिल नहीं है। इसलिए आपकी functions एक ही location में आपके एक server पर चलती हैं।
मैं Postgres database से सीधे कैसे connect करूं?
Server पर ही interactive shell के लिए docker exec -it supabase-db psql -U postgres का उपयोग करें। External client के लिए port 5432 पर Supavisor के माध्यम से postgres.<POOLER_TENANT_ID> user और अपने POSTGRES_PASSWORD के साथ connect करें। इस port को internet के लिए open न करें। इसे VPN या SSH tunnel के माध्यम से access करें।
मेरे auth confirmation emails में localhost का link क्यों था?
.env में SITE_URL और API_EXTERNAL_URL अपनी default values पर ही रह गए थे। Auth service हर confirmation और password reset link को इन्हीं दो values से बनाती है। इसलिए वह वही address भेजती है जो उसे दिया गया था। दोनों को अपने वास्तविक public URL पर set करें और stack को फिर से बनाएं।