Деплой Node.js-приложения
Эта статья дополняет общие правила из «Что нужно, чтобы деплой прошёл» конкретикой для Node.js. Всё, что нужно, задаётся в одном файле — package.json: зависимости, команда запуска и версия Node.
Шаг 1. Зависимости и lock-файл
Nixpacks определяет Node.js по package.json в корне репозитория и устанавливает то, что перечислено в dependencies. Закоммитьте вместе с ним файл блокировки версий (package-lock.json, pnpm-lock.yaml или yarn.lock) — по нему выбирается пакетный менеджер и точные версии.
Пакет, установленный локально без сохранения в package.json (npm install <пакет> без записи в зависимости), на сборке будет отсутствовать. Устанавливайте с флагом сохранения: npm install <пакет> записывает зависимость по умолчанию, проверьте, что она попала в файл.
Шаг 2. Команда запуска — скрипт start
Nixpacks запускает приложение командой npm start, то есть берёт скрипт start из package.json. Задайте его явно:
{
"scripts": {
"start": "node index.js"
}
}
Без скрипта start сборщик попытается угадать точку входа и может запустить не то. Не полагайтесь на угадывание.
Пример: Web-сервис (Express)
Web-сервис принимает HTTP-запросы и получает домен. Приложение обязано слушать порт из переменной PORT (см. общую статью).
package.json:
{
"name": "my-app",
"engines": { "node": "22" },
"scripts": {
"start": "node index.js"
},
"dependencies": {
"express": "^4.19.0"
}
}
index.js:
const express = require("express");
const app = express();
app.get("/", (req, res) => res.json({ status: "ok" }));
const port = process.env.PORT || 3000;
app.listen(port, () => console.log(`listening on ${port}`));
HTTP-сервер Node.js (и Express) по умолчанию слушает на
0.0.0.0, поэтому здесь достаточно указать правильный порт. Значение|| 3000— только для локального запуска; на платформеPORTпридёт из окружения.
Пример: Worker-сервис (Telegram-бот)
Worker работает в фоне, не принимает HTTP и не имеет домена. Порт слушать не нужно. Токен читается из переменных окружения.
package.json:
{
"name": "my-bot",
"engines": { "node": "22" },
"scripts": {
"start": "node bot.js"
},
"dependencies": {
"telegraf": "^4.16.0"
}
}
bot.js:
const { Telegraf } = require("telegraf");
const bot = new Telegraf(process.env.BOT_TOKEN);
bot.start((ctx) => ctx.reply("Привет"));
bot.launch();
Значение BOT_TOKEN задаётся в переменных окружения сервиса — см. «Переменные окружения и секреты».
Версия Node.js
Укажите её в поле engines.node файла package.json (как в примерах выше) или в файле .nvmrc. Без указания берётся актуальная LTS-версия.
Проект на TypeScript
Если код на TypeScript, нужен шаг сборки перед запуском:
- добавьте скрипт
build(например,"build": "tsc") — Nixpacks выполнит его автоматически; - в
startукажите запуск уже скомпилированного файла (например,"start": "node dist/index.js"); - инструменты сборки (
typescriptи типы) держите вdevDependencies— при сборке они устанавливаются.
Частые ошибки
| Симптом | Причина | Решение |
|---|---|---|
Cannot find module при запуске | Зависимость не записана в package.json | Добавьте её в dependencies, закоммитьте lock-файл |
| Сборка прошла, но контейнер сразу останавливается | Нет скрипта start или неверный путь к файлу | Задайте start, проверьте путь |
| Домен отдаёт 502 | Приложение слушает фиксированный порт вместо PORT | Используйте process.env.PORT |
Сборка TypeScript падает: не найден tsc | Задана переменная NODE_ENV=production — devDependencies не ставятся | Не задавайте NODE_ENV=production для сборки или перенесите инструменты в dependencies |
| Бот не отвечает, ошибка про токен | Токен захардкожен или не задан | Задайте BOT_TOKEN в переменных окружения |