Развёртывание Node.js REST API на Netlify через GitHub Actions

Netlify — это платформа для веб-хостинга и набор инструментов для развертывания и управления веб-приложениями в облаке. Помимо статического хостинга, Netlify предоставляет серверless-функции, позволяющие выполнять серверный код без постоянного сервера.
В этой статье мы детально рассмотрим, как создать CI/CD-пайплайн с помощью GitHub Actions для развёртывания Node.js REST API (Express) в виде serverless-функций на Netlify.
Обзор CI/CD и зачем это нужно
CI/CD (Continuous Integration / Continuous Delivery) — это последовательность автоматизированных шагов, которые проходят приложения перед попаданием в production: сборка, тестирование и развертывание. Автоматизация экономит время, снижает человеческие ошибки и обеспечивает повторяемый процесс доставки.
Преимущества автоматизации:
- Меньше ошибок при ручных деплоях.
- Быстрые и предсказуемые релизы.
- Централизованный контроль версий и откатов.
Что такое GitHub Actions
GitHub Actions — встроенный в GitHub механизм для описания workflow как кода. Вы описываете события (push, pull_request и др.) и шаги (actions), которые должны выполняться. Actions легко интегрируются с pull-req/issue и прочими фичами GitHub, что позволяет запускать пайплайны по нужным триггерам.
Требования и подготовка
Коротко о требованиях:
- Node.js (совместимые версии указывайте в Netlify.toml; пример — 16.x). Оптимально тестировать на одной версии у локальной среды и на CI.
- npm или yarn.
- Аккаунт Netlify и GitHub.
- Репозиторий на GitHub с кодом проекта.
- Понимание Express и принципов serverless-функций.
Краткое определение: serverless-функция — это единица выполнения серверного кода, запускаемая по событию (HTTP-запрос, триггер), без необходимости постоянно управлять хостом.
Шаблон проекта: создание Express-приложения
- Создайте папку проекта и перейдите в неё:
mkdir express-netlify
cd express-netlify- Инициализируйте npm:
npm init -y- Установите зависимости:
npm install express netlify-lambda serverless-httpПояснение: netlify-lambda используется для локальной разработки serverless-функций. serverless-http адаптирует Express-приложение под обработчик serverless.
Важно: Netlify не поддерживает запуск полного постоянного бэкенда, но через serverless-функции можно реализовать большинство API-эндпойнтов.
Структура проекта
Рекомендуемая структура:
- dist/ — сборка, статические файлы и index.html (placeholder для Netlify).
- functions/ — собранные serverless-функции (на CI/при сборке сюда попадёт handler).
- src/ — исходный код Express (роуты, middleware).
Создайте файл dist/index.html (пустой или базовый), чтобы Netlify корректно обслуживал сайт и API.
Пример Express-приложения
Создайте файл src/app.js с таким содержимым:
const express = require("express");
const serverless = require("serverless-http");
const app = express();
const router = express.Router();
router.get("/", (req, res) => {
res.send("hello world!");
});
// Все маршруты будут доступны по пути /.netlify/functions/app/... после деплоя
app.use(`/.netlify/functions/app`, router);
module.exports = app;
module.exports.handler = serverless(app);Комментарий: в Netlify serverless-функции разворачиваются как отдельные обработчики. Экспорт handler позволяет Netlify вызывать Express через адаптер serverless-http.
Если вы добавите, например, маршрут /api/auth, он станет доступен как:
Конфигурация Netlify: Netlify.toml
Создайте файл Netlify.toml в корне проекта:
[build]
base = "/"
command = "npm run build"
publish = "/dist/"
functions = "functions/"
[build.environment]
NODE_VERSION = "16"
[functions]
external_node_modules = ["express"]
node_bundler = "esbuild"
[[redirects]]
force = true
from = "/api/*"
status = 200
to = "/.netlify/functions/app/:splat"
[[redirects]]
from = "/*"
status = 200
to = "/index.html"Разбор ключевых параметров:
- publish — папка, которую Netlify отдаёт как статическую (dist).
- functions — директория с serverless-функциями после сборки.
- external_node_modules — перечислите модули, которые Netlify не должен бандлить (или которые необходимо сохранять отдельно).
- redirects — перенаправления; в примере все запросы к /api/* перенаправляются на функцию app, остальные — на index.html для SPA.
Совет: используйте node_bundler = “esbuild” для быстрой упаковки функций и меньшего размера артефактов.
Скрипты в package.json
Добавьте в package.json раздел scripts:
"scripts": {
"start": "netlify-lambda serve src",
"build": "netlify-lambda build src"
},Команды:
- npm run build — соберёт функции из src в functions и подготовит dist.
- npm run start — запустит локальный сервер для тестирования функций (обычно на порту 9000).
Запустите локально:
npm run build
npm run startAPI будет доступен по адресу: http://localhost:9000/.netlify/functions/app
Развёртывание приложения на Netlify вручную
Перед настройкой GitHub Actions рекомендую сначала развернуть приложение вручную на Netlify, чтобы удостовериться, что сборка и редиректы работают.
Пошагово:
- Зарегистрируйтесь или войдите в Netlify.
- На панели Netlify перейдите в Sites и нажмите Import from Git.
- Выберите GitHub как провайдера и авторизуйте Netlify для доступа к репозиторию.
- Выберите репозиторий с проектом.
- Проверьте настройки сборки: команда, папка публикации (publish), папка functions. Netlify обычно автоподставляет значения.
- Нажмите Deploy site.
После успешного развёртывания вы получите URL сайта. Ваш API будет доступен по:
Создание GitHub Actions workflow для автоматического деплоя
Откройте вкладку Actions в репозитории на GitHub и создайте новый workflow Node.js или добавьте файл .github/workflows/Netlify.yml. Ниже — минимальный пример workflow, который выполняет сборку и использует community action для деплоя на Netlify.
name: Build and Deploy to Netlify
on:
push:
pull_request:
jobs:
build:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
# ( Build to ./dist or other directory... )
- name: Deploy to Netlify
uses: nwtgck/actions-netlify@v2.0
with:
publish-dir: './dist'
production-branch: main
github-token: ${{ secrets.GITHUB_TOKEN }}
deploy-message: "Deploy from GitHub Actions"
enable-pull-request-comment: false
enable-commit-comment: true
overwrites-pull-request-comment: true
env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
timeout-minutes: 1Пояснения:
- on: push и pull_request — workflow сработает на пуши и PR.
- actions/checkout@v3 — клонирует код.
- nwtgck/actions-netlify@v2.0 — action для загрузки файлов на Netlify.
- NETLIFY_AUTH_TOKEN и NETLIFY_SITE_ID — конфиденциальные переменные (secrets) в репозитории GitHub.
Как получить NETLIFY_SITE_ID и NETLIFY_AUTH_TOKEN
- Site ID: в Netlify откройте Site settings и скопируйте Site ID.
- Auth token: нажмите на иконку профиля → User settings → Applications → New access token. Скопируйте токен.
Добавьте оба значения в GitHub Secrets (Settings → Secrets → Actions) как NETLIFY_SITE_ID и NETLIFY_AUTH_TOKEN.
Отладка и частые ошибки
- Ошибка build: проверьте, что npm run build корректно создаёт /dist и /functions.
- Некорректные пути: убедитесь, что Netlify.toml указывает правильные директории.
- Модуль не найден в функциях: добавьте модуль в external_node_modules или корректно бандлите зависимости.
- Лимит времени функции: Netlify functions имеют ограничения по времени и памяти — тяжёлые длительные задачи лучше выносить в очереди/фоновые процессы.
- Ошибка авторизации при деплое: проверьте, что NETLIFY_AUTH_TOKEN в GitHub Secrets указан верно.
Important: не храните токены внутри кода или публичных конфигов.
План отката и инцидент-руководство
Шаги при неудачном деплое:
- Откат к предыдущему коммиту: откатите ветку main до последнего успешного коммита и пушьте снова.
- Откат через Netlify: в интерфейсе Netlify можно вернуться к предыдущему деплою (Deploys → выбрать предыдущее развертывание → Rollback).
- Временно отключите workflow: в GitHub Actions можно временно отключить запуск автоматического деплоя.
- Проверка логов: просмотрите логи сборки в GitHub Actions и Netlify, чтобы найти stack trace.
Критерии приёмки:
- CI успешно собирает проект и создаёт артефакты (dist и functions).
- Автоматический деплой завершился без ошибок.
- Базовые API-эндпойнты возвращают ожидаемые ответы (см. тесты ниже).
- Система мониторинга алертов (при наличии) не показывает новых ошибок после релиза.
Роль-ориентированные контрольные списки
Developer:
- Локально собирается через npm run build
- Роуты корректно работают при netlify-lambda serve
- Обновлён package.json с нужными скриптами
DevOps:
- Netlify.toml настроен и проверен
- Secrets NETLIFY_SITE_ID и NETLIFY_AUTH_TOKEN добавлены в GitHub
- Workflow GitHub Actions проверен на тестовой ветке
QA:
- Тесты API пройдены (см. раздел тест-кейсов)
- Проверены упавшие кейсы и регрессии
Тест-кейсы и критерии приёмки
Минимальный набор тестов:
- GET /.netlify/functions/app/ возвращает 200 и «hello world!».
- Смоук-тесты для каждого критического эндпойнта: статус ответа и формат тела.
- Тестирование CORS (если требуется).
- Нагрузочные тесты для ключевых путей (если функции ожидают высокий трафик).
Критерий приёмки: все основные тесты зелёные и нет утечек ошибок в логах 30 минут после релиза.
Альтернативные подходы и когда этот метод не подходит
Когда подходит:
- Лёгкие и средние API, которые укладываются в ограничения serverless.
- SPA с небольшим бэкендом.
Когда не подходит:
- Длительные фоновые задачи, требующие постоянного процесса.
- Очень тяжёлые вычисления или требующие специализированного окружения.
Альтернативы:
- Использовать полноценный VPS или PaaS (Heroku, Render) для тяжёлых backend-сервисов.
- Вынос тяжёлых задач в отдельные background services или очередь (RabbitMQ, SQS).
Безопасность и приватность
- Храните NETLIFY_AUTH_TOKEN и NETLIFY_SITE_ID в GitHub Secrets.
- Минимизируйте права токена: выдавайте только необходимые права.
- Ограничьте доступ к репозиториям и Netlify сайту по принципу least privilege.
- Если обрабатываете персональные данные, проверьте соответствие локальным требованиям GDPR/законодательству о персональных данных.
Советы по оптимизации и отладке функций
- Используйте esbuild для быстрой упаковки функций.
- Минимизируйте разовый объём зависимостей: импортируйте только нужные пакеты.
- Кешируйте результаты там, где возможно.
- Логи: печатайте минимально необходимую информацию, используйте уровни логирования.
Совместимость и миграция
- Node.js: в Netlify указывайте желаемую версию через Netlify.toml (NODE_VERSION). Убедитесь, что локально и на CI используется та же версия.
- Если вы мигрируете с платформы, которая поддерживает постоянный сервер (например, VPS), убедитесь, что все долгоживущие соединения и веб-сокеты либо переработаны, либо размещены на другом сервисе.
Mini-методология развёртывания
- Локальная разработка и юнит-тесты.
- Локальная интеграционная проверка через netlify-lambda serve.
- Push в feature-ветку и PR с автоматическими тестами в GitHub Actions.
- Code review → merge в main.
- Автоматический билд + деплой на Netlify.
- Smoke-тесты и мониторинг после релиза.
Примерный чек-лист перед merge в main
- Код покрыт тестами.
- Локальная сборка успешна.
- Нет секретов в коде.
- Обновлены документация и README (если нужны изменения в API).
Visual: решение ветвления действий (Mermaid)
flowchart TD
A[Работа в feature-ветке] --> B[Открыть PR]
B --> C{CI прошёл?}
C -- Да --> D[Code Review]
C -- Нет --> E[Исправить проблемы]
D --> F{Approved?}
F -- Да --> G[Merge в main]
F -- Нет --> H[Доп. обсуждение]
G --> I[GitHub Actions: сборка и деплой]
I --> J[Netlify: новый деплой]
J --> K[Smoke-тесты]
K --> L{ОК?}
L -- Да --> M[Мониторинг]
L -- Нет --> N[Откат]Edge-кейсы и советы по работе с ними
- Функции превышают лимит времени: разбейте работу на несколько функций или используйте очередь.
- Нестабильная сборка только на CI: сравните окружения Node и версии зависимостей.
- Неправильные редиректы: проверьте порядок правил в Netlify.toml и совпадение шаблонов.
Примеры типичных сообщений ошибок и как их исправлять
- “Cannot find module ‘express’” — добавить express в external_node_modules или бандлить.
- “Function timed out” — оптимизировать функцию, увеличить таймаут, вынести тяжёлую работу.
- “Build failed: command ‘npm run build’ returned non-zero exit code” — посмотреть лог команды build и исправить ошибки сборки.
Частые вопросы
Q: Можно ли использовать Express с Netlify без serverless-http?
A: Netlify вызывает функции как отдельные обработчики, поэтому для использования Express удобно применять адаптеры вроде serverless-http. Без адаптера придётся вручную переписывать обработку запросов под формат Netlify.
Q: Что делать, если API требует авторизации и приватных ключей?
A: Хранить ключи в GitHub Secrets и/или в переменных окружения Netlify. Никогда не коммитьте секреты в репозиторий.
Q: Как тестировать WebSocket на Netlify?
A: Netlify Functions не предназначены для долговременных двунаправленных соединений; используйте специализированные сервисы (Pusher, WebSocket-сервер на отдельном хосте).
Пример краткого объявления релиза (100–200 слов)
Готово: автоматический пайплайн для развёртывания Node.js REST API на Netlify. Теперь при merge в main GitHub Actions автоматически собирает проект, создаёт serverless-функции и развертывает сайт и API на Netlify. Для доступа к приватным ресурсам используйте NETLIFY_AUTH_TOKEN и NETLIFY_SITE_ID в секретах GitHub. Локально можно тестировать через netlify-lambda serve. Проведите smoke-тесты основных эндпойнтов сразу после релиза.
Краткое резюме
- Netlify позволяет размещать front-end + backend в виде serverless-функций.
- GitHub Actions служит для автоматической сборки и деплоя.
- Важны корректные конфигурации Netlify.toml, скрипты сборки и безопасное хранение токенов.
- Переход на serverless требует учёта ограничений по времени и ресурсам.
Итоговые рекомендации:
- Начните с ручного деплоя, затем автоматизируйте через Actions.
- Внедрите smoke-тесты и мониторинг.
- Храните секреты в GitHub Secrets и в настройках Netlify.
Если нужно, я могу подготовить готовый шаблон .github/workflows/Netlify.yml, расширенные тест-кейсы для ваших эндпойнтов или пример CI с интеграцией тестирования и линтинга.