Supabase на VPS: как восстановить HTTPS после перехода с Kong на Envoy

После обновления Supabase перестал открываться прежний HTTPS-адрес, а контейнеры продолжают работать? Если раньше TLS обслуживал сам Kong на порту 8443, проверьте смену шлюза: начиная с self-hosted-релиза 0.8.0 стандартная конфигурация использует Envoy с HTTP на порту 8000. Для публичного HTTPS нужен обратный прокси, например Caddy или Nginx, перед шлюзом.

Ниже — диагностика и восстановление для официальной установки Supabase через Docker Compose на VPS. Команды рассчитаны на ветку 0.8.x; файлы конфигурации сверены с релизом 0.8.2. Изменение не относится к Supabase Cloud и локальному запуску через Supabase CLI. Для сборок Coolify, Portainer и сторонних установщиков сначала выясните, какие Compose-файлы и переменные они действительно используют.

Что изменилось при переходе с Kong на Envoy

Релиз 0.8.0 от 11 августа 2026 года изменил шлюз по умолчанию. Это затрагивает не только порт, но и способ применения вашей конфигурации:

Раньше В стандартной конфигурации 0.8.x Что проверить
Сервис kong, контейнер supabase-kong Сервис api-gw, контейнер supabase-envoy Команды логирования, мониторинг и скрипты перезапуска.
HTTP 8000 и HTTPS 8443 у Kong HTTP 8000 у Envoy Кто теперь принимает HTTPS и выдаёт сертификат.
Правила в volumes/api/kong.yml Конфигурация в volumes/api/envoy/ Собственные маршруты, плагины и ограничения доступа автоматически не переносятся.
Порт задавался через KONG_HTTP_PORT Основной параметр — API_GW_HTTP_PORT, с резервным значением из KONG_HTTP_PORT Итоговую публикацию порта в Docker.

Сетевой псевдоним kong сохранён: адрес http://kong:8000 в общей Docker-сети может продолжать работать. Однако команда docker compose logs kong от этого не становится правильной — имя сервиса теперь api-gw.

Envoy умеет работать с TLS, но поставляемая конфигурация Supabase его не завершает. Добавление KONG_HTTPS_PORT=8443 в .env не создаст HTTPS-слушатель в Envoy.

Сначала определите, где обрывается запрос

Работайте из каталога установленного Supabase, где находятся docker-compose.yml и .env. Выполните:

docker compose version
sh run.sh config
docker compose config --services
docker compose ps
docker compose images
docker compose logs --since=15m --tail=100 api-gw

Проверьте, что запущен именно Envoy и загружены нужные дополнительные Compose-файлы. Версия развёртывания обычно записана в .supabase-version. Если файла нет, ориентируйтесь на происхождение конфигурации и теги образов; не присваивайте установке случайную версию.

С другого компьютера проверьте публичный адрес. В примерах замените api.example.com своим доменом:

curl -sS --connect-timeout 5 --max-time 15 -D - -o /dev/null \
  https://api.example.com/auth/v1/

Проверка выполняется без -k, то есть с проверкой сертификата. Если приложение всё ещё обращается к :8443, сначала повторите запрос к этому старому адресу, чтобы зафиксировать исходный сбой.

Результат Что он означает Следующее действие
Connection refused или тайм-аут Соединение не установлено: адрес, порт, доступность сервера или правила сети. Проверьте DNS, опубликованные порты Docker и входящие правила для 443.
Ошибка сертификата До TLS-сервера удалось дойти, но сертификат не прошёл проверку. Проверьте домен, срок действия, цепочку сертификата и журнал прокси.
Ошибка TLS при обращении к порту 8000 Возможно, HTTPS отправляется на обычный HTTP-порт Envoy. Между прокси и штатным Envoy используйте HTTP.
502 или 503 Ответил прокси или шлюз, но следующий сервис недоступен либо не готов. Проверьте адрес upstream, Docker-сеть и состояние соответствующего сервиса.
401 или 403 HTTP-ответ получен через HTTPS. Дальше нужно разбирать маршрут и авторизацию. Посмотрите тело ответа, заголовок WWW-Authenticate и логи шлюза.

Для сравнения проверьте Envoy из его сетевого пространства. Команда запускает временный контейнер curl и не требует публикации порта 8000 наружу:

docker run --rm --network container:supabase-envoy curlimages/curl \
  -sS --max-time 10 -D - http://127.0.0.1:8000/auth/v1/

Без API-ключа для этого защищённого маршрута ожидается 401 Unauthorized: штатный фильтр отклоняет запрос без ключа. Такой ответ подтверждает работу слушателя и фильтра шлюза, но ещё не доказывает исправность Auth и базы данных. Если внутри ответ есть, а снаружи соединение не устанавливается, переходите к настройке HTTPS-прокси.

Что сохранить перед изменениями

Зафиксируйте текущие Compose-файлы, .env, .supabase-version, теги образов, конфигурацию прокси и сертификаты. Копию с секретами храните вне публичных каталогов и с ограниченным доступом.

Перед обновлением всего стека нужна проверенная резервная копия PostgreSQL и файлов Storage либо соответствующего объектного хранилища. Скрипт update.sh сохраняет конфигурацию, но не делает резервную копию базы и объектов. Копирование каталога работающего PostgreSQL обычной файловой командой не заменяет корректный бэкап.

Для уже запущенного Envoy восстановление HTTPS можно выполнить без нового обновления образов. Особенно важно сохранить версию PostgreSQL: в более раннем self-hosted-релизе 0.6.0 по умолчанию появился PostgreSQL 17. Его нельзя запускать на существующем каталоге данных PostgreSQL 15 без отдельной миграции.

Не используйте reset.sh, удаление томов или docker compose down -v для исправления HTTPS. Эти действия затрагивают данные и не восстанавливают отсутствующий TLS-слушатель.

Если HTTPS раньше обслуживал Kong: добавьте Caddy

Этот вариант подходит, если Envoy и остальные сервисы уже работают на согласованной конфигурации 0.8.x, а порты 80 и 443 свободны. Если их занимает Nginx, Traefik или другой действующий прокси, используйте его по следующему разделу.

В комплекте должны быть docker-compose.caddy.yml и каталог volumes/proxy/caddy/ из того же релиза. Для дополнительных конфигураций используйте актуальный Docker Compose v2: применяемый в некоторых файлах тег !override требует версии 2.24.4 или новее. При ошибке разбора YAML сначала обновите Compose, затем повторите проверку.

Проверьте DNS и занятые порты:

dig +short A api.example.com
dig +short AAAA api.example.com
sudo ss -ltnp '( sport = :80 or sport = :443 )'

Для прямого доступа к VPS запись A должна вести на его IPv4. Если существует AAAA, IPv6 тоже должен вести на этот сервер и обслуживать домен. Неверная AAAA может мешать выпуску сертификата даже при правильной A. Исправьте её или удалите, если IPv6 для домена не используется. Входящие TCP-порты 80 и 443 должны быть доступны в сетевом экране VPS и у провайдера.

В существующем .env измените только относящиеся к адресам значения, сохранив пароли и ключи:

PROXY_DOMAIN=api.example.com
SUPABASE_PUBLIC_URL=https://api.example.com
API_EXTERNAL_URL=https://api.example.com/auth/v1
SITE_URL=https://app.example.com

PROXY_DOMAIN — домен без протокола и пути; он нужен и штатному Caddy. SITE_URL — адрес вашего приложения, куда пользователь попадает после входа. Это может быть другой домен.

Подключите конфигурацию и проверьте её:

sh run.sh config add caddy
docker compose config --quiet

Выполняйте команды по очереди. При ошибках или предупреждениях о незаданных переменных сначала исправьте конфигурацию. Одновременно подключать штатные Caddy и Nginx не нужно: они претендуют на одни и те же порты.

В окно обслуживания пересоздайте сервисы, которым передаются изменённые публичные адреса, и запустите Caddy. Следующий пример рассчитан на штатный состав сервисов 0.8.x и неизменённые версии образов:

sh run.sh recreate api-gw auth storage studio functions
sh run.sh start caddy
docker compose ps
docker compose logs --tail=100 caddy

Эти операции прервут текущие соединения соответствующих сервисов. Обычный restart не перечитывает новое окружение Compose. После запуска повторите внешний curl-запрос: сертификат должен проверяться, а ответ на защищённый маршрут без ключа — доходить до шлюза.

Штатный Caddy самостоятельно получает и продлевает сертификат. Его данные сохраняются в томе caddy_data; сохраните этот том при обслуживании. Если сертификат не выпускается, в журнале ищите ошибку проверки домена, недоступности порта или ограничения центра сертификации, затем исправляйте указанную причину.

Штатный Caddy override также снимает публикацию порта шлюза на хосте. Поэтому отсутствие доступного снаружи :8000 после его подключения ожидаемо: API остаётся доступным через HTTPS.

Если Nginx или другой прокси уже есть

Проверьте, куда он направлял запросы до обновления. Адрес https://supabase-kong:8443 после смены контейнера и удаления TLS-слушателя работать не будет. Выберите upstream по расположению прокси:

Где работает прокси Адрес шлюза Условие
В общей Docker-сети Supabase http://api-gw:8000 Сервис доступен по Docker DNS; публикация 8000 на хосте не нужна.
Непосредственно на том же VPS http://127.0.0.1:8000 Порт шлюза опубликован на loopback хоста.
В другом контейнере или на другой машине Адрес по общей сети или приватному соединению 127.0.0.1 внутри контейнера обозначает сам контейнер, а не VPS.

Для прокси на самом VPS стандартный Compose 0.8.x позволяет задать API_GW_HTTP_PORT=127.0.0.1:8000. После пересоздания api-gw команда docker compose port api-gw 8000 должна показать привязку к loopback. Не открывайте 8000 всему интернету только ради связи между локальным прокси и шлюзом.

Сохраните исходные пути /auth/v1/, /rest/v1/, /storage/v1/ и остальных используемых API. Ошибочная перезапись префикса может превратить исправный HTTPS в 404. Для Nginx сверяйте API-маршруты, Host и заголовки X-Forwarded-* со штатным шаблоном.

Realtime дополнительно требует передачи WebSocket Upgrade. В его location должны присутствовать:

proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

Это фрагмент существующего маршрута, а не полная конфигурация Nginx. После изменений проверьте синтаксис и перезагрузите конфигурацию прокси. Для Nginx, установленного как системный сервис:

sudo nginx -t
sudo systemctl reload nginx

Вторую команду выполняйте только после успешной первой. В контейнерной установке используйте проверку и reload внутри соответствующего контейнера. Это также важно, если Nginx сохранил старый IP контейнера шлюза.

HTTPS заработал, но вход или загрузка файлов всё ещё ломаются

Публичный адрес должен быть HTTPS, а внутренний SUPABASE_URL=http://api-gw:8000 в сервисах может оставаться HTTP. Замена всех внутренних URL на публичный домен создаёт лишнюю зависимость от внешнего прокси и не требуется для этой схемы.

Не работает OAuth. В ветке 0.8.x API_EXTERNAL_URL уже содержит /auth/v1 — это отдельное изменение конфигурации Auth. Поэтому callback для внешнего провайдера выглядит так:

https://api.example.com/auth/v1/callback

Сравните этот адрес с зарегистрированным у провайдера. Проверьте фактические значения в работающем Auth:

docker compose exec auth printenv API_EXTERNAL_URL GOTRUE_SITE_URL

Первое должно указывать на публичный Auth URL, второе — на ваше приложение. Для дополнительных разрешённых адресов возврата проверьте ADDITIONAL_REDIRECT_URLS. После изменения окружения пересоздайте Auth и повторите полный вход. Не добавляйте /auth/v1 второй раз в старый вручную заданный callback.

Маленькие файлы загружаются, большие — нет. В обсуждении №40686 пользователи старой конфигурации Kong видели именно это: браузер получал адрес продолжения загрузки с HTTP и внутренним портом 8000. Первоначальные обходные решения зависели от схемы прокси; позднее разработчик указал на добавленный STORAGE_PUBLIC_URL.

В актуальном Compose этот параметр сервиса Storage получает значение из SUPABASE_PUBLIC_URL. Проверьте его:

docker compose exec storage printenv STORAGE_PUBLIC_URL

Ожидается https://api.example.com. Затем откройте Network в инструментах браузера и повторите возобновляемую загрузку тестового файла. В ответе на начальный POST проверьте Location: он должен вести на публичный HTTPS-домен с правильным внешним портом и путём. Последующие PATCH-запросы должны успешно отправлять части файла. Если возвращается внутренний HTTP-адрес, сверяйте окружение Storage и маршрут прокси; старые параметры Kong в Envoy не действуют.

REST API отвечает 403. С self-hosted-релиза 0.7.0 доступ к OpenAPI-описанию по /rest/v1/ через anon или publishable key ограничен. Это не означает, что сломан доступ к таблицам. Проверьте обычное разрешённое чтение через приложение или /rest/v1/имя_таблицы с его штатными ключами и пользовательской сессией. Не подставляйте service_role или secret key в браузер ради прохождения теста.

На отдельном пути появляется Basic Auth. Уточните назначение маршрута, прежде чем менять прокси. В обсуждении №50808 автор считал ошибкой поведение /pg/ и /api/mcp, но после объяснения разработчика подтвердил, что это внутренние маршруты. Переносить наружу все пути шлюза не требуется.

При этом для /.well-known/oauth-authorization-server действительно исправлялась маршрутизация: изменение вошло в 0.8.2. Если используете OAuth discovery и получаете Basic Auth на этом адресе, сравните файлы Caddy или Nginx с этим релизом — одного обновления образов недостаточно.

Как временно вернуться на Kong

В проверенном релизе 0.8.2 Kong доступен через docker-compose.kong.yml. Он может понадобиться, если рабочая система зависит от собственных плагинов, маршрутов или встроенного HTTPS Kong, которые ещё не перенесены. В changelog уже объявлено будущее удаление этого дополнительного файла; используйте его как временный вариант совместимости.

Сначала перенесите в Kong override нужные настройки из сохранённой конфигурации. Для прежнего HTTPS это в том числе подключение действующих сертификата и ключа, KONG_SSL_CERT, KONG_SSL_CERT_KEY и публикация нужного порта. Одно включение Kong не восстановит ваши старые сертификаты и пользовательские правила.

sh run.sh config add kong

Перед применением проверьте порядок COMPOSE_FILE. Если используете штатный Caddy или Nginx, его файл должен идти после Kong, чтобы снова убрать ненужные внешние порты шлюза. Например: docker-compose.yml:docker-compose.kong.yml:docker-compose.caddy.yml. После проверки:

docker compose config --quiet
sh run.sh recreate api-gw
docker compose ps
docker compose logs --tail=100 api-gw

При ошибке проверки конфигурации не переходите к пересозданию.

Сервис останется api-gw, а контейнер станет supabase-kong. После переключения проверьте внешний HTTPS и операции приложения. При необходимости отката самого этого изменения верните сохранённый список Compose-файлов и настройки, затем пересоздайте только шлюз. Откат PostgreSQL для смены шлюза не нужен.

Если вместе со шлюзом уже обновили другие сервисы и произошли миграции базы, полный возврат к старой версии требует отдельного плана восстановления. Запуск старых образов поверх изменённых данных не гарантирует корректный откат.

Как убедиться, что приложение восстановлено

Проверяйте адрес из внешней сети и выполняйте операции от обычного пользователя приложения:

  • Сертификат проходит проверку без отключения TLS-проверок; Studio доступен с предусмотренной авторизацией.
  • Вход по используемому способу завершается возвратом в приложение, сессия работает после обновления страницы.
  • Разрешённое чтение и запись тестовых данных через REST API проходят с обычными правами пользователя.
  • Небольшой файл и файл с возобновляемой загрузкой загружаются и скачиваются; в URL нет внутреннего адреса или HTTP.
  • Realtime устанавливает WebSocket-соединение и доставляет тестовое событие; используемые Edge Functions возвращают ожидаемый результат.

В браузере проверьте соединение wss:// в Network → WS: при обычном WebSocket Upgrade ожидается статус 101, затем успешная подписка и событие. Само открытие сокета ещё не подтверждает правильность канала и разрешений. После проверки удалите созданные тестовые записи и файлы.

Для следующего обновления используйте официальный порядок обновления: установите исходную версию, сохраните данные, предварительно выполните sh update.sh --dry-run, разберите несовместимые изменения и конфликты. Храните Compose, конфигурацию шлюза и прокси как согласованный комплект выбранного релиза.

Если нужна помощь с диагностикой или переносом конфигурации, задачу можно обсудить в рамках администрирования серверов QCKL. Для оценки подготовьте версии до и после обновления, схему прокси, конкретный URL и код ошибки, логи без ключей и паролей, сведения о резервной копии. Объём работ и окно переключения согласуются заранее.

  • 0 Uživatelům pomohlo
Byla tato odpověď nápomocná?

Související články

VGA монитор для серверов в 2026: зачем он всё ещё нужен в дата-центре и что даёт Sceptre 24″ Prime E248W-19203R

VGA давно пропал из мира ноутбуков, мини-ПК и рабочих станций, но в серверной реальности он...

10GbE в 2026 выходит на переломный момент: почему 10Gbase-T становится нормой для серверов

10GbE в 2026 перестал быть «дорогой игрушкой» для энтузиастов и крупных дата-центров. Он быстро...

Сетевая карта 2.5GbE PCIe в 2026: mini-обзор BrosTrend и зачем апгрейд

Если вы всё ещё живёте на 1GbE, то знакомы с ощущением «железо норм, а сеть душит». Копирование...

1, 10, 40 или 100 Gb/s: какой порт нужен серверу под реальную задачу

Скорость порта у выделенного сервера часто выбирают неправильно. Клиент видит 10 Gb/s или 100...

Dedicated server для streaming, CDN и раздачи файлов: почему важны порт, peering и трафик

Dedicated server для streaming, CDN и раздачи файлов выбирают не так, как обычный сервер для...