For AI agents: fetch the complete documentation index at /llms.txt, the full documentation corpus at /llms-full.txt, the agent skill at /skill.md, or this page as Markdown at /ru/docs/web/deploy-google-cloud.md (or send Accept: text/markdown).
Развёртывание в 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 перед экспериментами.
Создание аккаунта и установка CLI
1. Откройте 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: скачайте установщик для вашей операционной системы, завершите его, затем откройте новый терминал, чтобы команда gcloud стала доступна.
5. Выполните две команды ниже. Первая открывает браузер для авторизации CLI; вторая выбирает ваш проект — используйте ID проекта, показанный на дашборде консоли, он не всегда совпадает с именем.
Ожидается: gcloud config list показывает ваш аккаунт и проект. Если gcloud не распознаётся, переоткройте терминал или сначала завершите установку.
gcloud auth login
gcloud config set project YOUR_PROJECT_IDСоздание продакшен-базы данных
Путь для новичков — управляемая Postgres вне Google. На supabase.com: New project → выберите имя, пароль базы данных и регион → дождитесь провижининга → Project Settings → Database. Supabase предлагает две строки подключения: сессионный пулер / прямое подключение на порту 5432 и транзакционный пулер на порту 6543 — строка 5432 для миграций и долгоживущих клиентов, строка 6543 для serverless-приложения. На 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 для десктопной оболочки.
Чтобы продолжить настройку, прочитайте Чек-лист развёртывания.