Kubernetes-стейджинг на ноутбуке: Auth0 и Stripe

Ваш ноутбук — это ваша среда стейджинга. Буквально.

В этой статье мы пройдём путь от локального исходного кода поли­глот­ного микросервисного приложения до продакшн-кластера Kubernetes с TLS, Auth0-авторизацией и Stripe-вебхуками — всё работает сквозь, end-to-end. Без облачного стейджинга. Без Docker Compose. Без ручного написания YAML.

Приложение называется oauth-example — демо из четырёх сервисов, которое можно склонировать и повторять шаг за шагом.

Что мы строим

Микросервисное приложение с реальными внешними интеграциями:

Browser → UI (React/nginx)
          ↓
       Gateway (Go) ← Auth0 OIDC login/callback
          ↓          ← Stripe webhook receiver
     ┌────┴────┐
   Orders   Inventory
  (Python)  (Node.js)
  Postgres   MongoDB
  Redis ←──── shared event queue
  • UI — React-дашборд, раздаваемый через nginx

  • Gateway — обратный прокси на Go с Auth0 OIDC и верификацией Stripe-вебхуков

  • Orders — Python FastAPI с Postgres, публикует события в Redis

  • Inventory — Node.js Fastify с MongoDB, потребляет события заказов из Redis

Самое интересное: Auth0 требует публичный HTTPS-адрес для callback-редиректа, а Stripe — публичный HTTPS-эндпоинт для вебхуков. Именно это делает локальную разработку мучительной — и именно это решает kindling.

Шаг 1: инициализация кластера

brew install kindlingdev/tap/kindling
kindling init

Всё. У вас теперь есть Kind-кластер с оператором, встроенным container registry и Traefik ingress-контроллером. Полностью локально, полностью одноразово.

Шаг 2: регистрация CI-раннера

kindling runners -u <github-user> -r oauth-test -t <github-pat>

Команда разворачивает self-hosted GitHub Actions runner внутри вашего Kind-кластера. Когда вы пушите код, CI запускается локально — сборки выполняются через Kaniko, образы попадают во встроенный registry по адресу localhost:5001. Никакого DockerHub. Никакого ECR. Никакого ожидания удалённого CI.

Шаг 3: генерация CI-воркфлоу

kindling generate -k <api-key> -r .

ИИ Kindling анализирует репозиторий — находит четыре сервиса, определяет языки и фреймворки, читает Dockerfile’ы, обнаруживает манифесты деплоя — и генерирует GitHub Actions воркфлоу, который собирает и деплоит всё. Сгенерированный воркфлоу берёт на себя:

  • сборку каждого сервиса через Kaniko

  • пуш образов во встроенный registry

  • применение DSE-манифестов (DevStagingEnvironment)

  • связывание сервисов между собой через переменные окружения

  • подготовку зависимостей (Postgres, Redis, MongoDB)

Этот воркфлоу не надо писать вручную и поддерживать. Запушили код — он запустится сам.

Шаг 4: создание аккаунтов Auth0 и Stripe, настройка учётных данных

Манифест деплоя шлюза ссылается на секреты через secretKeyRef — Kubernetes не запустит под, если они отсутствуют. Создайте аккаунты во внешних сервисах и задайте учётные данные до первого деплоя.

Создание приложения в Auth0

  • Зарегистрируйтесь или войдите на auth0.com

  • В Auth0 Dashboard перейдите в Applications → Create Application

  • Назовите приложение, например oauth-example-dev, выберите Regular Web Application и нажмите Create

  • На вкладке Settings скопируйте три значения — они понадобятся чуть позже:

    • Domain (например, your-tenant.us.auth0.com)

    • Client ID

    • Client Secret

Callback URL’ы пока не настраивайте — для этого нужен публичный tunnel URL, который появится после деплоя.

Создание Stripe webhook endpoint

  • Зарегистрируйтесь или войдите на dashboard.stripe.com

  • Убедитесь, что включён Test mode (переключатель в правом верхнем углу)

  • Откройте вкладку Webhooks в Workbench

Сам webhook endpoint вы создадите позже, когда получите tunnel URL. Пока просто скопируйте Stripe Secret Key в разделе Developers → API keys — он начинается с sk_test_.

Задание предварительных секретов

Задайте учётные данные, чтобы поды могли стартовать:

kindling secrets set AUTH0_DOMAIN your-tenant.auth0.com
kindling secrets set AUTH0_CLIENT_ID your-client-id
kindling secrets set AUTH0_CLIENT_SECRET your-client-secret
kindling secrets set SESSION_SECRET $(openssl rand -hex 32)
kindling secrets set STRIPE_SECRET_KEY sk_test_your_stripe_secret_key
kindling secrets set STRIPE_WEBHOOK_SECRET placeholder
kindling secrets set PUBLIC_URL http://localhost

STRIPE_WEBHOOK_SECRET и PUBLIC_URL — заглушки: шлюз запустится без них, но не упадёт. Настоящие значения вы зададите после запуска тоннеля.

Обратите внимание: STRIPE_SECRET_KEY (начинается с sk_test_) — это ваш Stripe API key из раздела Developers → API keys. Он отличается от STRIPE_WEBHOOK_SECRET (начинается с whsec_) — это signing secret для вебхука, который вы получите после создания webhook endpoint на шаге 6.

DSE-манифесты ссылаются на эти значения через secretKeyRef — оператор передаёт их в под шлюза как переменные окружения. Никаких секретов в YAML. Никаких секретов в .env-файлах. Никаких секретов в git.

Шаг 5: пуш и деплой

git add -A && git commit -m "initial deploy"
git push origin main

Раннер подхватывает пуш, собирает все четыре образа, оператор деплоит их. Проверьте статус:

kindling status
▸ Dev Staging Environments
📦 jeff-vincent-gateway     9090   jeff-vincent-gateway.localhost
📦 jeff-vincent-inventory   3000   jeff-vincent-inventory.localhost
📦 jeff-vincent-orders      5000   jeff-vincent-orders.localhost
📦 jeff-vincent-ui          80     jeff-vincent-ui.localhost
▸ All Deployments
jeff-vincent-gateway              1/1
jeff-vincent-inventory            1/1
jeff-vincent-inventory-mongodb    1/1
jeff-vincent-orders               1/1
jeff-vincent-orders-postgres      1/1
jeff-vincent-orders-redis         1/1
jeff-vincent-ui                   1/1

Четыре сервиса, три базы данных — всё запущено. Откройте http://jeff-vincent-ui.localhost, и дашборд будет живым. Auth0 и Stripe пока не подключены — это следующий шаг.

Шаг 6: запуск тоннеля и настройка OAuth + вебхуков

Теперь, когда сервисы запущены, нужен публичный HTTPS URL для Auth0 callback’ов и Stripe-вебхуков. Kindling использует бесплатные quick tunnels от Cloudflare. Создайте бесплатный аккаунт Cloudflare, перейдите в Protect and Connect > Networking > Tunnels и создайте тоннель. Затем запустите Cloudflare daemon на локальной машине:

brew install cloudflared &&
sudo cloudflared service install <your-token>
kindling expose

Вы получите публичный URL вида https://verb-noun-adj-noun.trycloudflare.com. Скопируйте его.

Тоннель работает в фоне. URL меняется при каждом перезапуске, поэтому callback URL’ы в Auth0 и Stripe нужно обновлять, когда требуется тестировать внешние интеграции. Для большинства повседневных задач тоннель не нужен вовсе.

Настройка callback URL’ов в Auth0

Вернитесь в настройки Auth0-приложения и задайте следующие значения:

Auth0 Dashboard → Applications → oauth-example-dev → Settings → Application URIs

Allowed Callback URLs  https://<your-tunnel-url>/auth/callback
Allowed Logout URLs    https://<your-tunnel-url>
Allowed Web Origins    https://<your-tunnel-url>

Замените <your-tunnel-url> на URL из kindling expose (например, verb-noun-adj-noun.trycloudflare.com).

Нажмите Save Changes.

Callback URL — это адрес, на который Auth0 перенаправляет пользователя после аутентификации. Он должен точно совпадать с тем, что шлюз передаёт в OIDC authorization request. Путь /auth/callback обрабатывается OIDC callback handler’ом шлюза: он обменивает authorization code на токены и устанавливает session cookie.

OIDC-интеграция шлюза использует Universal Login от Auth0 — кастомная страница входа не нужна. Подробнее — в руководстве по началу работы с Auth0.

Создание Stripe webhook endpoint

Теперь создайте webhook endpoint в Stripe, указав tunnel URL:

  • В Workbench → Webhooks нажмите Create an event destination

  • Пройдите через мастер создания:

    Events from      Your account
    API version      Выберите версию по умолчанию (или последнюю)
    Events           checkout.session.completed  payment_intent.succeeded
  • Нажмите Continue, затем выберите Webhook endpoint как тип назначения

  • Нажмите Continue и задайте:

    Endpoint URL     https://<your-tunnel-url>/webhooks/stripe
  • Нажмите Create destination

  • Выберите созданный endpoint и нажмите Click to reveal, чтобы скопировать signing secret (whsec_…​)

Webhook URL — адрес, на который Stripe отправляет POST-запросы с данными событий. Шлюз получает запрос на /webhooks/stripe, верифицирует заголовок Stripe-Signature по signing secret через HMAC-SHA256 и пересылает валидные payload’ы в сервис orders. Неверифицированные запросы отклоняются с кодом 400. Подробнее о верификации подписей и типах событий — в документации Stripe по вебхукам.

Задание настоящих PUBLIC_URL и webhook secret

Теперь обновите значения-заглушки на реальные:

kindling secrets set PUBLIC_URL https://<your-tunnel-url>
kindling secrets set STRIPE_WEBHOOK_SECRET whsec_your_signing_secret

Под шлюза перезапустится автоматически и подхватит новые значения. Убедитесь через kindling status, что шлюз снова в состоянии 1/1.

Шаг 7: внутренний цикл разработки

Теперь вы разрабатываете. Вы меняете код и хотите видеть изменения сразу. Проверьте статус:

kindling status
▸ Dev Staging Environments
📦 jeff-vincent-gateway     9090   jeff-vincent-gateway.localhost
📦 jeff-vincent-inventory   3000   jeff-vincent-inventory.localhost
📦 jeff-vincent-orders      5000   jeff-vincent-orders.localhost
📦 jeff-vincent-ui          80     jeff-vincent-ui.localhost
▸ All Deployments
jeff-vincent-gateway              1/1
jeff-vincent-inventory            1/1
jeff-vincent-inventory-mongodb    1/1
jeff-vincent-orders               1/1
jeff-vincent-orders-postgres      1/1
jeff-vincent-orders-redis         1/1
jeff-vincent-ui                   1/1

Четыре сервиса, три базы данных — всё запущено. Откройте http://jeff-vincent-ui.localhost, и дашборд будет живым.

Шаг 6: внутренний цикл разработки

Вы разрабатываете. Код меняется — изменения нужны немедленно.

kindling sync -d jeff-vincent-gateway

Изменения файлов синхронизируются напрямую в работающий под — без пересборки образа и повторного деплоя. Для Go-сервисов бинарник перекомпилируется прямо внутри контейнера. Для Python и Node.js изменение файла автоматически запускает перезагрузку.

Нужно отлаживать код пошагово? Запустите debug из корня проекта:

cd /path/to/oauth-test
kindling debug -d jeff-vincent-orders --port 5678
Примечание
kindling debug нужно запускать из корня проекта — команде требуется доступ к дереву исходников для настройки сеанса отладки.

Подключите отладчик IDE к localhost:5678 и расставляйте точки останова в сервисе orders прямо во время его работы внутри кластера — с живыми Postgres и Redis.

Шаг 8: тестирование OAuth и Stripe

Когда сервисы запущены и секреты настроены, проверьте, что всё связано:

curl http://jeff-vincent-gateway.localhost/auth/status
# {"auth0_configured":true,"callback_url":"https://<your-tunnel-url>/auth/callback"}
curl http://jeff-vincent-gateway.localhost/stripe/status
# {"stripe_webhook_configured":true,"webhook_url":"https://<your-tunnel-url>/webhooks/stripe"}

Откройте tunnel URL в браузере (например, https://verb-noun-adj-noun.trycloudflare.com), нажмите Login — загрузится универсальная страница входа Auth0, вы аутентифицируетесь, и callback перенаправит обратно на tunnel URL. Запрос проходит по цепочке: Cloudflare → localhost:80 → Traefik → ingress шлюза, который обменивает код на токены и устанавливает session cookie. Полный OIDC flow — локально.

Для Stripe вызовите тестовое событие из Stripe Dashboard или воспользуйтесь Stripe CLI. Событие поступает на шлюз по tunnel URL тем же путём — Cloudflare → localhost:80 → Traefik → шлюз — подпись верифицируется по signing secret, payload пересылается в сервис orders, который обновляет статус заказа в Postgres.

Шаг 9: деплой в продакшн

Dev-окружение проверено. Auth0 callbacks работают. Stripe-вебхуки приходят. Пора запускать в продакшн.

kindling dashboard --prod-context <your-prod-cluster-context>

Продакшн-дашборд подключается к реальному кластеру. Дальше:

  • Snapshot — оператор фиксирует точные теги образов, переменные окружения и конфигурацию зависимостей

  • Deploy — образы перетегируются и пушатся в продакшн registry, манифесты применяются

  • TLS — cert-manager автоматически выпускает сертификаты Let’s Encrypt

Примечание
После деплоя нужно обновить A-запись DNS вашего домена, указав IP нового балансировщика нагрузки (найдите его командой kubectl get svc traefik -n traefik). Распространение DNS может занять несколько минут — в это время браузер может показывать предупреждение «Ваше подключение не является приватным» (ERR_CERT_AUTHORITY_INVALID). Это нормально. Займитесь чем-нибудь другим — и не сидите, судорожно обновляя страницу. Когда DNS распространится, cert-manager завершит ACME challenge и сертификат Let’s Encrypt будет выпущен автоматически.

В продакшне замените секреты на продакшн-значения:

  • AUTH0_DOMAIN → ваш продакшн tenant в Auth0

  • AUTH0_CLIENT_ID / AUTH0_CLIENT_SECRET → credentials продакшн-приложения

  • STRIPE_SECRET_KEY → продакшн API key Stripe (начинается с sk_live_)

  • STRIPE_WEBHOOK_SECRET → продакшн signing secret вебхука (начинается с whsec_)

  • PUBLIC_URL → ваш продакшн домен

Тот же код, та же архитектура, та же модель деплоя. Меняются только секреты и домен.

Что произошло

Проследим весь путь:

  • Исходный код на ноутбуке

  • kindling init — локальный Kind-кластер с оператором, registry и ingress

  • kindling generate — CI-воркфлоу, сгенерированный ИИ

  • kindling secrets set — Auth0/Stripe credentials заданы, поды могут стартовать

  • git push — локальный раннер собирает образы через Kaniko, деплоит через оператор

  • kindling expose + kindling secrets set — тоннель запущен, callback URL’ы в Auth0/Stripe настроены, PUBLIC_URL обновлён

  • kindling sync — живые изменения кода без пересборки

  • Тест OAuth + Stripe — сквозная проверка callback flow’ов

  • Деплой в продакшн — те же образы, та же конфигурация, реальный кластер с TLS

Никакого Docker Compose. Никаких Helm-чартов. Никакого Terraform. Никаких расходов на облачный стейджинг. Никаких расхождений в духе «у меня работает» между dev и prod.

Вся среда стейджинга живёт на ноутбуке. Если здесь работает — будет работать в продакшне: тот же Kubernetes, те же контейнерные образы, та же сетевая модель.

Попробуйте сами

brew install kindlingdev/tap/kindling
git clone https://github.com/kindling-sh/oauth-example
cd oauth-example
kindling init
kindling runners -u <user> -r oauth-example -t <pat>
kindling generate -k <api-key> -r .
# Задаём credentials, чтобы поды могли стартовать
kindling secrets set AUTH0_DOMAIN <your-domain>
kindling secrets set AUTH0_CLIENT_ID <your-id>
kindling secrets set AUTH0_CLIENT_SECRET <your-secret>
kindling secrets set SESSION_SECRET $(openssl rand -hex 32)
kindling secrets set STRIPE_SECRET_KEY <sk_test_...>
kindling secrets set STRIPE_WEBHOOK_SECRET placeholder
kindling secrets set PUBLIC_URL http://localhost
# Деплоим
git push origin main
# Запускаем тоннель, настраиваем callback URL'ы в Auth0/Stripe, обновляем секреты
kindling expose
# скопируйте tunnel URL, добавьте его в дашборды Auth0 и Stripe
kindling secrets set PUBLIC_URL <your-tunnel-url>
kindling secrets set STRIPE_WEBHOOK_SECRET <whsec_...>

Ваш ноутбук — это ваша среда стейджинга. Начинайте строить.

Логотип сообщества DEV
© 2026 meganuke