Open-source Firebase: сборка BaaS своими руками | AiManual
AiManual Logo Ai / Manual.
21 Июн 2026 Гайд

Собираем аналог Firebase на open-source: пошаговый туториал с кодом

Полный гайд по созданию open-source аналога Firebase: Supabase, Realtime, Auth, Storage и деплой в 2026. С примерами кода.

Реклама
cliv2

Firebase – штука удобная. Пока ты не начнешь платить $1000 в месяц за 5000 пользователей. Или пока не поймешь, что твои данные навсегда привязаны к экосистеме Google. Vendor lock-in – единственная болезнь, которая лечится только долларом. Но есть и другой путь – собрать свой BaaS из open-source кирпичиков.

В 2026 году экосистема созрела: Supabase v1.5 (последняя версия на июнь), PocketBase, Appwrite – каждый закрывает свою нишу. Но для максимально близкой копии Firebase (база данных, realtime, авторизация, storage, edge functions) лучше всего связка Supabase + собственный Docker Compose workflow. Под капотом – PostgreSQL, GoTrue, Kong, Realtime, Storage API. Всё как у взрослых, только бесплатно.

Мы не будем использовать облачный Supabase – мы поднимем self-hosted версию на своей машине. Полный контроль, никаких лимитов. Только ты и твой сервер.

Почему не Firebase?

Давай честно: Firebase – это приманка. Бесплатный Spark план – идеальный вход, но как только проект начинает расти, цены взлетают. Realtime Database стоит денег, Storage стоит денег, Cloud Functions – отдельная история. И самое ужасное – миграция на другую платформу превращается в харакири. Попробуй вытащить данные из Firestore и перенести в PostgreSQL без даунтайма.

Open-source альтернативы сняли все эти проблемы. Ты можешь запустить BaaS на своём VPS за $5 (аренда сервера) и получить ровно то же самое, но с возможностью кастомизации. Хочешь заменить email-аутентификацию на Telegram OAuth? Пожалуйста. Хочешь хранить файлы на S3? Конфиг в одну строку.

Кстати, в последнее время инструменты ИИ здорово упрощают настройку такой инфраструктуры. Например, нейросети уже генерируют конфиги и Dockerfile, а Cursor AI может написать сам SDK. Но мы не будем полагаться на магию – сделаем всё руками. От этого будет больше пользы.

Что собираем?

Наш самодельный Firebase будет уметь:

  • База данных – реляционная (PostgreSQL) с автоматической генерацией REST и GraphQL API через PostgREST.
  • Realtime – WebSocket подписки на изменения таблиц (usign Supabase Realtime).
  • Авторизация – email/пароль, Google, GitHub, Apple, Telegram (через GoTrue).
  • Storage – загрузка и раздача файлов (S3-совместимый или локальный).
  • Edge Functions – Deno-рантайм для серверного кода (аналог Cloud Functions).

Всё это – через единый Docker Compose файл. Развернуть можно на любой VPS, где есть Docker. Если у тебя нет сервера – рекомендую DigitalOcean (дешевый droplet за $4) или Hetzner.

Засада: как НЕ надо делать

Перед тем как писать код, покажу типичную ошибку новичков. Многие скачивают официальный супабейсовский docker-compose.yml и запускают как есть. Через 10 минут работа падает – порты конфликтуют, секретные ключи установлены по умолчанию, а Realtime не работает, потому что не настроен JWT.

Вот как НЕ надо:

# Не делай так! Плохая практика
git clone https://github.com/supabase/supabase
cd supabase/docker
docker compose up -d  # никакой конфигурации, никаких переменных окружения

Это рабочий способ для тестов, но не для продакшена. Мы пойдем правильным путем – создадим файл .env с кастомными паролями, выключим ненужные сервисы и настроим SSL.

Шаг 1: Подготовка окружения

Нам понадобятся:

  • Docker & Docker Compose v2.29+ (можно использовать Podman, я лично не советую – у Supabase есть нюансы с сетевыми мостами).
  • Node.js v22 (для клиентского SDK и edge functions).
  • Linux или Mac (на Windows тоже работает, но через WSL2, и это боль).

1 Клонируем репозиторий Supabase self-hosted

mkdir my-baas && cd my-baas
# Скачиваем актуальный compose-файл (на 2026 год последняя стабильная – v1.5.0)
curl -o docker-compose.yml https://raw.githubusercontent.com/supabase/supabase/master/docker/docker-compose.yml
curl -o .env.example https://raw.githubusercontent.com/supabase/supabase/master/docker/.env.example
cp .env.example .env

2 Настраиваем .env

Открой .env и измени эти строки. Без них продакшн – дыра:

# Обязательно меняем все пароли и ключи
POSTGRES_PASSWORD=your_strong_password_here
JWT_SECRET=$(openssl rand -hex 64)  # генерируем случайный
SITE_URL=http://localhost:3000  # потом поменяем на домен

# Отключаем ненужные сервисы, если не планируем их использовать
# Например, если тебе не нужен Logflare (логирование) – ставь false
ENABLE_LOGFLARE=false

# Для Storage лучше указать S3-бакет, но пока оставим локальный
FILE_SIZE_LIMIT=52428800  # 50 MB

Зачем это? Supabase запускает контейнеры с GoTrue (аутентификация), Realtime, Kong (API gateway), PostgREST, Storage. Все сервисы используют общий JWT-секрет, так что если он будет известен – злоумышленник сможет сгенерировать токен от имени любого пользователя. Не повторяй мой факап с default-ключом в песочнице.

3 Запускаем Docker Compose

docker compose up -d

# Проверяем, что все сервисы поднялись
docker compose ps
# Должны быть примерно такие:
# supabase-studio    Up  0.0.0.0:3000->3000/tcp
# supabase-kong      Up  0.0.0.0:8000->8000/tcp
# supabase-auth      Up  0.0.0.0:9999->9999/tcp (GoTrue)
# supabase-realtime  Up  0.0.0.0:4000->4000/tcp

Если всё зелёное – открывай в браузере http://localhost:8000 (Kong API). Там будет заглушка. Админка Supabase Studio – http://localhost:3000. Войди с логином supabase и паролем из .env (STUDIO_PASSWORD).

Шаг 2: Создаем базу и таблицы

В админке Studio перейди в SQL Editor и создай простую таблицу для сообщений (как в firebase realtime database, только реляционная):

CREATE TABLE public.messages (
  id BIGSERIAL PRIMARY KEY,
  created_at TIMESTAMPTZ DEFAULT NOW(),
  content TEXT NOT NULL,
  user_id UUID REFERENCES auth.users(id) ON DELETE CASCADE
);

-- Включаем Realtime для этой таблицы
ALTER PUBLICATION supabase_realtime ADD TABLE public.messages;

Обрати внимание на ALTER PUBLICATION – это и есть магия realtime. Без этой строки WebSocket подписки не будут работать. Firebase реалтайм база привязана к типу данных, а здесь ты контролируешь, какие таблицы транслировать.

Шаг 3: Авторизация – свой Auth сервер

GoTrue уже запущен. Чтобы зарегистрировать пользователя через email, используем клиентскую библиотеку. Но сначала надо настроить провайдеров.

3.1 Включаем OAuth провайдеров

В админке Studio -> Authentication -> Providers. Включи Google, GitHub, или любой другой. Для получения Client ID и Client Secret придется зарегистрировать OAuth приложение в соответствущем сервисе. Но если лень – можно работать только с email/пароль.

3.2 Пишем клиентский код (по сути – наш SDK)

Создай директорию client/ и поставь пакет Supabase JS:

mkdir client && cd client
npm init -y
npm install @supabase/supabase-js

Теперь создай файл supabase-client.js с конфигурацией. В 2026 году @supabase/supabase-js уже версия 2.45, API стабилен.

import { createClient } from '@supabase/supabase-js'

const supabaseUrl = 'http://localhost:8000'  // для разработки
const supabaseAnonKey = 'your-anon-key-from-supabase-studio-settings'

export const supabase = createClient(supabaseUrl, supabaseAnonKey)

// Регистрация пользователя
async function signUp(email, password) {
  const { data, error } = await supabase.auth.signUp({
    email,
    password,
  })
  if (error) throw error
  return data
}

// Вход
async function signIn(email, password) {
  const { data, error } = await supabase.auth.signInWithPassword({
    email,
    password,
  })
  if (error) throw error
  return data
}

Анонимный ключ (anon key) лежит в админке Studio -> Settings -> API. Этот же ключ будет передаваться клиентом, поэтому он публичный. Безопасность обеспечивается Row Level Security (RLS) – политиками доступа к таблицам.

Шаг 4: Realtime подписки – чувствуем магию

Самое вкусное – получать обновления таблицы в реальном времени. Вот как подписаться на изменения messages:

// Подписываемся на все изменения (INSERT, UPDATE, DELETE) в messages
const subscription = supabase
  .channel('public:messages')
  .on(
    'postgres_changes',
    { event: '*', schema: 'public', table: 'messages' },
    (payload) => {
      console.log('Change received!', payload)
    }
  )
  .subscribe()

// Чтобы отписаться позже:
// supabase.removeChannel(subscription)

Это работает потому, что Supabase Realtime слушает WAL (Write-Ahead Log) PostgreSQL и транслирует события через WebSocket. В Firebase под капотом та же логика, но там они скрывают реализацию, а здесь ты видишь каждый байт.

Если при подписке вылетает ошибка 42601: publication supabase_realtime does not exist – значит ты забыл выполнить ALTER PUBLICATION для таблицы. Возвращайся к Шагу 2.

Шаг 5: Storage – загружаем файлы

Firebase Storage – это просто бакет. Supabase Storage – тоже бакет, но можно прикрутить S3 (например, MinIO для самодостаточности). В self-hosted варианте по умолчанию используется локальная файловая система (volume docker). Загрузить файл:

// Создаем бакет (один раз) – лучше через админку
const { data: bucket, error } = await supabase.storage.createBucket('avatars', {
  public: false, // только авторизованные пользователи
})

// Загрузка файла
const file = document.querySelector('input[type=file]').files[0]
const { data, error } = await supabase.storage
  .from('avatars')
  .upload(`public/${file.name}`, file, {
    cacheControl: '3600',
    upsert: false,
  })

Чтобы скачать файл, нужно сгенерировать подписанный URL. Безопасность контролируется через RLS и политики бакета.

Шаг 6: Edge Functions – serverless на Deno

Supabase использует Deno для serverless функций. Они запускаются в отдельном контейнере. Создай функцию в папке supabase/functions/ (если используешь CLI) или через интерфейс Studio -> Edge Functions. Пример функции для отправки приветственного письма:

// supabase/functions/welcome/index.ts
import { serve } from 'https://deno.land/std@0.200.0/http/server.ts'

serve(async (req) => {
  const { email } = await req.json()
  // Отправляем письмо через какой-нибудь email API
  console.log(`Sending welcome to ${email}`)
  return new Response(JSON.stringify({ success: true }), {
    headers: { 'Content-Type': 'application/json' },
  })
})

Задеплоить можно через CLI: supabase functions deploy welcome. Теперь у тебя своя Cloud Functions, только без цен за вызовы.

Шаг 7: Деплой на VPS

На продакшене нельзя оставлять localhost. Выбери VPS с Ubuntu 24.04, установи Docker, скопируй папку с compose-файлами и .env. Подними через docker compose up -d.

Не забудь:

  • Настроить HTTPS через reverse proxy (Caddy или Nginx + Let's Encrypt).
  • Изменить SITE_URL и API_EXTERNAL_URL на реальный домен.
  • Включить бэкапы базы данных (через pg_dump внутри контейнера).

Вся магия в Docker Compose – он поднимает Kong как API-шлюз, который маршрутизирует запросы к нужным сервисам. Если нужен автоматический SSL, добавь Caddy:

# docker-compose.override.yml
version: '3'
services:
  caddy:
    image: caddy:2
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - caddy_data:/data
    networks:
      - supabase

volumes:
  caddy_data:

И простой Caddyfile:

yourdomain.com {
    reverse_proxy kong:8000
}

Где спотыкаются даже опытные

Собрал коллекцию граблей, на которые наступил сам и которые видел в issue Supabase (их баг-трекер на GitHub – кладезь боли).

  • Порты. Kong по умолчанию слушает 8000 (API) и 8443 (gRPC). Если на сервере уже крутится что-то на 80/443 – будут конфликты. Либо останови другие сервисы, либо перенастрой Kong.
  • JWT в Realtime. WebSocket требует токен доступа. Если клиент не авторизован – подписка упадет с 401. Всегда проверяй, что supabase.auth.getSession() возвращает валидную сессию перед подпиской.
  • Row Level Security. Без RLS анонимный ключ сможет читать любые данные. Покажи уважение к безопасности: добавь политики для каждой таблицы. Пример:
CREATE POLICY "Users can read own messages" ON public.messages
  FOR SELECT
  USING (auth.uid() = user_id);

CREATE POLICY "Users can insert own messages" ON public.messages
  FOR INSERT
  WITH CHECK (auth.uid() = user_id);
  • Обновления Supabase. У них релизный цикл – раз в месяц. Если обновляешь версию, читай CHANGELOG и не забывай мигрировать БД (через supabase migration up).
  • Масштабирование. Один Docker Compose потянет несколько тысяч пользователей. Если больше – придется разворачивать кластер PostgreSQL, ставить балансировщик для Kong и разносить сервисы по отдельным хостам. Но это уже тема для отдельной статьи.

Неочевидный совет на десерт

Не пытайтесь сделать из Supabase универсальное решение для всех проектов. Для простых CRUD-приложений (блог, форма обратной связи) лучше использовать PocketBase – он поднимается одним бинарником, не требует Docker, встроенная админка и realtime. А Supabase берите, когда нужна полноценная SQL база, сложные запросы и гранулярные права доступа.

И ещё – обязательно автоматизируйте деплой через CI/CD. Например, с помощью гибридного workflow Cloud Architect + Local Builder или через Roo Code для QA-тестов инфраструктуры. Будущее за тем, что инфраструктура как код (IaC) пишется нейросетями, а ты только контролируешь результат.

Собранный аналог Firebase – это не просто экономия денег. Это свобода. Ты можешь в любой момент мигрировать, можешь форкнуть любой компонент, можешь вшить кастомную логику без согласования с вендором. И когда проект вырастет до миллионов пользователей – твой стек останется с тобой, а не сгорит на счете за облачные сервисы.

💡
Попробуй запустить всё это на виртуалке за $5, а потом сравни с FireBase pricing calculator. Разница в десятки раз при том же функционале. Если не знаешь, с чего начать аренду сервера – вот ссылка на DigitalOcean с бесплатным кредитом на старте.

Подписаться на канал