После обновления 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 и код ошибки, логи без ключей и паролей, сведения о резервной копии. Объём работ и окно переключения согласуются заранее.
