Supabase od środka: architektura PostgreSQL, Row Level Security, self-hosting i produkcyjne wdrożenie

Opublikowano: 24 maja 2026 · Autor: Marcin Szewczyk-Wilgan

Supabase zyskuje popularność jako otwartoźródłowa alternatywa Firebase, ale większość materiałów w sieci ogranicza się do tutoriali „jak zrobić todo app". Poniższe opracowanie idzie głębiej – pokazuje, co Supabase robi pod maską z PostgreSQL, jak działa Row Level Security w kontekście API i WebSocketów, czym jest Supavisor i dlaczego zastąpił PgBouncer, oraz jak wdrożyć Supabase produkcyjnie na własnym serwerze. Artykuł powstał na podstawie aktualnej dokumentacji architektonicznej Supabase (2025–2026) oraz wieloletniego doświadczenia w administracji PostgreSQL.

Wprowadzenie – czym jest Supabase i dlaczego warto go zrozumieć

Supabase to platforma Backend-as-a-Service (BaaS), która stawia PostgreSQL w centrum całej architektury. W odróżnieniu od Firebase – gdzie baza danych (Firestore) jest zastrzeżonym produktem Google z ograniczonym modelem zapytań – Supabase daje deweloperowi pełny, nieograniczony dostęp do relacyjnej bazy danych. SQL, indeksy, transakcje ACID, widoki zmaterializowane, funkcje PL/pgSQL, rozszerzenia (np. PostGIS, pgvector) – wszystko jest dostępne, ponieważ pod spodem działa zwykły PostgreSQL.

Filozofia Supabase opiera się na trzech zasadach: otwartość (każdy komponent to niezależny projekt open-source), kompozycyjność (usługi można uruchamiać osobno) i brak abstrakcji (deweloper widzi bazę danych, nie ukrytą warstwę pośrednią). To czyni Supabase interesującym nie tylko dla startupów szukających szybkiego backendu, ale także dla inżynierów infrastruktury, którzy chcą zrozumieć, jak zbudować nowoczesny stos aplikacyjny wokół PostgreSQL.

PostgreSQL jako centralny silnik Supabase

W typowej architekturze webowej baza danych pełni rolę „magazynu" – dane wchodzą i wychodzą, a cała logika biznesowa, autoryzacja i routing żyją w warstwie aplikacji (np. Express.js, Django, Laravel). Supabase odwraca ten model. PostgreSQL nie jest tutaj pasywnym magazynem – jest centralnym silnikiem obliczeniowym, który odpowiada za przechowywanie danych, autoryzację (Row Level Security), generowanie zdarzeń (replikacja logiczna WAL), przechowywanie metadanych plików (Storage) i zarządzanie tożsamościami użytkowników (schemat auth).

Supabase przyznaje właścicielowi projektu pełne uprawnienia administracyjne do bazy. Możesz połączyć się bezpośrednio przez TCP, uruchomić EXPLAIN ANALYZE, stworzyć własne indeksy, zainstalować rozszerzenia – coś niemożliwego w Firebase, DynamoDB czy wielu usługach zarządzanych. Ta transparentność ma praktyczne konsekwencje: jeśli kiedykolwiek zdecydujesz się odejść od Supabase, zabierasz ze sobą standardową bazę PostgreSQL, którą możesz uruchomić na dowolnym serwerze. Szczegóły strojenia PostgreSQL omawiamy w publikacji Strojenie wydajności PostgreSQL.

Stos komponentów: co robi każda usługa

Supabase to nie jeden monolityczny program – to zestaw niezależnych usług open-source, z których każda realizuje jedną konkretną funkcję. Razem tworzą kompletny backend, ale można je również uruchamiać osobno.

PostgREST – baza danych jako API

PostgREST to serwer napisany w Haskellu, który przy starcie odczytuje schemat bazy danych i automatycznie generuje REST API dla wszystkich tabel, widoków i funkcji. Nie trzeba pisać żadnych endpointów – zapytanie HTTP GET /rest/v1/products?price=gte.100&order=name zostaje przetłumaczone na zoptymalizowane zapytanie SQL z filtrami i sortowaniem.

Co istotne, PostgREST nie implementuje własnej logiki autoryzacji. Zamiast tego przełącza rolę bazy danych na tę wskazaną w tokenie JWT użytkownika (zazwyczaj authenticated lub anon) i ustawia zmienne sesyjne (GUC) z danymi z tokenu. Dzięki temu polityki Row Level Security w PostgreSQL automatycznie filtrują dane – PostgREST jest jedynie pośrednikiem, a cała logika bezpieczeństwa żyje w bazie.

Aby unikać problemu N+1 zapytań przy pobieraniu danych z relacjami (np. zamówienia z pozycjami), PostgREST wykorzystuje funkcje agregacji JSON wbudowane w PostgreSQL (json_agg, jsonb_build_object). Jedno zapytanie HTTP zwraca zagnieżdżoną strukturę JSON, zamiast wymagać dziesiątek osobnych żądań.

GoTrue – uwierzytelnianie i tokeny JWT

GoTrue to serwis uwierzytelniania napisany w Go (oryginalnie fork projektu Netlify). Zarządza rejestracją użytkowników, logowaniem (hasło, OAuth, SSO), sesjami i tokenami JWT. Dane użytkowników przechowuje w izolowanym schemacie auth w PostgreSQL.

Po udanym logowaniu GoTrue generuje krótkotrwały token dostępu (access token) i jednorazowy token odświeżający (refresh token). Token dostępu zawiera w ładunku (payload) identyfikator użytkownika (sub), jego rolę i ewentualne metadane – te same dane, które polityki RLS odczytują funkcją auth.uid().

GoTrue wspiera wielopoziomowe uwierzytelnianie (MFA) – po weryfikacji TOTP, SMS lub e-mail token zostaje oznaczony poziomem aal2, co pozwala na tworzenie polityk RLS wymagających dwuskładnikowej weryfikacji dla wrażliwych operacji. System chroni się przed kradzieżą tokenów poprzez ścisłą rotację refresh tokenów – ponowne użycie unieważnionego tokenu natychmiast zamyka całą rodzinę sesji.

Realtime – zmiany w bazie przez WebSocket

Serwer Realtime, zbudowany w Elixirze na frameworku Phoenix, utrzymuje tysiące jednoczesnych połączeń WebSocket, korzystając z lekkości procesów maszyny wirtualnej BEAM (Erlang VM). Jego zadaniem jest strumieniowanie zmian w bazie danych do podłączonych klientów w czasie rzeczywistym.

Mechanizm opiera się na replikacji logicznej PostgreSQL – Realtime podłącza się do slotu replikacyjnego i dekoduje zmiany z dziennika WAL (za pomocą wtyczki wal2json). Każda operacja INSERT, UPDATE i DELETE w bazie jest konwertowana na strukturę JSON i wysyłana do klientów, którzy subskrybują daną tabelę. Mechanikę replikacji logicznej i slotów szczegółowo omawiamy w publikacji Replikacja i wysoka dostępność PostgreSQL.

Storage API i Edge Functions

Storage API (Node.js/TypeScript) to usługa przechowywania plików kompatybilna z S3. Kluczowa cecha: metadane plików przechowywane są w PostgreSQL, dzięki czemu dostęp do plików podlega tym samym politykom RLS co dane w tabelach. Upload pliku do prywatnego bucketu wymaga tokenu JWT z odpowiednimi uprawnieniami – bez pisania osobnego middleware.

Edge Functions (Deno runtime) pozwalają uruchamiać własny kod TypeScript po stronie serwera – np. integrację z zewnętrznym API płatności, wysyłkę e-maili czy przetwarzanie webhooków. Działają poza cyklem żądanie-odpowiedź bazy danych, dzięki czemu nie blokują połączeń PostgreSQL.

Kong – brama wejściowa API

Kong (oparty na Nginx, napisany w Lua) pełni rolę API Gateway – jedynego punktu wejścia dla całego ruchu klientów. Realizuje routing oparty na ścieżkach, waliduje klucze API, wymusza limity zapytań (rate limiting) i wstrzykuje nagłówki autoryzacyjne do usług wewnętrznych.

Przy żądaniach nieuwierzytelnionych (klient przesyła klucz API projektu, ale nie ma tokenu sesji użytkownika) Kong sam generuje wewnętrzny JWT z rolą anon i przekazuje go do usługi docelowej. Przy żądaniach uwierzytelnionych – przepuszcza token sesji użytkownika bez modyfikacji. Ta logika oznacza, że usługi wewnętrzne (PostgREST, GoTrue) nigdy nie muszą samodzielnie walidować kluczy API – robią to wyłącznie na poziomie bramy.

Ścieżka routingu Usługa docelowa
/rest/v1/*PostgREST – REST API bazy danych
/auth/v1/*GoTrue – rejestracja, logowanie, sesje
/realtime/v1/*Realtime – WebSocket (upgrade połączenia)
/storage/v1/*Storage API – pliki i buckety S3
/functions/v1/*Edge Functions – kod TypeScript (Deno)

Row Level Security – autoryzacja na poziomie bazy danych

Jak RLS działa w Supabase

W tradycyjnej architekturze webowej autoryzacja żyje w kodzie aplikacji – serwer sprawdza, czy użytkownik ma prawo zobaczyć lub zmodyfikować dany zasób. Problem polega na tym, że każdy nowy endpoint wymaga osobnej logiki autoryzacyjnej, a błąd w jednym miejscu otwiera lukę w całym systemie.

Supabase przenosi autoryzację do samej bazy danych za pomocą natywnego mechanizmu PostgreSQL – Row Level Security. Polityka RLS to wyrażenie SQL, które baza ewaluuje przy każdym odczycie lub zapisie. Jeśli wyrażenie zwróci false dla danego wiersza, użytkownik go nie zobaczy – niezależnie od tego, w jaki sposób połączył się z bazą (przez PostgREST, bezpośrednie połączenie TCP czy narzędzie administracyjne).

Typowa polityka wygląda tak: auth.uid() = user_id – użytkownik widzi tylko wiersze, w których kolumna user_id odpowiada jego identyfikatorowi z tokenu JWT. Funkcja auth.uid() to helper Supabase, który odczytuje zmienną sesyjną (GUC) ustawioną przez PostgREST na początku transakcji.

Mechanizm ten ma subtelną pułapkę, którą warto znać. Dla żądań nieuwierzytelnionych (rola anon) funkcja auth.uid() zwraca NULL. W logice SQL wyrażenie NULL = user_id ewaluuje się do false (nie do true ani do NULL), więc polityka cicho nie zwraca żadnych wierszy – bez komunikatu o błędzie. Dla zachowania przewidywalności polityki powinny zawierać jawne sprawdzenie: auth.uid() IS NOT NULL AND auth.uid() = user_id.

Istotny jest również sposób, w jaki PostgREST izoluje konteksty między użytkownikami. Na początku każdej transakcji PostgREST ustawia zmienne GUC (request.jwt.claims, rola bazy) na dane z tokenu JWT bieżącego klienta. Po zakończeniu transakcji (COMMIT lub ROLLBACK) zmienne są czyszczone do pustego stringa. Dzięki temu połączenie z puli nie „pamięta" kontekstu poprzedniego użytkownika – nawet jeśli Supavisor przydzieli to samo fizyczne połączenie innemu klientowi.

Od 2025 roku Supabase automatycznie włącza RLS na każdej nowo tworzonej tabeli za pomocą triggera na zdarzeniu ddl_command_end. Jeśli tabela zostanie utworzona przez zewnętrzne narzędzie migracyjne (np. Prisma, Drizzle), trigger natychmiast wykonuje ALTER TABLE ... ENABLE ROW LEVEL SECURITY. Domyślnie – bez zdefiniowanych polityk – tabela z włączonym RLS nie zwraca żadnych wierszy, co realizuje zasadę „bezpieczne domyślnie".

Optymalizacja wydajności RLS

RLS wprowadza narzut obliczeniowy – każdy wiersz musi być ewaluowany przez politykę. Przy dużych tabelach i prostym wywołaniu auth.uid() = user_id PostgreSQL przelicza wartość auth.uid() osobno dla każdego wiersza. Optymalizacja polega na opakowanie wywołania w subselect: (SELECT auth.uid()) = user_id. Wymusza to na planerze zapytań utworzenie initPlan – wartość jest obliczana raz i cache'owana na czas całego zapytania.

Dla złożonej logiki autoryzacyjnej (np. systemy ról, uprawnienia per organizacja) Supabase rekomenduje Custom Claims – wstrzykiwanie roli użytkownika bezpośrednio do tokenu JWT za pomocą Auth Hooka (funkcja PL/pgSQL wywoływana podczas generowania tokenu). Dzięki temu polityka RLS sprawdza rolę z tokenu ((auth.jwt() ->> 'user_role') = 'admin') zamiast wykonywać kosztowne JOIN z tabelą ról przy każdym zapytaniu.

Od 2025 roku Supabase wspiera również natywne Column-Level Security PostgreSQL. Podczas gdy RLS kontroluje, które wiersze widzi użytkownik, uprawnienia kolumnowe określają, które pola w tych wierszach są widoczne. Wrażliwe kolumny (np. PESEL, dane finansowe, PII) mogą być wykluczone z odpowiedzi API PostgREST, nawet jeśli polityka RLS zezwala na dostęp do wiersza. W połączeniu z RLS daje to dwuwymiarową kontrolę dostępu: filtrowanie wierszy i filtrowanie kolumn na poziomie bazy, bez konieczności pisania logiki w kodzie aplikacji.

WALRUS – RLS na strumieniu Realtime

Największym wyzwaniem architektonicznym Supabase jest egzekwowanie Row Level Security na strumieniu Realtime. Gdy administrator zaktualizuje wiersz w tabeli, zmiana powinna być widoczna dla Użytkownika A (właściciela wiersza), ale nie dla Użytkownika B (który nie ma uprawnień). Dekodowanie zmian z WAL nie wystarczy – trzeba jeszcze sprawdzić, komu wolno je zobaczyć.

Supabase rozwiązuje to za pomocą modułu WALRUS (Write Ahead Log Realtime Unified Security). Dla każdej zmiany odebranej ze strumienia WAL, serwer Realtime wywołuje funkcję PostgreSQL realtime.apply_rls(jsonb), która:

  1. Ustawia kontekst bazy danych (rolę i zmienne JWT) na tożsamość każdego klienta WebSocket subskrybującego daną tabelę.
  2. Ponownie odpytuje bazę o zmieniony wiersz (po kluczu głównym) – tym razem w kontekście konkretnego użytkownika, więc RLS automatycznie filtruje wynik.
  3. Stosuje filtry subskrypcji zdefiniowane przez klienta (np. eq, gt, in).
  4. Usuwa z wyniku kolumny, do których użytkownik nie ma uprawnień SELECT (Column-Level Security).

Mechanizm ten ma ograniczenia, które trzeba znać. Tabela musi posiadać klucz główny – bez niego WALRUS nie może ponownie odpytać bazy i zwraca błąd HTTP 400. Dla operacji DELETE polityka RLS nie może być zastosowana retrospektywnie, ponieważ wiersz już fizycznie nie istnieje – stary rekord jest wysyłany do wszystkich subskrybentów. Dlatego w tabelach z wrażliwymi danymi należy ostrożnie konfigurować REPLICA IDENTITY, aby uniknąć wycieku danych podczas zdarzeń usunięcia.

Supavisor – connection pooling nowej generacji

PostgreSQL tworzy osobny proces systemowy dla każdego połączenia – model, który nie skaluje się przy tysiącach klientów, szczególnie w środowiskach serverless (Vercel, AWS Lambda), gdzie każde wywołanie funkcji otwiera nowe połączenie. Supabase historycznie używał PgBouncera, ale jego jednowątkowa architektura stawała się wąskim gardłem. Mechanikę tego problemu i działania poolerów opisujemy w publikacji Strojenie wydajności PostgreSQL.

Supavisor to connection pooler napisany w Elixirze (we współpracy z Dashbit), zaprojektowany do obsługi milionów jednoczesnych połączeń. Oferuje trzy tryby pracy, z których każdy odpowiada innemu scenariuszowi architektonicznemu:

Tryb Port Cykl życia połączenia Zastosowanie
Transaction6543Połączenie przypisane na czas transakcji – po COMMIT wraca do puli.Serverless API, Edge Functions, aplikacje o wysokiej współbieżności.
Session5432Połączenie na czas sesji TCP. Przy wyczerpaniu puli – kolejkowanie do 60 s.Legacy aplikacje, długotrwałe zadania batchowe, sieci IPv4-only.
Native5432Proxy 1:1 bez multipleksowania – bezpośrednie połączenie z bazą.Administracja, DDL, migracje schematów.

Kluczowa innowacja Supavisora 1.0 to rozwiązanie problemu prepared statements w trybie Transaction. PgBouncer wymuszał rezygnację z prepared statements, bo po zakończeniu transakcji klient mógł trafić na inne fizyczne połączenie, które nie znało skompilowanego planu. Supavisor rozwiązuje to przez rozgłaszanie – gdy klient wysyła PREPARE, Supavisor propaguje plan na wszystkie połączenia w puli. Benchmark: 1 003 200 jednoczesnych połączeń przy 20 000 zapytań na sekundę bez degradacji latencji.

Bezpieczeństwo: klucze asymetryczne, Splinter i GitHub scanning

W 2025 roku Supabase przeszedł fundamentalną zmianę modelu bezpieczeństwa – z symetrycznych kluczy JWT (HS256) na model asymetryczny. Tokeny są podpisywane kluczem prywatnym (izolowanym od reszty infrastruktury), a weryfikowane kluczem publicznym. Jeśli zostanie skompromitowany węzeł weryfikujący (np. API Gateway), atakujący nie może tworzyć nowych tokenów – nie ma dostępu do klucza podpisującego.

Statyczne klucze anon i service_role zostały zastąpione przez rotowalne klucze z podziałem na publishable (niskie uprawnienia, bezpieczne do umieszczenia w kodzie frontendowym) i secret (pełne uprawnienia, wyłącznie po stronie serwera). Integracja z GitHub Secret Scanning automatycznie wykrywa commitowanie kluczy do publicznych repozytoriów i unieważnia je w ciągu godzin.

Splinter to linter bezpieczeństwa PostgreSQL wbudowany w Supabase. Skanuje schemat bazy pod kątem typowych błędów: tabele w schemacie public bez włączonego RLS (otwarte API), nieautoryzowany dostęp do schematu auth (wyciek danych tożsamościowych), funkcje SECURITY DEFINER z modyfikowalnym search_path (wektor eskalacji uprawnień) oraz nieefektywne implementacje funkcji autoryzacyjnych (degradacja wydajności przy dużych tabelach).

Na poziomie sieciowym platforma oferuje AWS VPC PrivateLink dla klientów Enterprise – ruch do bazy przechodzi przez prywatną sieć AWS, z pominięciem publicznego internetu. Dla publicznych endpointów działają mechanizmy fail2ban (blokada po serii nieudanych logowań) i ograniczenia CIDR dla bezpośrednich połączeń z bazą.

Self-hosting: Docker Compose i Kubernetes

Docker Compose – pojedynczy serwer

Supabase udostępnia oficjalną konfigurację Docker Compose, która uruchamia cały stos (Kong, GoTrue, PostgREST, Realtime, Storage, PostgreSQL) na jednej maszynie. Minimalne wymagania to 2 rdzenie CPU, 4 GB RAM i 50 GB SSD – dla produkcji rekomendowane jest 4+ rdzeni i 8+ GB RAM.

Kong mapuje wewnętrzne porty kontenerów na jeden punkt wejścia (domyślnie port 8000), symulując zachowanie chmury Supabase. Self-hosting nie wysyła telemetrii do serwerów Supabase – logi trafiają do lokalnego stosu Vector → Logflare → PostgreSQL (lub BigQuery).

Kluczowa różnica w stosunku do chmury: cały ciężar administracji – backupy PostgreSQL, aktualizacje bezpieczeństwa, strojenie bazy, konfiguracja SSL, monitoring – spoczywa na zespole DevOps. Nie ma automatycznego PITR (Point-in-Time Recovery) ani read replik. Dla backupów PostgreSQL na ZFS odsyłamy do naszej publikacji Optymalizacja ZFS dla baz danych. Kwestie konteneryzacji omawiamy w publikacji Konteneryzacja aplikacji webowych.

Kubernetes – skalowanie horyzontalne

Dla wdrożeń wymagających horyzontalnej skalowalności społeczność utrzymuje repozytorium Helm chartów. Bezstanowe komponenty (PostgREST, Realtime, Kong) skalują się horyzontalnie za pomocą Horizontal Pod Autoscaler. Warstwa bazodanowa wymaga Persistent Volume Claims dla trwałości danych i dedykowanego obrazu Docker z preinstalowanymi rozszerzeniami (pgjwt, wal2json).

Replikacja PostgreSQL i failover nie są częścią oficjalnych Helm chartów – należy je zrealizować za pomocą zewnętrznych operatorów (Zalando Postgres Operator, StackGres) lub wdrożenia Patroni. Mechanikę klastrów HA opisujemy w publikacji Replikacja i wysoka dostępność PostgreSQL.

Kiedy Supabase, a kiedy klasyczny backend

Supabase doskonale sprawdza się w scenariuszach, gdzie logika aplikacji sprowadza się do operacji CRUD na relacyjnych danych z autoryzacją per użytkownik: panele administracyjne, aplikacje SaaS z wieloma tenantami (RLS z tenant_id), MVP i prototypy wymagające szybkiego backendu, aplikacje mobilne z synchronizacją offline-first (Realtime + PostgREST).

W kontekście aplikacji B2B SaaS Supabase umożliwia dwa modele wielodostępności (multi-tenancy). Pierwszy – izolacja przez RLS (pooled tenancy) – polega na współdzieleniu jednej bazy przez wszystkich tenantów, z rozdzieleniem danych za pomocą kolumny tenant_id i polityki RLS: tenant_id = (auth.jwt() -> 'app_metadata' ->> 'tenant_id'). Jest efektywny i skaluje się do setek tenantów. Drugi – schema-per-tenant – tworzy oddzielny schemat PostgreSQL dla każdego klienta, zapewniając fizyczną izolację danych (ważne np. dla HIPAA). Komplikuje jednak migracje i wymaga dynamicznego przełączania schematów w zapytaniach API.

Praktyczny problem w modelu pooled: GoTrue wymaga globalnej unikalności adresu e-mail. Jeśli konsultant chce mieć konto w dwóch organizacjach, drugie rejestrowanie się nie powiedzie. Obejście stosowane w produkcji to wewnętrzne mapowanie e-maili – backend hashuje kombinację UUID tenanta i adresu e-mail (np. SHA256), rejestrując ten hash jako adres w GoTrue. Każdy tenant ma kryptograficznie unikalne konto, a prawdziwy adres e-mail jest rozwiązywany z osobnej tabeli mapującej.

Ograniczenia pojawiają się, gdy logika biznesowa jest złożona i wieloetapowa – orkiestracja kilku zewnętrznych API (płatności, wysyłka, CRM), skomplikowane workflow z kolejkami zadań, przetwarzanie plików w tle. Edge Functions rozwiązują część tych problemów, ale nie zastąpią pełnego serwera aplikacyjnego z własnym cyklem życia, middleware i obsługą błędów.

Podejście hybrydowe jest rekomendowaną strategią: Supabase jako warstwa danych (PostgreSQL + auth + storage + realtime) z własnym backendem (Node.js, Go, Python) obsługującym złożoną logikę biznesową. Backend łączy się z bazą PostgreSQL bezpośrednio (przez Supavisor w trybie Session lub Native), z pominięciem PostgREST, i sam zarządza transakcjami.

Zakończenie

Supabase to nie „Firebase na PostgreSQL" – to kompletna architektura mikroserwisowa, w której baza danych jest centralnym silnikiem autoryzacji, routingu i generowania zdarzeń. Zrozumienie jej wewnętrznej mechaniki – od GUC variables w PostgREST, przez WALRUS w Realtime, po broadcasting prepared statements w Supavisorze – pozwala na świadome decyzje architektoniczne i unikanie pułapek, które pojawiają się dopiero przy produkcyjnym obciążeniu.

Największą siłą Supabase jest fakt, że pod spodem działa standardowy PostgreSQL. Cała wiedza o strojeniu bazy, indeksach, autovacuum, replikacji i connection poolingu – opisana w pozostałych publikacjach WebOptimo – ma bezpośrednie zastosowanie. Supabase nie zastępuje tej wiedzy. Opakowanie jest nowe, ale silnik pozostaje tym samym, sprawdzonym przez dekady motorem relacyjnym.

W WebOptimo specjalizujemy się w administracji PostgreSQL, budowie infrastruktury serwerowej i wdrożeniach produkcyjnych. Jeśli planujesz wdrożenie Supabase na własnym serwerze, potrzebujesz strojenia bazy danych lub audytu bezpieczeństwa – skontaktuj się z nami. Sprawdź również nasze usługi administracji PostgreSQL, administracji serwerem oraz hostingu. Zobacz też nasze pozostałe publikacje: Strojenie PostgreSQL, PostgreSQL HA, Optymalizacja ZFS, Konteneryzacja oraz Architektura stosu LEMP.

FAQ – Supabase

Supabase to otwartoźródłowa platforma Backend-as-a-Service oparta na PostgreSQL. W przeciwieństwie do Firebase, która używa zastrzeżonej bazy NoSQL (Firestore), Supabase daje pełny dostęp do relacyjnej bazy danych ze wszystkimi jej możliwościami – SQL, indeksy, transakcje ACID, Row Level Security. Każdy komponent jest niezależnym projektem open-source, co eliminuje vendor lock-in.

Row Level Security to natywny mechanizm PostgreSQL, który pozwala definiować polityki dostępu na poziomie pojedynczych wierszy tabeli. Supabase deleguje całą autoryzację do RLS zamiast implementować ją w warstwie aplikacji. Nawet jeśli klient połączy się bezpośrednio z API, baza danych samodzielnie filtruje dane na podstawie tokenu JWT użytkownika.

Serwer Realtime podłącza się do replikacji logicznej PostgreSQL i dekoduje zmiany z dziennika WAL. Moduł WALRUS zapewnia, że każdy klient WebSocket widzi tylko te zmiany, do których ma dostęp zgodnie z politykami RLS – weryfikacja odbywa się przez ponowne odpytanie bazy w kontekście danego użytkownika.

Supavisor to connection pooler napisany w Elixirze, zaprojektowany do obsługi milionów jednoczesnych połączeń. PgBouncer jest jednowątkowy i nie skaluje się wertykalnie. Supavisor rozwiązuje również problem prepared statements w trybie transaction – rozgłasza plany zapytań na wszystkie połączenia w puli.

Minimalne wymagania to 2 rdzenie CPU, 4 GB RAM i 50 GB SSD. Dla środowisk produkcyjnych rekomendowane jest 4+ rdzeni, 8+ GB RAM i 80+ GB SSD. Self-hosting wymaga samodzielnego zarządzania backupami PostgreSQL, aktualizacjami, konfiguracją SSL i strojeniem bazy danych.

Tak, pod warunkiem świadomego podejścia. Supabase doskonale sprawdza się w aplikacjach CRUD, panelach, MVP i projektach SaaS. Ograniczeniem jest złożona logika biznesowa wymagająca orkiestracji wielu usług zewnętrznych – w takich scenariuszach klasyczny backend daje większą elastyczność. Rekomendowane jest podejście hybrydowe.

W 2025 roku Supabase przeszedł na model asymetryczny – tokeny podpisywane kluczem prywatnym, weryfikowane kluczem publicznym. Integracja z GitHub Secret Scanning automatycznie wykrywa commitowanie kluczy do publicznych repozytoriów i unieważnia je. Klucze dzielą się na publishable (bezpieczne w kodzie frontendowym) i secret (wyłącznie po stronie serwera).

Potrzebujesz wsparcia z Supabase lub PostgreSQL?

Self-hosting, strojenie bazy, audyt bezpieczeństwa. Bez zobowiązań – konkretna propozycja po analizie.

Telefon

+48 608 271 665

Pn–Pt, 8:00–16:00

E-mail

kontakt@weboptimo.pl

Odpowiadamy w ciągu 24h

Firma

WebOptimo

NIP: 6391758393