Развертывание Node.js REST API на Netlify с GitHub Actions
Important: Netlify не хостит полноценные постоянные бэкенды — используйте serverless-функции для серверной логики.

Netlify — это платформа для хостинга веб-сайтов и набор инструментов для развёртывания и управления веб-приложениями в облаке. Однако одной из ключевых возможностей Netlify являются serverless-функции: они дают возможность запускать серверный код без выделенного сервера.
В этой статье подробно рассматриваются все этапы создания CI/CD пайплайна для развертывания Node.js REST API на Netlify с использованием GitHub Actions. Материал подходит для разработчиков, инженеров DevOps и команд, которые хотят автоматизировать доставку кода в продакшн.
Что такое CI/CD и зачем он нужен
CI/CD (Continuous Integration / Continuous Delivery) — это набор автоматизированных шагов, через которые проходит код перед попаданием в продакшн. Типичный пайплайн включает фазы: source → build → test → deploy.
Преимущества автоматизации:
- Снижение риска ошибок из-за человеческого фактора.
- Ускорение выпуска изменений.
- Консистентный процесс релизов и улучшенное качество.

Что такое GitHub Actions
GitHub Actions — встроенный в GitHub механизм описания рабочих процессов (workflows) как кода. Вы можете использовать готовые actions и создавать собственные. Actions легко интегрируются с pull request, issues и другими событиями, позволяя запускать пайплайны при коммитах, PR или по расписанию.
Подготовка Node.js проекта
Ниже приведены шаги для создания минимального Express-приложения, которое будет упаковано в serverless-функцию и развернуто на Netlify.
- Создайте директорию проекта и перейдите в неё:
mkdir express-netlify
cd express-netlify- Инициализируйте package.json:
npm init -y- Установите зависимости:
npm install express netlify-lambda serverless-httpПояснение пакетов:
- express — HTTP-фреймворк.
- netlify-lambda — упрощает локальную разработку serverless-функций и сборку в папку functions.
- serverless-http — адаптирует Express-приложение под хэндлер serverless-платформы.
Netlify не предоставляет полноценный сервер для бэкенда; вместо этого используется модель serverless — код вызывается по запросу и масштабируется автоматически.
Структура файлов и папок
Рекомендуемая минимальная структура проекта:
- dist/ — статическая сборка (publish dir)
- functions/ — собранные serverless-функции для Netlify
- src/ — исходники Express-приложения
- package.json
- Netlify.toml
Создайте пустой файл index.html в папке dist — он нужен, чтобы Netlify успешно развернул сайт и обслуживал маршруты SPA/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!")
});
app.use(`/.netlify/functions/app`, router);
module.exports = app;
module.exports.handler = serverless(app);Как это работает:
- Мы регистрируем маршруты через router и монтируем их на префиксе /.netlify/functions/app — так Netlify будет направлять HTTP-запросы к нашей функции.
- Экспортируется handler через serverless-http, чтобы Netlify мог вызвать Express-приложение как serverless-функцию.
- При добавлении маршрута /api/auth он будет доступен по пути
/.netlify/functions/app/api/auth.
Конфигурация 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"Разбор ключевых секций:
- [build].command — команда, которая соберёт проект. Здесь netlify-lambda создаст функции в папку functions.
- [build].publish — директория, содержащая статические файлы для сервинга (index.html и прочие).
- [build].functions — каталог, куда Netlify смотрит на serverless-функции.
- [functions].external_node_modules — модули, которые нужно исключить из бандла и оставить как внешние, чтобы уменьшить размер бандла.
- redirects /api/* → /.netlify/functions/app/:splat — перенаправляет все вызовы /api/… к нашей функции app.
- redirect /* → /index.html — включаем поддержку SPA-маршрутизации.
Примечание: NODE_VERSION в environment указывает версию Node на билде; при необходимости обновите.
Обновление package.json
Добавьте скрипты для локальной разработки и билда функций:
"scripts": {
"start": "netlify-lambda serve src",
"build": "netlify-lambda build src"
},Сборка и запуск локально:
npm run build
npm run startПо умолчанию сервер netlify-lambda стартует на порту 9000. Тестируйте API через Postman: http://localhost:9000/.netlify/functions/app
Развёртывание приложения на Netlify через UI
Рекомендуется сначала вручную развернуть сайт через UI Netlify, чтобы получить Site ID и проверить конфигурацию.
Шаги:
- Создайте аккаунт Netlify и войдите в панель Overview.
- Выберите вкладку Sites.
- Нажмите Import from Git и выберите GitHub как провайдера.
- Авторизуйте Netlify с GitHub и выберите репозиторий с проектом.
- Netlify автоматически предложит build settings (build command, publish и functions directory). Это тот же Netlify.toml, но автоматическая настройка удобна для первого деплоя.

- Нажмите Deploy site. После успешного деплоя вы получите публичный URL сайта.
Настройка GitHub Actions для автоматического деплоя
После ручного развертывания подключите CI/CD через GitHub Actions, чтобы каждый push в main автоматически создавал новый деплой.
- В репозитории GitHub перейдите в Actions → настроить workflow → Configure Node.js.
- Переименуйте файл в Netlify.yml и замените шаблон на код ниже.
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 — указывает события, которые запускают workflow (push и pull_request).
- runs-on — образ виртуальной машины (здесь Ubuntu 22.04).
- uses: nwtgck/actions-netlify — action, который выполняет деплой на Netlify.
- with.publish-dir — каталог, отправляемый в Netlify (./dist).
- env.NETLIFY_AUTH_TOKEN и NETLIFY_SITE_ID — секреты для доступа к Netlify API.
Где взять секреты
- Site ID: в Site settings → General → Site details → Site ID.
- Auth token: User settings → Applications → New access token.
Добавьте NETLIFY_AUTH_TOKEN и NETLIFY_SITE_ID в Secrets репозитория на GitHub (Settings → Secrets and variables → Actions).
Note: Не храните токены в коде или в открытых файлах. Используйте секреты GitHub.
Тестирование и отладка
Локальная отладка:
- netlify-lambda serve src — стартует локальный сервер для функций.
- Используйте Postman или curl для тестов: http://localhost:9000/.netlify/functions/app
Отладка сборки в CI:
- Просматривайте логи GitHub Actions в UI GitHub: Actions → ваш workflow → run.
- Логи Netlify можно смотреть в панели Netlify в Deploys → choose deploy → View deploy logs.
Распространённые ошибки и способы их устранения
- Ошибка: “Function failed to load” — вероятно, неправильный путь экспорта handler в src/app.js. Убедитесь, что module.exports.handler = serverless(app).
- Ошибка: Неверные зависимости при сборке — укажите external_node_modules в Netlify.toml для «heavy» библиотек, или используйте бандлер esbuild для уменьшения размеров.
- Ошибка: 404 на API в продакшне — проверьте redirects в Netlify.toml и что publish-dir указан правильно.
- Ошибка: Unauthorized при деплое из GitHub Actions — проверьте NETLIFY_AUTH_TOKEN и NETLIFY_SITE_ID в Secrets.
Лучшие практики и безопасность
- Минимизируйте права токена Netlify: создавайте токен с ограниченным доступом, если это возможно.
- Не включайте секреты в package.json или файлы репозитория.
- Логи в CI не должны выводить секреты — используйте masked secrets.
- Ограничьте время выполнения функций и тщательно контролируйте медленные операции.
- Добавьте rate limiting и/или аутентификацию для публичных API, особенно для endpoint-ов с изменением данных.
Альтернативные подходы
- Vercel: аналогичный подход (serverless Functions), иногда удобнее для Next.js.
- AWS Lambda + API Gateway: даёт большую гибкость и интеграцию с AWS экосистемой, но требует больше инфраструктурной работы.
- Heroku / Render: для традиционных long-running бэкендов.
Когда Netlify не подходит:
- Требуется длительно работающий процесс или WebSocket-соединения с постоянной сессией.
- Очень низкая латентность и контроль над сетью — в таких задачах чаще выбирают управляемые сервисы (VM/containers).
Роли и контрольный список при выпуске
Для команды разработки приведён практический checklist перед мёржем в main:
Разработчик:
- Локально прошло npm run build и npm run start.
- Добавлены unit/integration тесты для новых маршрутов.
- Локальные тесты проходят.
QA:
- Проверены ключевые сценарии через Postman.
- Проверена авторизация и обработка ошибок.
DevOps:
- Secrets добавлены в GitHub Actions.
- Netlify.toml корректен и перенаправления работают.
- Проверены логи первого деплоя.
Security:
- Токен Netlify имеет минимальные права.
- Проверен доступ к приватным данным в логах.
Пример playbook для быстрого восстановления после неудачного деплоя
- Откат: откатиться к предыдущему коммиту, который успешно деплоился, и запушить revert.
- Если проблема только в функциях, временно отключить redirect /api/* на Netlify и вернуть статический сайт.
- Проанализировать логи GitHub Actions и Netlify, исправить и прогнать workflow локально.
Чек-лист для production readiness
- Логи и мониторинг настроены (Netlify deploy logs, внешние APM при необходимости).
- SLO/SLI: определите целевой uptime и время ответа для ваших функций.
- Тесты: unit и интеграционные тесты покрывают критичные сценарии.
- Secrets: нет в репозитории, все в GitHub Secrets.
Пример расширенного workflow с тестированием и кэшированием зависимостей
name: CI/CD Netlify
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test-and-build:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: 16
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test
- name: Build functions and static
run: npm run build
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: dist
path: ./dist
deploy:
needs: test-and-build
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- name: Download artifact
uses: actions/download-artifact@v3
with:
name: dist
path: ./dist
- name: Deploy to Netlify
uses: nwtgck/actions-netlify@v2.0
with:
publish-dir: './dist'
production-branch: main
env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}Этот пример показывает: запуск тестов, сборку, передачу артефакта и деплой уже проверённого билда.
Ментальные модели и эвристики
- Keep functions small: чем меньше функция, тем проще тестировать и быстрее запуск.
- Single responsibility: каждый endpoint должен делать одно дело.
- Идём к idempotent-операциям: постарайтесь, чтобы повторные вызовы не приводили к неконсистентности.
Советы по миграции существующего бэкенда
- Начинайте с выноса read-only endpoint-ов в serverless.
- Используйте адаптер вида serverless-http для экспортирования существующих Express-приложений.
- Следите за cold-start latency: критичные по задержке функции лучше держать в других инфраструктурах.
Edge-case галерея
- Большие файлы в ответе: лучше отдавать через CDN или presigned URLs, не через функции.
- WebSocket: Netlify не подходит для долгоживущих WebSocket-подключений.
- Background jobs: используйте внешние планировщики или очереди (e.g., AWS SQS, Cloud Tasks).
Критерии приёмки
- CI Workflow успешно собирает и тестирует проект при каждом PR.
- Деплой на main автоматически выполняется и доступен по публичному URL.
- Все публичные API работают через
/.netlify/functions/app. - Неутечка секретов: токены хранятся в GitHub secrets и не видны в логах.
Короткий план действий на одну страницу (SOP)
- Настроить проект: создать src/app.js, dist/index.html, Netlify.toml.
- Добавить скрипты build/start в package.json.
- Развернуть сайт в Netlify вручную и получить Site ID.
- Создать GitHub Secrets NETLIFY_AUTH_TOKEN и NETLIFY_SITE_ID.
- Добавить Netlify.yml в .github/workflows и закоммитить.
- Проверить логи GitHub Actions и Netlify Deploy.
Заключение
Netlify и GitHub Actions вместе дают простую и мощную связку для автоматического развёртывания Node.js API в модели serverless. Такой подход ускоряет релизы и уменьшает сложность инфраструктуры, особенно для приложений с небольшими бэкенд-функциями.
Ключевые рекомендации:
- Используйте netlify-lambda и serverless-http для адаптации Express.
- Тестируйте локально и в CI до деплоя.
- Храните секреты в GitHub Secrets.
- Ограничьте scope токенов и следите за логами.

Summary:
- Netlify — отличный выбор для статических сайтов с serverless-бэкендом.
- GitHub Actions помогает автоматизировать CI/CD и гарантировать повторяемость.
- Для сложных бэкендов рассмотрите альтернативные платформы.
Похожие материалы
Показываем и управляем sideload приложениями на Android TV
Медленный мобильный интернет: 10 шагов для ускорения
Как выбрать тариф iCloud+ — 50GB–12TB
Как заменить фон меню GRUB на своё изображение
Организация содержимого PS4 — полное руководство