> ## Documentation Index
> Fetch the complete documentation index at: https://supastack.dev/llms.txt
> Use this file to discover all available pages before exploring further.
> For the full documentation corpus in one file, fetch: https://supastack.dev/llms-full.txt

# Развёртывание в Google Cloud

Соберите Docker-образ комплекта на Cloud Build, запустите его на Cloud Run с управляемыми секретами и привяжите свой домен.

## Прохождение для начинающих

Предварительные условия: приложение работает локально, реальная база данных, доступная из интернета (Настройка базы данных), и аккаунты провайдеров для функций, которые вы поставляете. Нужен аккаунт Google; настройка биллинга попросит карту, хотя лёгкое использование остаётся в пределах бесплатного уровня.

Кратко о терминах: контейнерный образ — это упакованная копия вашего приложения, которую может запустить любой хост. Artifact Registry — хранилище Google для образов. Cloud Build собирает образ на машинах Google — локальный Docker не нужен. Cloud Run запускает образ как HTTPS-сервис и масштабирует его. Secret Manager хранит пароли и ключи. Ревизия — одна развёрнутая версия сервиса.

Что вы строите: проект Google Cloud, репозиторий Artifact Registry с вашим образом, сервис Cloud Run, обслуживающий приложение по HTTPS, секреты в Secret Manager и управляемую Postgres. Корневой `Dockerfile` комплекта уже производит автономный сервер Next.js, слушающий порт 8080 — именно то, что ожидает Cloud Run.

Честная заметка о стоимости: бесплатный уровень Cloud Run покрывает лёгкий трафик, но Cloud SQL — управляемая Postgres Google — не имеет бесплатного уровня. База данных Supabase или Neon на бесплатном уровне — самый дешёвый способ начать; это руководство использует именно этот путь. Рассмотрите добавление бюджетного оповещения в Billing → Budgets & alerts перед экспериментами.

[Настройте базу данных](https://supastack.dev/ru/docs/web/setup-database.md)

[Сначала создайте OAuth-аккаунты](https://supastack.dev/ru/docs/web/external-accounts.md)


## Создание аккаунта и установка CLI

1. Откройте [console.cloud.google.com](https://console.cloud.google.com), войдите своим аккаунтом Google и примите условия.

2. Привяжите биллинг, когда попросят: Billing → Link a billing account → Create billing account. Карта обязательна для активации аккаунта; пробный кредит покрывает первые эксперименты.

3. Нажмите выпадающий список проектов → New Project, назовите его и Create — или переиспользуйте проект, созданный для входа через Google; одного проекта достаточно.

4. Установите Google Cloud CLI с [cloud.google.com/sdk](https://cloud.google.com/sdk/docs/install): скачайте установщик для вашей операционной системы, завершите его, затем откройте новый терминал, чтобы команда `gcloud` стала доступна.

5. Выполните две команды ниже. Первая открывает браузер для авторизации CLI; вторая выбирает ваш проект — используйте ID проекта, показанный на дашборде консоли, он не всегда совпадает с именем.

Ожидается: `gcloud config list` показывает ваш аккаунт и проект. Если `gcloud` не распознаётся, переоткройте терминал или сначала завершите установку.

```
gcloud auth login
gcloud config set project YOUR_PROJECT_ID
```


## Создание продакшен-базы данных

Путь для новичков — управляемая Postgres вне Google. На [supabase.com](https://supabase.com): New project → выберите имя, пароль базы данных и регион → дождитесь провижининга → Project Settings → Database. Supabase предлагает две строки подключения: сессионный пулер / прямое подключение на порту 5432 и транзакционный пулер на порту 6543 — строка 5432 для миграций и долгоживущих клиентов, строка 6543 для serverless-приложения. На [neon.tech](https://neon.tech): New project → скопируйте показанную строку подключения. Подойдёт любая; сохраните парольную часть нетронутой.

Поместите прямую/сессионную строку в `DATABASE_URL` в корневом `.env` — инструмент миграций читает корневой файл и нуждается в сессионном подключении — и в `apps/web/.env.local` для локального dev-сервера. Затем выполните команду миграции один раз из корня репозитория, чтобы создать таблицы комплекта в новой базе данных. Секрет `DATABASE_URL`, который использует развёрнутое приложение, может быть пулированной строкой 6543.

Google-нативная альтернатива — Cloud SQL, управляемая Postgres внутри того же проекта. У неё нет бесплатного уровня, а подключения по приватному IP требуют VPC-коннектора — воспринимайте её как более позднее обновление, а не отправную точку.

```
# DATABASE_URL=<the direct/session Postgres string, port 5432> in .env + apps/web/.env.local, then:
corepack pnpm --filter @supastack/db db:migrate
```


## Включение сервисов и отправка образа

Выполните команды ниже из корня репозитория. Они включают четыре сервиса Google, которые использует это развёртывание, создают Docker-репозиторий в Artifact Registry и отправляют репозиторий в Cloud Build — который собирает корневой `Dockerfile` удалённо, поэтому Docker Desktop не требуется.

Замените `YOUR_PROJECT_ID` и выберите один регион — `us-central1` ниже — и переиспользуйте его для репозитория и сервиса. Ожидается: лог сборки стримится несколько минут и заканчивается `DONE` / `STATUS: SUCCESS`. Затем образ появляется в консоли в Artifact Registry → supastack → web.

```
gcloud services enable run.googleapis.com artifactregistry.googleapis.com cloudbuild.googleapis.com secretmanager.googleapis.com

gcloud artifacts repositories create supastack --repository-format=docker --location=us-central1

gcloud builds submit --tag us-central1-docker.pkg.dev/YOUR_PROJECT_ID/supastack/web:latest
```


## Хранение секретов в Secret Manager

Секреты никогда не должны попадать в `--set-env-vars` или в образ — оба хранятся открытым текстом и видны любому, кто может читать конфигурацию сервиса. Secret Manager держит их зашифрованными и внедряет во время выполнения.

1. В консоли откройте Security → Secret Manager → Create Secret.

2. Создайте `DATABASE_URL` с полной строкой подключения Postgres — пулированная serverless-строка подходит для приложения — `AUTH_SECRET` минимум с 32 случайными символами (`openssl rand -hex 32` генерирует их) и `CREDENTIAL_ENCRYPTION_KEY` с Base64-закодированным 32-байтовым ключом (`openssl rand -base64 32`); он шифрует ключи провайдеров, которые воркспейсы хранят в приложении.

3. Создайте по одному секрету на каждого включённого провайдера — например `STRIPE_SECRET_KEY` плюс `STRIPE_WEBHOOK_SECRET`, `RESEND_API_KEY`, `GOOGLE_CLIENT_SECRET`, `GITHUB_CLIENT_SECRET`. Несекретные настройки вроде `EMAIL_PROVIDER=resend` остаются обычными переменными окружения, а не секретами.

Когда сервис впервые ссылается на секрет, его runtime-сервисному аккаунту нужно разрешение на чтение — при подключении секретов через редактор сервиса консоли Google предлагает это разрешение автоматически; в CLI ошибка развёртывания называет отсутствующую роль Secret Manager, которую нужно выдать.

```
# Secrets to create in Secret Manager:
DATABASE_URL     # Postgres connection string — the pooled serverless string is fine
AUTH_SECRET      # openssl rand -hex 32
CREDENTIAL_ENCRYPTION_KEY   # openssl rand -base64 32

# plus one per enabled provider, e.g.:
STRIPE_SECRET_KEY
STRIPE_WEBHOOK_SECRET
RESEND_API_KEY
GOOGLE_CLIENT_SECRET
GITHUB_CLIENT_SECRET
```


## Развёртывание сервиса Cloud Run

Путь через консоль: Cloud Run → Create service → Deploy one revision from an existing container image → выберите отправленный образ `…/supastack/web:latest` → выберите тот же регион → в Authentication выберите Allow unauthenticated invocations (это публичное приложение) → Create.

Эквивалент на CLI ниже добавляет окружение тем же шагом. Конфигурация открытым текстом идёт в `--set-env-vars`; секреты указываются по имени в Secret Manager в `--set-secrets`. Добавьте флаги провайдеров (`EMAIL_PROVIDER`, `BILLING_PROVIDER`, `AI_PROVIDER`, `JOB_PROVIDER`) как обычные env-переменные рядом с `APP_URL`.

`APP_ENV=production` обязателен — без него приложение загружается в режиме `local`: валидация продакшен-конфигурации пропускается, префиксы защищённых cookie остаются выключенными, а dev-only страница `/mail-preview` остаётся публично доступной (утекая локальный почтовый ящик исходящих при `EMAIL_PROVIDER=local`). Продакшен затем требует ещё четыре значения при загрузке: `EXPO_PUBLIC_API_URL` — публичный https-URL, по которому мобильное приложение обращается к API — установите его в URL сервиса (тот же, что `APP_URL` для web-only развёртывания); `EXPO_PUBLIC_APP_SCHEME` — deep-link схема мобильного приложения — любое валидное значение вроде `supastack` работает, когда мобильное приложение не поставляется; `MOBILE_ALLOWED_ORIGINS` — список точных https-ориджинов через запятую, которым сервер доверяет — URL вашего приложения — правильное начало, а подстановочные знаки отклоняются; `CREDENTIAL_ENCRYPTION_KEY` шифрует сохранённые креденшелы провайдеров и остаётся в Secret Manager.

Cloud Run назначает URL `https://….run.app` при первом развёртывании, и `APP_URL` приложения должен равняться его реальному публичному URL для работы колбэков аутентификации и ссылок. Поэтому разверните один раз с плейсхолдером, скопируйте `*.run.app` URL со страницы сервиса, затем обновите сервис (консоль: Edit & deploy new revision или выполните команду заново), установив `APP_URL` — и соответствующие значения `EXPO_PUBLIC_API_URL` / `MOBILE_ALLOWED_ORIGINS` — на него. Порт контейнера остаётся 8080 — стандарт Cloud Run уже совпадает с `PORT` из `Dockerfile`.

```
gcloud run deploy supastack --image us-central1-docker.pkg.dev/YOUR_PROJECT_ID/supastack/web:latest --region us-central1 --allow-unauthenticated --set-env-vars "APP_ENV=production,APP_URL=https://YOUR_SERVICE_URL,EXPO_PUBLIC_API_URL=https://YOUR_SERVICE_URL,EXPO_PUBLIC_APP_SCHEME=supastack,MOBILE_ALLOWED_ORIGINS=https://YOUR_SERVICE_URL" --set-secrets "DATABASE_URL=DATABASE_URL:latest,AUTH_SECRET=AUTH_SECRET:latest,CREDENTIAL_ENCRYPTION_KEY=CREDENTIAL_ENCRYPTION_KEY:latest"
```


## Привязка собственного домена (необязательно)

Пропускайте это во время тестирования — URL `*.run.app` уже обслуживает HTTPS. Когда будете готовы: Cloud Run → ваш сервис → Custom Domains / Domain Mappings → Add mapping → выберите сервис и введите свой домен.

Подтвердите владение доменом, если попросят (Google проведёт вас через это), затем создайте DNS-записи, которые перечисляет экран маппинга, у вашего регистратора. Управляемый HTTPS-сертификат выдаётся автоматически после распространения записей — обычно минуты, до суток.

После того как домен обслуживает трафик, обновите `APP_URL` до `https://yourdomain.com` и зарегистрируйте соответствующие redirect URI OAuth (`https://yourdomain.com/api/auth/callback/…`) — руководства по входу объясняют где.


## Проверка развёртывания

Откройте `https://YOUR_SERVICE_URL/api/health` — ожидайте `ok`. Затем пройдите приложение от начала до конца: откройте URL, зарегистрируйтесь, запросите код по почте, подтвердите, что он достигает почтового ящика (это требует `EMAIL_PROVIDER=resend`, `RESEND_API_KEY` и проверенного отправителя — локальный адаптер никогда не достигает реальных ящиков), войдите и используйте одну включённую функцию.

Cloud Run → ваш сервис → Logs показывает вывод запросов и ошибок. Вкладка Revisions предлагает откат в один клик к предыдущей ревизии, если развёртывание пошло не так.

Мобильные и десктопные клиенты должны указывать на этот HTTPS-бэкенд: `EXPO_PUBLIC_API_URL` в `apps/mobile/.env.local` для Expo, `SUPASTACK_APP_URL` для десктопной оболочки.

[Создайте мобильные аккаунты](https://supastack.dev/ru/docs/mobile/external-accounts.md)

[Пройдите полный чек-лист развёртывания](https://supastack.dev/ru/docs/web/deployment.md)


Чтобы продолжить настройку, прочитайте [Чек-лист развёртывания](https://supastack.dev/ru/docs/web/deployment.md).


## Вперёд

[Чек-лист развёртывания](https://supastack.dev/ru/docs/web/deployment.md)
