lenec ru

← все посты

Деплой на Timeweb Cloud Apps: гайд для Node-проекта

13K

Timeweb Cloud — российский хостер с понятной панелью и приличной инфраструктурой. У них есть отдельный продукт Cloud Apps: PaaS-вариант, в котором ты привязываешь git-репозиторий, и платформа сама делает билд и деплой. Я катал на нём пару проектов; делюсь рабочей схемой и тонкостями.

Контекст: Node 20, TypeScript, бекенд на Express/Fastify или Astro SSR. Cloud Apps также отлично жуёт Next.js, статические сайты и Python-приложения.

Что такое Cloud Apps

Cloud Apps — это «как Vercel, только в Timeweb». Ты подключаешь репозиторий из GitHub/Gitlab, платформа сама собирает приложение и поднимает его. Не нужен VPS, не нужны systemd-юниты, не нужен ручной nginx. Платформа сама делает SSL, авто-перезапуск, деплой по push.

Что внутри:

  • Cloud Apps крутит приложения в контейнерах с автоматическим масштабированием (вертикальным).
  • Поддержка Node.js, Python, PHP, Go, Java, Docker.
  • Бесплатный TLS на стандартный поддомен *.twc1.net, привязка собственного домена.
  • Биллинг по часам работы конфигурации.

Когда подходит Cloud Apps

  • Простые Node/Next-приложения без долгих фоновых задач.
  • Маленькие команды, которые не хотят возиться с VPS.
  • Прототипы и MVP, которые надо быстро задеплоить и показать.

Когда не подходит:

  • Нужны фоновые воркеры, которые работают часами.
  • Нужны WebSocket-соединения с долгой жизнью.
  • Сложная сетевая конфигурация (private networks, отдельные подсети).
  • Нужна полная контроль над окружением: тогда лучше обычный Cloud Server.

Подготовка проекта

Cloud Apps определяет тип приложения по содержимому репозитория. Для Node-проекта он смотрит на package.json и запускает то, что в scripts.start.

В package.json:

{
  "name": "myapp",
  "version": "1.0.0",
  "engines": {
    "node": ">=20.0.0 <21.0.0"
  },
  "scripts": {
    "build": "tsc -p tsconfig.json",
    "start": "node dist/server.js"
  },
  "dependencies": {
    "express": "^4.21.0",
    "pg": "^8.13.0"
  },
  "devDependencies": {
    "typescript": "^5.4.0",
    "@types/node": "^20.0.0"
  }
}

В engines.node указывай нужную версию. Cloud Apps подберёт ближайшую, доступную в их образах. Если ты на 22 — пиши 22, на 20 — 20.

На сервере приложение должно слушать порт из переменной PORT:

const port = Number(process.env.PORT ?? 3000);
app.listen(port, '0.0.0.0', () => console.log(`listening on ${port}`));

Платформа подкидывает PORT динамически и пробрасывает с публичного 80/443 на этот порт.

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

В панели Timeweb Cloud:

  1. Cloud Apps → Создать приложение.
  2. Подключить GitHub или Gitlab. Если репо приватное, авторизуешься через OAuth.
  3. Выбрать репозиторий и ветку (обычно main или master).
  4. Указать путь к проекту (если в репо несколько проектов в подкаталогах — здесь монорепы поддерживаются ограниченно).
  5. Выбрать тип фреймворка: Node.js.
  6. Выбрать конфигурацию (CPU/RAM). Стартовая 1 vCPU / 1 GB обычно хватает на простое API.

На этом шаге можно указать билд- и старт-команды, если автодетект промахнулся:

Build command: pnpm install --frozen-lockfile && pnpm build
Start command: node dist/server.js

По умолчанию платформа берёт npm install и npm start. Если у тебя pnpm/yarn, обязательно перепиши.

Переменные окружения

В разделе «Окружение» приложения добавляешь все нужные переменные: DATABASE_URL, JWT_SECRET, ключи API. Они доступны в process.env на этапе билда и в рантайме.

Важный момент: в Cloud Apps секреты хранятся в зашифрованном виде, но они не защищены так, как менеджеры секретов уровня Vault. Для критически чувствительных данных я бы хранил их в Yandex Lockbox или отдельном self-hosted Vault и тащил оттуда при старте.

База данных

Cloud Apps не предоставляют собственную БД, но в Timeweb Cloud есть Managed Postgres, MySQL, Redis. Заводишь рядом с приложением, настраиваешь private network между ними, в переменные окружения подсовываешь connection string.

Например:

DATABASE_URL=postgres://user:pass@<managed-pg-host>:5432/dbname?sslmode=require

Если кладёшь рядом Redis для очередей — тот же подход с приватным IP в одной сети.

Свой домен

В разделе «Домены» приложения добавляешь домен, ставишь A-запись на IP, который покажет панель. Платформа сама выпишет Let's Encrypt-сертификат и будет его обновлять. У меня привязка домена обычно занимает минут 10–15 после прогрева DNS.

Для wildcard-сертификата нужен DNS-вызов; стандартного wildcard через панель нет, но app.example.ru и www.example.ru делаются легко.

Логи и мониторинг

В панели Cloud Apps есть вкладки:

  • Логи: stdout/stderr приложения. На простых сценариях достаточно. На больших объёмах фильтрация и поиск ограничены, я отправляю важные логи во внешний агрегатор (Loki, ClickHouse) через push.
  • Метрики: CPU, RAM, RPS, время ответа. Базовые графики, для подробной аналитики — добавляй OpenTelemetry или собственные метрики.
  • События: рестарты, деплои, ошибки билда. Полезно для понимания «почему вдруг упало в 3 ночи».

Авто-деплой

По умолчанию Cloud Apps подписывается на webhook git-репозитория и при push в выбранную ветку запускает билд и деплой. Это удобно: коммит в main → через 2–3 минуты приложение обновлено.

Если хочется деплоить только из CI после прогона тестов — отключай авто-деплой и используй webhook от своего Gitea/GitHub Actions, который дёргает Cloud Apps API.

curl -X POST https://api.timeweb.cloud/api/v1/apps/<app_id>/deploy \
  -H "Authorization: Bearer $TIMEWEB_TOKEN"

Подводные камни

Долгий билд

На крупных проектах билд может идти 5–10 минут, и за это время Cloud Apps удерживает рабочий контейнер. Если ты деплоишь часто, имеет смысл оптимизировать билд: pnpm cache, меньше ненужных зависимостей, prebuilt artifacts.

Memory leak

Cloud Apps делает auto-restart, если контейнер упирается в лимит памяти. Это спасает, но скрывает реальную проблему. Если ты замечаешь периодические рестарты — это сигнал поискать утечку: heapdump, clinic.js, отдельный staging для нагрузочного теста.

Cron-задачи

Долго живущие cron-задачи в одной инстанции с веб-сервером — плохая идея. Если приложение перезапустится во время cron, ты пропустишь работу. Я разделяю: для cron-задач отдельное приложение или внешний планировщик, который зовёт endpoint на основном.

Holding state

На Cloud Apps инстанс может перезапускаться: после деплоя, при смене конфигурации, при обновлении платформы. Любое состояние в памяти потеряется. Кэши в памяти держи коротко, постоянное хранение — в БД или Redis.

Что я в итоге получаю

  • API на ноде с git-deploy: коммит → продакшен.
  • HTTPS из коробки.
  • Базовые метрики и логи в панели.
  • Не нужен VPS-уход: апдейты безопасности не моя забота.

Cloud Apps — приличный вариант для небольших Node-приложений, особенно если у тебя нет devops-ресурса. На моих проектах с трафиком до сотен RPS работает стабильно. Когда нужно масштабироваться или появляются нестандартные требования — переезд на Cloud Server с тем же Timeweb или на Yandex Cloud делается за пару дней. Главное — не закладываться на специфические фишки одной платформы и держать код переносимым.

Комментарии 0

  • Будьте первым, кто оставит комментарий.

Войдите, чтобы оставить комментарий.