Supabase self-hosted z Docker Compose bez CLI: konfiguracja własnego rejestru
Uruchomienie produkcyjnego stacku Supabase na czystym Docker Compose bez CLI. Pełna konfiguracja z własnymi rejestrami, zmiennymi środowiskowymi i siecią między serwisami.
Ten runbook rozszerza poradnik ECR 403 zmiana rejestru. Tamten naprawia lokalne środowisko deweloperskie (development). Ten pokrywa produkcyjne wdrożenia self-hosted, gdzie CLI nie powinien brać udziału w procesie.
Objawy
Chcesz uruchomić Supabase self-hosted, ale:
supabase startnie nadaje się do produkcji (to polecenie wyłącznie deweloperskie).- Twój pipeline CI/CD nie może zależeć od zainstalowanego Supabase CLI.
- Potrzebujesz obrazów z prywatnego rejestru, nie z publicznego ECR.
- Potrzebujesz pełnej kontroli nad zmiennymi środowiskowymi, siecią i wersjami serwisów.
Przyczyna
Supabase CLI ukrywa w sobie konfigurację Docker Compose, którą generuje w czasie wykonania. To oznacza:
- Nie możesz przypiąć dokładnych wersji w swoim IaC lub GitOps.
- CLI narzuca własną konfigurację sieci i wolumenów.
- Aktualizacje następują gdy CLI się zaktualizuje, nie gdy Ty zdecydujesz.
- Środowiska korporacyjne wymagające audytu pochodzenia obrazów nie mogą sprawdzić konfiguracji generowanej przez CLI.
Rozwiązaniem jest utrzymywanie własnego docker-compose.yml, który odwołuje się bezpośrednio do obrazów Supabase z pełnym przypięciem wersji i kontrolą rejestru.
Rozwiązanie
Krok 1: Utwórz bazowy plik Docker Compose
Zacznij od oficjalnej referencji self-hostingu Supabase, a następnie dostosuj do swojego rejestru:
# docker-compose.yml
version: "3.8"
services:
postgres:
image: ${IMAGE_REGISTRY:-docker.io}/supabase/postgres:15.6.1.143
restart: unless-stopped
ports:
- "5432:5432"
environment:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: postgres
volumes:
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
auth:
image: ${IMAGE_REGISTRY:-docker.io}/supabase/gotrue:v2.158.1
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
environment:
GOTRUE_DB_DATABASE_URL: postgres://supabase_auth_admin:${POSTGRES_PASSWORD}@postgres:5432/postgres
GOTRUE_SITE_URL: ${SITE_URL}
GOTRUE_URI_ALLOW_LIST: ${ADDITIONAL_REDIRECT_URLS:-}
GOTRUE_JWT_SECRET: ${JWT_SECRET}
GOTRUE_JWT_EXP: 3600
GOTRUE_EXTERNAL_EMAIL_ENABLED: "true"
GOTRUE_MAILER_AUTOCONFIRM: "false"
API_EXTERNAL_URL: ${API_EXTERNAL_URL}
rest:
image: ${IMAGE_REGISTRY:-docker.io}/supabase/postgrest:v12.2.3
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
environment:
PGRST_DB_URI: postgres://authenticator:${POSTGRES_PASSWORD}@postgres:5432/postgres
PGRST_DB_SCHEMAS: public,storage,graphql_public
PGRST_DB_ANON_ROLE: anon
PGRST_JWT_SECRET: ${JWT_SECRET}
realtime:
image: ${IMAGE_REGISTRY:-docker.io}/supabase/realtime:v2.30.34
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
environment:
DB_HOST: postgres
DB_PORT: "5432"
DB_USER: supabase_admin
DB_PASSWORD: ${POSTGRES_PASSWORD}
DB_NAME: postgres
SECRET_KEY_BASE: ${SECRET_KEY_BASE}
API_JWT_SECRET: ${JWT_SECRET}
storage:
image: ${IMAGE_REGISTRY:-docker.io}/supabase/storage-api:v1.0.6
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
environment:
DATABASE_URL: postgres://supabase_storage_admin:${POSTGRES_PASSWORD}@postgres:5432/postgres
STORAGE_BACKEND: file
FILE_STORAGE_BACKEND_PATH: /var/lib/storage
ANON_KEY: ${ANON_KEY}
SERVICE_KEY: ${SERVICE_ROLE_KEY}
POSTGREST_URL: http://rest:3000
volumes:
- storage-data:/var/lib/storage
kong:
image: ${IMAGE_REGISTRY:-docker.io}/library/kong:3.5
restart: unless-stopped
ports:
- "8000:8000"
- "8443:8443"
environment:
KONG_DATABASE: "off"
KONG_DECLARATIVE_CONFIG: /var/lib/kong/kong.yml
volumes:
- ./kong.yml:/var/lib/kong/kong.yml:ro
volumes:
postgres-data:
storage-data:
Krok 2: Utwórz plik .env dla sekretów
# .env
IMAGE_REGISTRY=docker.io
POSTGRES_PASSWORD=twoje-silne-haslo
JWT_SECRET=twoj-jwt-secret-min-32-znaki
ANON_KEY=twoj-anon-key
SERVICE_ROLE_KEY=twoj-service-role-key
SITE_URL=https://twoja-aplikacja.example.com
API_EXTERNAL_URL=https://api.example.com
SECRET_KEY_BASE=twoj-secret-key-base-min-64-znaki
Krok 3: Zmiana rejestru
Aby pobierać obrazy z prywatnego ECR:
IMAGE_REGISTRY=123456789.dkr.ecr.eu-west-1.amazonaws.com
Aby pobierać z GHCR:
IMAGE_REGISTRY=ghcr.io
Wszystkie serwisy pobierają prefix rejestru z jednej zmiennej. Nie trzeba edytować każdej linii z obrazem.
Krok 4: Uruchomienie stacku
docker compose up -d
# Obserwuj logi pod kątem błędów startu
docker compose logs -f --tail=50
Krok 5: Konfiguracja bramki API Kong
Utwórz deklaratywną konfigurację kong.yml, aby kierować żądania do odpowiednich serwisów:
# kong.yml
_format_version: "3.0"
services:
- name: auth
url: http://auth:9999
routes:
- name: auth-routes
paths:
- /auth/v1
strip_path: true
- name: rest
url: http://rest:3000
routes:
- name: rest-routes
paths:
- /rest/v1
strip_path: true
- name: realtime
url: http://realtime:4000
routes:
- name: realtime-routes
paths:
- /realtime/v1
strip_path: true
- name: storage
url: http://storage:5000
routes:
- name: storage-routes
paths:
- /storage/v1
strip_path: true
Weryfikacja
# 1. Potwierdź, że wszystkie kontenery działają
docker compose ps
# Oczekiwany wynik: wszystkie serwisy pokazują status "Up"
# 2. Zweryfikuj, że obrazy pochodzą z właściwego rejestru
docker compose images
# Oczekiwany wynik: kolumna IMAGE pokazuje prefix Twojego rejestru
# 3. Sprawdź czy PostgREST odpowiada
curl -s http://localhost:8000/rest/v1/ \
-H "apikey: ${ANON_KEY}" | head -c 100
# Oczekiwany wynik: odpowiedź JSON (pusta tablica lub informacja o schemacie)
# 4. Sprawdź health Auth (GoTrue)
curl -s http://localhost:8000/auth/v1/health
# Oczekiwany wynik: {"status":"ok"}
# 5. Sprawdź łączność z bazą danych
docker compose exec postgres pg_isready -U postgres
# Oczekiwany wynik: accepting connections
Jeśli wszystkie pięć sprawdzeń przechodzi, Twój stack Supabase działa niezależnie od CLI. Kontrolujesz wersje, źródło rejestru i pełną konfigurację. Stąd możesz zintegrować z pipeline deployment, generując plik .env z menedżera sekretów (AWS Secrets Manager, Vault itp.).
Dla zespołów potrzebujących skanowania obrazów i kontroli łańcucha dostaw, zobacz nasz poradnik self-hosting Supabase na AWS bez ECR, który pokrywa budowanie i podpisywanie własnych obrazów.
Potrzebujesz produkcyjnego Supabase na AWS?
Umów bezpłatną 30-minutową rozmowę. Budujemy infrastrukturę dla self-hosted Supabase z prywatnymi rejestrami, automatycznymi backupami i pełnym monitoringiem.