Как развернуть Docker-контейнер в Google Cloud Run
Практика4 минРедакция Innovialabs
Коротко
Соберите образ, который слушает порт из переменной PORT, загрузите его в Artifact Registry и выполните gcloud run deploy — Cloud Run сам запустит контейнеры, выдаст HTTPS-адрес и будет масштабировать их от нуля, а платить вы будете в основном за время обработки запросов.
Коротко: как это работает
Cloud Run — serverless-платформа Google Cloud для контейнеров. Вы отдаёте ей Docker-образ, а она запускает его, выдаёт HTTPS-адрес, масштабирует копии под нагрузку и гасит их до нуля, когда запросов нет.
Путь от кода до работающего сервиса:
- Dockerfile, в котором приложение слушает порт из переменной
PORT. - Сборка образа и загрузка в Artifact Registry.
- Команда
gcloud run deploy. - Настройка переменных, секретов, масштабирования и домена.
Шаг 1. Подготовьте Dockerfile
Главное требование — приложение должно слушать порт из переменной окружения PORT (по умолчанию Cloud Run передаёт 8080) на адресе 0.0.0.0. Пример для Node.js:
FROM node:20-slim
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
ENV NODE_ENV=production
CMD ["node", "server.js"]
Советы:
- держите образ компактным — это ускоряет холодный старт;
- не храните состояние на локальном диске: файловая система контейнера временная, а копий может быть несколько;
- пишите логи в stdout и stderr — они автоматически попадут в Cloud Logging.
Шаг 2. Соберите образ и загрузите в Artifact Registry
Включите нужные API и создайте репозиторий:
gcloud services enable run.googleapis.com artifactregistry.googleapis.com secretmanager.googleapis.com
gcloud artifacts repositories create apps \
--repository-format=docker --location=europe-west1
gcloud auth configure-docker europe-west1-docker.pkg.dev
Соберите и отправьте образ:
docker build --platform linux/amd64 \
-t europe-west1-docker.pkg.dev/PROJECT_ID/apps/api:v1 .
docker push europe-west1-docker.pkg.dev/PROJECT_ID/apps/api:v1
Флаг --platform linux/amd64 важен, если вы собираете на Mac с процессором ARM. Если Docker локально нет, образ можно собрать в облаке командой gcloud builds submit --tag <адрес образа>.
Шаг 3. Разверните сервис
gcloud run deploy api \
--image=europe-west1-docker.pkg.dev/PROJECT_ID/apps/api:v1 \
--region=europe-west1 \
--allow-unauthenticated
После деплоя команда выведет адрес вида https://api-....run.app. Флаг --allow-unauthenticated делает сервис публичным; для внутренних API его не указывают и настраивают доступ через IAM.
Каждый деплой создаёт новую ревизию. Трафик можно разделять между ревизиями и быстро откатываться на предыдущую.
Шаг 4. Переменные окружения и секреты
Обычные настройки передайте как переменные:
gcloud run services update api --region=europe-west1 \
--set-env-vars=APP_ENV=production,LOG_LEVEL=info
Пароли и ключи храните в Secret Manager, а не в переменных или образе:
printf 'super-secret' | gcloud secrets create db-password --data-file=-
gcloud run services update api --region=europe-west1 \
--set-secrets=DB_PASSWORD=db-password:latest
Сервисному аккаунту, от имени которого работает Cloud Run, нужна роль Secret Manager Secret Accessor на этот секрет.
Шаг 5. Concurrency и min instances
- Concurrency — сколько запросов одновременно обрабатывает один экземпляр. По умолчанию — 80. Для лёгких асинхронных API значение можно оставить, для тяжёлых задач или однопоточных приложений — уменьшить.
- Min instances — сколько экземпляров держать запущенными всегда. Значение
1и выше убирает холодный старт, но такие экземпляры оплачиваются и в простое. - Max instances — верхняя граница, которая защищает от неожиданного счёта и перегрузки базы данных.
gcloud run services update api --region=europe-west1 \
--concurrency=40 --min-instances=1 --max-instances=10
Шаг 6. Свой домен
Варианты подключения домена:
- Domain mapping в Cloud Run — самый простой путь: подтверждаете владение доменом, добавляете DNS-записи, сертификат выпускается автоматически. Функция доступна не во всех регионах и имеет ограничения, поэтому проверьте документацию.
- Глобальный Application Load Balancer с serverless NEG — рекомендуемый вариант для продакшена: работает в любом регионе, поддерживает CDN и Cloud Armor.
- Firebase Hosting с перенаправлением на Cloud Run — удобно, если там же лежит фронтенд.
Как устроена оплата
Платят за vCPU, память и количество запросов, а также за исходящий трафик, хранение образов и секреты. Есть бесплатный месячный лимит.
Два режима тарификации:
- По запросам — CPU выделяется только во время обработки запроса. Если запросов нет и min instances равно нулю, вы почти ничего не платите.
- По экземплярам — CPU выделен постоянно, оплачивается всё время жизни экземпляра. Нужен для фоновой работы между запросами.
Чтобы контролировать расходы, задайте max instances, настройте бюджет с оповещениями и не держите min instances там, где холодный старт допустим.