SSD Nodes Learn Hosting plans →
Rehberler Matt ConnorYazan Matt Connor · Güncellendi 2026-08-27

VPS Üzerinde Kendi Supabase Sunucunuzu Kurma Rehberi

Kendi sunucunuzda Supabase Docker yığınını çalıştırmanın detaylarını öğrenin. Güvenlik için değiştirilmesi gereken anahtarlar, RAM gereksinimleri ve güncelleme yöntemleri.

Ne inşa ediyorsunuz

Supabase'i kendi sunucunuzda barındırmak (self-hosting), resmi Docker Compose yığınını kendi sunucunuzda çalıştırmak anlamına gelir: Postgres, önünde bir REST API, bir kimlik doğrulama servisi, dosya depolama, gerçek zamanlı websocket'ler ve Studio paneli. Tek bir depoyu klonlar, bir adet .env dosyasını düzenler ve birlikte kontrolünüz altındaki bir Supabase projesi gibi davranan yaklaşık on dört container başlatırsınız.

Kurulum kısadır. Hata yapılan kısım .env dosyasıdır. Bu dosya, depoda yayınlanan demo gizli anahtarlarıyla gelir ve bu varsayılan ayarlarla başlatılan bir yığın, onu bulan herkese açık hale gelir. Bu kılavuz, değiştirmeniz gereken gizli anahtarları, her servisin ne işe yaradığını, yığının gerçekte ne kadar belleğe ihtiyaç duyduğunu ve veritabanınızı silmeden onu nasıl güncelleyeceğinizi kapsar.

Eğer Compose sizin için yeniyse, önce VPS üzerinde Docker Compose temelleri konusunu okuyun. Aşağıdaki her şey, docker compose version komutunun halihazırda bir sürüm bilgisi döndürdüğünü varsayar.

Yığının gerçek içeriği

Supabase tek bir program değildir. Compose dosyası, tek bir ağ üzerinde bir dizi ayrı servisi başlatır. Hangi servisin ne işe yaradığını bilmek, karmaşık container isimlerini hata ayıklayabileceğiniz bir yapıya dönüştürür.

  • db, Supabase eklentileri yüklü olan PostgreSQL'dir. Diğer tüm servisler onunla iletişim kurar. Bu container sağlıklı değilse, diğer her şey başarısız olur.
  • kong, API ağ geçididir. 8000 numaralı portu dinler ve /rest/v1/, /auth/v1/ ve /storage/v1/ trafiğini ilgili arka uçlara yönlendirir. Dış dünyaya açmanız gereken tek container budur.
  • rest, PostgREST'tir. Postgres şemanızı okur ve bunu bir REST API olarak sunar; böylece yeni bir tablo, kod yazmaya gerek kalmadan yeni bir uç nokta haline gelir.
  • auth, GoTrue'dur. Kullanıcılarınızı tanımlayan JSON web token'larını (JWT) oluşturur.
  • storage ve imgproxy, dosya yükleme ve görüntü yeniden boyutlandırma işlemlerini yönetir.
  • realtime, veritabanı değişikliklerini WebSocket üzerinden yayınlar.
  • studio ve meta, kontrol paneli ve onun arkasındaki yönetici API'sidir.
  • analytics (Logflare) ve vector günlük kayıtlarını toplar, supavisor ise Postgres bağlantı havuzlayıcısıdır.

Aşağıdaki kaynak gereksinimlerinin bu seviyede olmasının nedeni bu listedir. Yalnızca bir veritabanı çalıştırmıyorsunuz. Bir veritabanı ile birlikte bir düzine destek servisi çalıştırıyorsunuz.

Boyutlandırma: 8 GB RAM için planlama

Temmuz 2026 itibarıyla, kendi verileriniz veya trafiğiniz eklenmeden önce, yığın (stack) temiz bir kurulumda yaklaşık 2,5 ila 3 GB yerleşik bellek (resident memory) tüketir. Analitik servisi ve Studio Node.js süreci, en çok kaynak tüketen iki bileşendir. 2 GB RAM'e sahip bir sunucu container'ları başlatacak, ancak ardından çekirdeğin bellek yetersizliği (out of memory) katili nedeniyle bunlardan birini kaybedecektir; bu genellikle analytics veya db olur ve belirtisi, container'ın 137 çıkış koduyla sürekli yeniden başlatma döngüsüne girmesidir.

Güvendiğiniz her türlü kurulum için 8 GB RAM ve 4 vCPU tahsis edin. Eğer ağır bir sorgu ile Studio oturumunun aynı anda yavaş çalışmasını kabul ediyorsanız, tek kişilik bir geliştirme örneği için 4 GB yeterli olabilir. Postgres, depolama birimi ve günlük verilerinin tamamı proje dizini altında yer aldığından disk kapasitesi de önemlidir. 40 GB ile başlayın ve kullanımı izleyin. Kendi sunucunuzda barındırdığınız (self-host) her şey için bir plan seçmeden önce servisleri saymak alışkanlık haline getirilmelidir; çünkü PhotoPrism ve Immich gibi uygulamaların gerçek RAM taban değerleri, hızlı başlangıç sayfalarında belirtilenlerin oldukça üzerindedir.

Kurulum: resmi depoyu klonlayın

Desteklenen yöntem, docker dizinini ana depodan kendi proje dizininize kopyalar. Bu ayrım önemlidir; çünkü daha sonra yapılacak bir git pull işlemi, .env dosyanızın üzerine yazamaz.

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 pull

docker compose pull komutu birkaç gigabaytlık imaj indirir. İşlem, her servisin Pulled olarak işaretlenmesiyle tamamlanmalıdır. Burada alınan bir manifest unknown hatası, sabitlenmiş imaj etiketinin yukarı akışta (upstream) kaldırıldığı anlamına gelir; bu durumda çözüm, etiketleri elle düzenlemek yerine deponun daha yeni bir kopyasını çekmektir.

İlk başlatmadan önce değiştirmeniz gereken gizli veriler

Bunu yığını başlatmadan önce yapın, sonrasında değil. Bu değerlerin birçoğu ilk açılışta verilere yazılır; bu nedenle bunları daha sonra değiştirmek veritabanını sıfırlamanız anlamına gelir.

Depo, her değeri doğru şekilde üreten ve yeni JWT gizli anahtarınızla imzalanması gereken iki API anahtarını da içeren bir oluşturucu ile gelir.

sh utils/generate-keys.sh --update-env

Bu betik; JWT_SECRET, ANON_KEY, SERVICE_ROLE_KEY, SECRET_KEY_BASE, REALTIME_DB_ENC_KEY, VAULT_ENC_KEY, PG_META_CRYPTO_KEY ve Logflare belirteçleri için yeni değerleri .env dosyasına yazar. Bu betik, herhangi bir standart Ubuntu imajında bulunan openssl aracına ihtiyaç duyar.

Betik tarafından ayarlanmayan ve .env dosyasında elle düzenlemeniz gereken iki değer şunlardır:

  • POSTGRES_PASSWORD. Yalnızca harf ve rakam kullanın. Buradaki noktalama işaretleri, çeşitli servislerin dizeleri birleştirerek oluşturduğu bağlantı dizgilerini bozar. Oluşan hata, ayrıştırma hatası yerine kimlik doğrulama hatası gibi görünür ve bu da kullanıcıları yanlış yerde arama yapmaya yönlendirir.
  • DASHBOARD_USERNAME ve DASHBOARD_PASSWORD. Bunlar, Studio için temel kimlik doğrulama bilgileridir. Varsayılan parola değeri this_password_is_insecure_and_should_be_updated olarak gelmektedir.

ANON_KEY ve SERVICE_ROLE_KEY değerlerinin neden rastgele belirlenemeyeceğini anlayın. Her ikisi de JWT_SECRET ile imzalanmış JWT'lerdir. Ağ geçidi, her istekte bu imzayı doğrular; dolayısıyla gizli anahtarınızla eşleşmeyen bir anahtar, {"message":"Invalid authentication credentials"} hatasıyla reddedilir. Bu, self-hosting sürecinde en sık karşılaşılan hatadır: operatör JWT_SECRET değerini değiştirmiş ancak demo anahtarlarını korumuştur. Üçünü her zaman birlikte oluşturun.

SERVICE_ROLE_KEY değerine bir root parolası gibi davranın. Bu değer, satır düzeyi güvenliği (row level security) tamamen devre dışı bırakır. Yalnızca sunucu tarafındaki kodlarda bulunmalıdır, başka hiçbir yerde değil.

SITE_URL ve API_EXTERNAL_URL değerlerini, kullanıcılarınızın gerçekten erişeceği adres olarak ayarlayın; örneğin https://supabase.example.com. Kimlik doğrulama servisi, e-posta onay ve OAuth geri çağırma bağlantılarını bu değerlere göre oluşturur. Bu değerleri http://localhost:8000 olarak bırakırsanız, tüm kullanıcılarınız kendi yerel makinelerine yönlendirilir.

Ardından sahip olduğunuz yapılandırmayı kontrol edin:

sh run.sh secrets

Servisi başlatın ve sağlıklı çalıştığını doğrulayın

sh run.sh start
docker compose ps

run.sh start, docker compose up -d --wait komutunu sarmalar; bu nedenle sağlık kontrolleri geçene kadar işlem sonlanmaz. Her servis running (healthy) veya running durumunu göstermelidir. Postgres, diğer servisler bağlanmadan önce başlatma betiklerini çalıştırdığı için ilk açılış iki ila dört dakika sürer.

Eğer bir container sürekli yeniden başlatılıyorsa, servis adına göre log kayıtlarını inceleyin:

docker compose logs db
docker compose logs auth

Studio bu aşamadan sonra 8000 numaralı port üzerinde erişilebilir durumdadır ve belirlediğiniz dashboard kullanıcı adı ile parolasını isteyecektir.

8000 numaralı portu genel internete açmayın

Kong, 8000 numaralı port üzerinde şifrelenmemiş HTTP kullanır. Tüm API anahtarları ve kullanıcı parolaları ağ üzerinden düz metin olarak iletilir. Studio kimlik bilgileri ise şifreleme değil, base64 kodlaması kullanan temel kimlik doğrulama (basic authentication) yöntemidir.

Önüne bir reverse proxy yerleştirin, TLS (transport layer security) sonlandırma işlemini burada yapın ve Kong'u loopback adresine bağlayarak dışarıdan erişimi tamamen kapatın. docker-compose.yml içerisinde kong port eşleştirmesi 127.0.0.1:8000:8000 haline gelir ve proxy trafiği bu adrese yönlendirir. Birden fazla Compose uygulaması önünde Traefik rehberi, sertifika tarafındaki yapılandırmayı kapsamaktadır.

Ayrıca güvenlik duvarı üzerinden diğer portları da kapatın; çünkü Docker, portları kendi iptables kurallarını yazarak yayınlar ve bu kurallar standart bir ufw yapılandırması tarafından görülmez. Bu tuzak, Docker container'ları neden ufw kurallarınızı yok sayar başlıklı yazıda açıklanmıştır.

Dizini değil, veritabanını yedekleyin

Postgres verileri ./volumes/db/data yolundaki bir bind mount içinde tutulur. Konteyner çalışırken bu dizini kopyalamak, tutarsız bir kopyaya yol açar; çünkü Postgres yazma işlemlerini önbelleğe alır ve diskteki dosyalar yalnızca bir checkpoint anında tutarlı hale gelir. Geri yükleme işlemi genellikle çalışsa da bazen son işlemleri sessizce kaybedebilir; bu durum, bir yedekleme için olabilecek en kötü hata senaryosudur.

Bunun yerine dump alın. pg_dumpall komutu konteyner içinde çalışır ve tutarlı bir anlık görüntü oluşturur:

docker exec -t supabase-db pg_dumpall -U postgres > supabase-$(date +%F).sql

Yedeğe güvenmeden önce dosyanın boş olmadığını doğrulayın. Ardından bu dump dosyalarını bir zaman çizelgesine bağlı olarak sunucudan dışarı aktarın; restic ile şifreli uzak yedekleme bu amaçla kullanılır. Aynı zamanda .env dosyanızı da yedekleyin. JWT_SECRET dosyasının kaybedilmesi, verilen tüm token'ların geçersiz kalması ve saklanan tüm şifreli gizli verilerin okunamaması anlamına gelir.

Yüklenen dosyalar ./volumes/storage dizininde bulunur; bunlar standart dosyalar olduğu için düz bir kopyalama işlemi yeterlidir.

Veri kaybı olmadan güncelleme

Supabase, imaj sürümlerini docker-compose.yml içinde sabitler; siz güncellemediğiniz sürece hiçbir bileşen değişmez. Elle kurduğunuz her stack'te sürüm sabitleme uygulanmaya değerdir. Bu nedenle self-hosted RustDesk relay değişken bir etiketi izlemek yerine iki sunucu imajının sürümünü sabitler. Bir yükseltme, zaman ayırabildiğiniz bir sabah sizin seçtiğiniz bir işlem olmalıdır. Her seferinde önce dump alın.

docker compose pull
sh run.sh recreate

recreate, yığını durdurur ve yeni imajlarla tekrar başlatır. Verileriniz container içerisinde değil, ana makine üzerindeki bind mount alanlarında tutulduğu için korunur. Büyük sürüm yükseltmeleri öncesinde depodaki CHANGELOG.md dosyasını okuyun; çünkü Postgres ana sürüm yükseltmeleri otomatik değildir ve dump ile restore işlemlerini gerektirir.

Compose dosyasındaki değişiklikleri uygulamak için yukarı akış (upstream) deposunu tekrar klonlayın ve .env dosyasının üzerine yazmamaya dikkat ederek docker dizinini projenizin üzerine kopyalayın.

Veritabanı dahil her şeyi silen tam sıfırlama işlemi ayrı bir betiktir ve onay ister:

sh reset.sh

FAQ

API çağrılarım neden "Geçersiz kimlik doğrulama bilgileri" hatası veriyor?

ANON_KEY veya SERVICE_ROLE_KEY değeriniz, .env içinde bulunan JWT_SECRET ile imzalanmamıştır. Ağ geçidi, her istekteki imzayı doğrular ve uyuşmazlık durumunda isteği reddeder. sh utils/generate-keys.sh --update-env kullanarak üçünü birlikte yeniden oluşturun, ardından servislerin yeni değerleri okuması için sh run.sh recreate komutunu çalıştırın.

2 GB RAM'li bir VPS üzerinde self-hosted Supabase çalıştırabilir miyim?

Güvenilir bir şekilde çalışmaz. Temmuz 2026 itibarıyla yığın, yaklaşık on dört servis çalıştırdığı için boşta 3 GB civarında bellek tüketir. Bu nedenle 2 GB'lık bir sunucuda container'lar "out of memory killer" tarafından sonlandırılır ve docker compose ps içinde 137 çıkış kodunu görürsünüz. Üretim ortamı için 8 GB kullanın; bireysel geliştirme için ise 4 GB'ı alt sınır olarak kabul edin.

Self-hosted Supabase, edge functions içeriyor mu?

Evet. Compose dosyası, Deno tabanlı functions çalışma zamanını içerir ve ./volumes/functions altına yerleştirdiğiniz her şeyi çalıştırır. Barındırılan platformun küresel dağıtım ağını içermediği için fonksiyonlarınız tek bir sunucuda ve tek bir konumda çalışır.

Postgres veritabanına doğrudan nasıl bağlanırım?

Sunucunun kendisinde etkileşimli bir kabuk için docker exec -it supabase-db psql -U postgres kullanın. Harici bir istemci için, postgres.<POOLER_TENANT_ID> kullanıcısı ve POSTGRES_PASSWORD parolanız ile 5432 numaralı port üzerinden Supavisor'a bağlanın. Bu portu internete açmayın. Bağlantıyı bir VPN veya SSH tüneli üzerinden sağlayın.

Kimlik doğrulama onay e-postalarım neden localhost adresine yönlendiriyor?

.env içindeki SITE_URL ve API_EXTERNAL_URL varsayılan değerlerinde bırakılmıştır. Kimlik doğrulama servisi, tüm onay ve parola sıfırlama bağlantılarını bu iki değeri temel alarak oluşturur; dolayısıyla kendisine verilen adresi gönderir. Her iki değeri de gerçek genel URL adresinizle güncelleyin ve yığını yeniden oluşturun.