VPS

Supabase на VPS: свой Postgres-бэкенд целиком

Развернуть self-hosted Supabase на VPS is*hosting: 11 контейнеров за 7 минут, без паузы проектов и без per-project счетов за вычислительную мощность.

Команда is*hosting 3 сент. 2026 6 мин
Supabase на VPS: свой Postgres-бэкенд целиком
Содержание

Любому пет-проекту рано или поздно нужен бэкенд: база, аутентификация, файловое хранилище и REST API, чтобы всё это связать.

Supabase Cloud даёт это из коробки, но на Free-плане потолок — два проекта, и любой из них ставится на паузу после недели простоя. А демо, приёмник вебхуков, API, от которого зависит скрипт должны оставаться доступными.

В этом гайде реальная установка self-hosted Supabase на VPS is*hosting тарифа Medium: от голого CentOS 9 x64 до одиннадцати контейнеров в статусе healthy меньше чем за семь минут.

Как работает Supabase

Supabase собирает Postgres вместе с сервисами, которые обычно навешивают на базу вручную.

  • Postgres — сама база.
  • Kong стоит впереди как API-шлюз.
  • PostgREST автоматически превращает схему Postgres в REST API.
  • GoTrue отвечает за аутентификацию и сессионные токены.
  • Realtime — Elixir-сервер, который транслирует изменения в базе подписанным клиентам.
  • Storage управляет загрузкой файлов, права раздаёт сам Postgres.
  • imgproxy делает трансформации картинок на лету.
  • Supavisor пулит подключения к Postgres, чтобы serverless-фронтенд не исчерпал лимит соединений базы.
  • Дополняют стек postgres-meta и Deno-based Edge Runtime.
  • Дашборд Studio связывает всё вместе.

Итого одиннадцать контейнеров в дефолтной установке.

Пара вещей по умолчанию выключена.

Logs и Analytics (Logflare плюс коллектор логов Vector) не запускаются, пока их не включить через sh run.sh config add logs — а включение заметно поднимает потребление памяти.

AI Assistant внутри Studio требует OPENAI_API_KEY в .env; из коробки ничего не подключено.

HTTPS тоже не настроен по умолчанию — нужен reverse proxy перед Kong.

Email-флоу для Auth (magic links, сброс пароля, подтверждение регистрации) не отправят ничего, пока в .env не прописан реальный SMTP-релей.

is*hosting по умолчанию блокирует исходящий SMTP на тарифах Lite и Start, но на Medium и выше он открыт. И ещё: self-hosted Supabase поддерживается сообществом — дежурной поддержки, которая примет вызов в 3 часа ночи, здесь нет.

Что понадобится до старта

  • Root-доступ по SSH к VPS (есть на всех тарифах is*hosting)
  • CentOS 9 x64, выбранный при оформлении — официальный установщик Supabase нативно поддерживает RHEL/CentOS
  • Около 10 минут на саму установку
  • Публичный IP VPS или домен, направленный на него, если HTTPS понадобится позже
  • SMTP-релей, если нужны email-флоу для Auth (на Medium и выше исходящий SMTP открыт по умолчанию)

Сценарий

RAM

CPU

is*hosting тариф

Разработка / тестирование (заявленный минимум самого Supabase)

4 GB

3 CPU

Medium — от $21.24/месяц

Продакшн или с включёнными Logs & Analytics

8 GB

4 CPU

Premium — от $31.99/месяц

Оба тарифа по умолчанию включают выделенный IPv4-адрес и еженедельные бэкапы VPS. Полные спеки на странице VPS-тарифов. Этот гайд использует тариф Medium.

Как установить Supabase на VPS

Как установить Supabase на VPS

Шаг 1: проверяем стартовое состояние

CentOS Stream 9 идёт с установленным firewalld, но не обязательно запущенным. Проверяем, прежде чем что-то трогать:

cat /etc/os-release
systemctl status firewalld

На Medium VPS, который использовался для этого гайда, ОС подтвердилась как ожидалось, а firewalld оказался неактивен:

PRETTY_NAME="CentOS Stream 9"
...
○ firewalld.service - firewalld - dynamic firewall daemon
     Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; preset: enabled)
     Active: inactive (dead)

Это важно для раздела про файрвол дальше: на этой машине правила firewalld трогать не нужно, и Docker ничего не отключал — оно и так было выключено.

Шаг 2: запускаем quick-start установщик

Supabase поставляет один скрипт, который ставит Docker, тянет конфиг Docker Compose и генерирует все секреты, нужные стеку. Запускаем от root:

curl -fsSL https://supabase.link/setup.sh | sh

Сначала он определяет ОС:

===> Detected OS: centos (rhel)

Затем ставит git, openssl, jq и ca-certificates, добавляет официальный CentOS-репозиторий Docker и ставит оттуда docker-ce, docker-ce-cli, containerd.io, docker-buildx-plugin и docker-compose-plugin.

Добавление репозитория Docker первым шагом на CentOS 9 важно: dnf install docker-ce из дефолтных репозиториев падает с ошибкой «No match for argument», потому что пакета там нет, пока не подключён репозиторий Docker. Скрипт делает этот шаг сам.

Шаг 3: задаём URL'ы

Скрипт спрашивает четыре значения в управляющем терминале. Для VPS без домена подставляем публичный IP сервера в первый запрос и принимаем дефолты для остальных:

SUPABASE_PUBLIC_URL (Studio + APIs) [http://localhost:8000]: http://<your-vps-ip>:8000
API_EXTERNAL_URL (Auth callbacks) [http://<your-vps-ip>:8000]: [Enter]
SITE_URL (default Auth redirect) [http://localhost:3000]: [Enter]
PROXY_DOMAIN (for nginx/caddy HTTPS proxy) [your-domain.example.com]: [Enter]

Скрипт попытается вывести email для Certbot из того, что введено как публичный URL. Если дать ему голый IP вместо домена, он выдаст что-то вроде [email protected], собранное из двух последних октетов.

На работу это не влияет — Certbot вообще не запускается, пока не включён override для HTTPS reverse-proxy, — но при первом появлении в консоли выглядит как ошибка.

Шаг 4: генерация секретов и pull образов

Скрипт автоматически прогоняет utils/generate-keys.sh и utils/add-new-auth-keys.sh, записывая свежие POSTGRES_PASSWORD, JWT_SECRET, DASHBOARD_PASSWORD и остальную пару API-ключей прямо в .env. Ни одно из этих значений не должно попасть в сохранённый лог или тикет в поддержку — скрипт печатает каждое в stdout по мере записи, так что если пишете свою сессию, редиректьте или вычищайте этот шаг.

Дальше он тянет все нужные образы:

===> Pulling Docker images
 Image postgrest/postgrest:v14.12 Pulling
 Image supabase/realtime:v2.102.3 Pulling
 Image kong/kong:3.9.1 Pulling
 ...

Одиннадцать сервисных образов плюс временный node:22-alpine, нужный только для генерации ключей. Это самая долгая часть установки.

Шаг 5: поднимаем стек

cd supabase-project
sh run.sh start

Это запускает docker compose up -d --wait, стартуя каждый контейнер и блокируясь, пока все не перейдут в статус healthy.

Postgres и Studio поднимаются первыми, потому что от одного или обоих зависит большинство остальных сервисов; Kong конкретно ждёт Studio, а storage и edge-functions заканчивают последними.

На этом Medium VPS весь прогон — от первой строки ===> Setup starting до последнего контейнера в статусе healthy — занял 6 минут 53 секунды:

Setup complete. Project ready at: /root/supabase-project

Next steps:
  cd /root/supabase-project
  sh run.sh config
  sh run.sh secrets
  sh run.sh start

Проверяем, что всё поднялось:

docker compose ps
NAME                             IMAGE                                    STATUS
supabase-db                      supabase/postgres:17.6.1.136             Up (healthy)
supabase-kong                    kong/kong:3.9.1                          Up (healthy)
supabase-studio                  supabase/studio:2026.07.07-sha-a6a04f2   Up (healthy)
supabase-auth                    supabase/gotrue:v2.189.0                 Up (healthy)
supabase-rest                    postgrest/postgrest:v14.12               Up (healthy)
supabase-storage                 supabase/storage-api:v1.60.4             Up (healthy)
supabase-meta                    supabase/postgres-meta:v0.96.6           Up (healthy)
supabase-pooler                  supabase/supavisor:2.9.5                 Up (healthy)
supabase-imgproxy                darthsim/imgproxy:v3.30.1                Up (healthy)
supabase-edge-functions          supabase/edge-runtime:v1.74.0            Up (healthy)
realtime-dev.supabase-realtime   supabase/realtime:v2.102.3               Up (healthy)

Все одиннадцать в статусе healthy — ровно те одиннадцать образов, что тянулись на шаге 4.

Файрвол

Все порты, которые открывает этот стек, приходят от Docker, а не от хостового сервиса. Kong публикует 8000 (HTTP) и 8443 (HTTPS, не используется, пока не настроен сертификат) прямо в интернет. Supavisor так же публикует 5432 (Postgres в session-режиме) и 6543 (пулинг в transaction-режиме). Проверили на этой машине через ss -tlnp:

LISTEN 0.0.0.0:5432   docker-proxy
LISTEN 0.0.0.0:8000   docker-proxy
LISTEN 0.0.0.0:8443   docker-proxy
LISTEN 0.0.0.0:6543   docker-proxy
LISTEN 0.0.0.0:22     sshd

iptables-правила Docker делают эти четыре порта доступными независимо от состояния firewalld, поэтому шага с firewall-cmd тут нет — firewalld остался неактивным и до, и после установки, хосту он не нужен.

Одно решение стоит принять самостоятельно: 5432 и 6543 по умолчанию открыты всему интернету, защищены только POSTGRES_PASSWORD. Если прямой внешний доступ к Postgres не нужен, эти два порта лучше ограничить или вовсе убрать маппинг портов у сервиса supavisor в docker-compose.yml.

Как пользоваться Supabase: Studio, Table Editor и API-ключи

Studio доступен за Kong по адресу http://<your-vps-ip>:8000, защищён HTTP Basic Auth через DASHBOARD_USERNAME и DASHBOARD_PASSWORD из .env.

После логина сразу открывается обзор проекта — многошагового онбординг-визарда прокликивать не нужно.

Как пользоваться Supabase

Панель Advisor на этом первом экране запускается автоматически и подсвечивает проблемы безопасности и производительности — неиспользуемые индексы, таблицы без row-level security и подобное, — без всякой настройки.

Table Editor и SQL Editor, оба в левом сайдбаре, закрывают две самые частые задачи первого дня: собрать схему визуально в Table Editor или выполнить сырой SQL в SQL Editor для всего, что не покрывает point-and-click.

Supabase: Studio, Table Editor и API-ключи

API Keys, под панелью Get Connected — там лежат anon-ключ (безопасен для клиентского кода) и service_role-ключ (только серверная сторона, полный доступ к базе). Каждый запрос через Kong к /rest/v1/, /auth/v1/ или /storage/v1/ требует один из этих двух ключей.

Как обновлять Supabase

Supabase выпускает новый стабильный релиз конфига Docker Compose примерно раз в месяц. Чтобы обновить один сервис, паттерн, который документирует сам проект: проверить теги образов на Docker Hub, поправить строку с версией в docker-compose.yml, затем спуллить и пересоздать только этот сервис:

sh run.sh pull
sh run.sh recreate studio

Обновление конфигурации всего стека менее автоматично, потому что quick-start скрипт делает sparse-clone директории docker/ один раз и не держит её под git локально. Повторный запуск setup.sh внутри существующей директории проекта ничего не делает — он находит существующие .env и docker-compose.yml и сразу выходит.

Чтобы подхватить новый релиз, нужно пере-клонировать директорию docker/ из репозитория Supabase в свежую временную папку и сравнить её с текущим docker-compose.yml, не трогая существующий .env.

is*hosting включает бесплатные еженедельные бэкапы VPS на всех тарифах, но полное восстановление VPS — слишком грубый способ откатить один сбойный контейнер. Точечный дамп Postgres восстанавливается быстрее и не трогает ничего больше на машине:

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

Что в итоге работает

От начала до конца установка заняла 6 минут 53 секунды на VPS Medium (3 CPU, 4 GB RAM, 40 GB SSD, $21.24/мес) — от первой строки вывода setup.sh до всех одиннадцати контейнеров в статусе healthy.

Стек занял примерно на 10 GB диска и 1.9 GB RAM из 3.8 GB доступных по free -h, оставляя около 2 GB запаса до момента, когда есть смысл переходить на Premium.

На этой одной машине работает: полноценная база Postgres 17, автогенерируемый REST API, JWT-аутентификация, файловое хранилище с трансформацией картинок, realtime-подписки и Deno-based edge-функции — всё за единым шлюзом Kong на порту 8000.

Для первого логина и начального харденинга VPS основы, которые этот гайд подразумевает, разобраны в гайде по настройке Linux VPS, а вся линейка тарифов — на странице VPS-тарифов.

VPS

Разверните весь стек Supabase — Postgres, Auth, Storage и edge-функции — на VPS с выделенным IPv4 и бесплатными еженедельными бэкапами.

Смотреть тарифы VPS

Supabase vs. Supabase Cloud: когда селф-хостинг оправдан

Free-план Supabase Cloud покрывает два проекта по 500 МБ хранилища базы на каждый, но ставит на паузу любой проект после недели простоя. Именно пауза, а не цена — реальный потолок Free-плана для всего, что должно работать постоянно.

Pro стоит $25 в месяц за организацию, с compute-кредитом $10, который покрывает один Micro-инстанс; каждый следующий проект в той же организации требует своего compute-аддона от ~$10 в месяц. Три always-on пет-проекта на Pro выходят примерно в $45 в месяц.

VPS is*hosting тарифа Medium держит столько self-hosted проектов, сколько влезет на машину, за $21.24 в месяц по фиксированной цене — без паузы и без per-project счётчика compute.

Компромисс в том, что патчить Postgres и следить за диском теперь ваша забота. Еженедельные бэкапы is*hosting покрывают весь VPS, а не point-in-time recovery для одной базы.

Для чувствительных к задержке приложений 40+ локаций is*hosting дают ещё один плюс — базу можно физически поставить рядом с пользователями, чего фиксированный AWS-регион в Supabase Cloud на уровне проекта не предложит.

GPU-серверы

Для ML, рендеринга и тяжелых вычислений.

Смотреть тарифы GPU