Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Развёртывание на сервере

Развёртывание — перенос приложения на сервер, где оно работает круглосуточно и доступно по домену. Для Node.js-приложения нужны три вещи: режим production, менеджер процессов, который перезапустит сервер после сбоя, и обратный прокси — веб-сервер, который принимает запросы из интернета и передаёт их приложению.

Режим production

Переменная окружения NODE_ENV=production включает в Express рабочий режим: шаблоны кешируются, а стандартная страница ошибки не показывает стек вызовов. Её же читает наш src/config.js, чтобы включить безопасные cookie и подробный журнал.

Подготовка на сервере

На сервере должен быть установлен Node.js 22 или новее. Скопируйте проект через Git и установите только рабочие зависимости:

git clone https://github.com/anna/blog.git
cd blog
npm ci --omit=dev

npm ci ставит точно те версии, что записаны в package-lock.json, а --omit=dev пропускает пакеты для разработки вроде supertest. Файл .env создайте на сервере вручную, с новыми длинными секретами.

Менеджер процессов pm2

Если запустить npm start в терминале, сервер остановится вместе с сессией SSH и не поднимется после сбоя. pm2 держит приложение запущенным:

npm install --global pm2
NODE_ENV=production pm2 start src/server.js --name blog --node-args="--env-file=.env"
pm2 save
pm2 startup

pm2 save запоминает список приложений, а pm2 startup печатает команду, после выполнения которой pm2 будет запускаться вместе с сервером.

КомандаЧто делает
pm2 statusСписок приложений и их состояние
pm2 logs blogЖурнал приложения в реальном времени
pm2 restart blogПерезапуск, например после обновления кода
pm2 stop blogОстановка

Обратный прокси nginx

Приложение слушает порт 3000 только на самом сервере, а nginx принимает запросы на 80-м и 443-м портах, занимается HTTPS-сертификатами и передаёт запросы дальше. Файл сайта, например /etc/nginx/sites-available/blog:

server {
    listen 80;
    server_name example.com;
 
    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

После включения сайта и перезагрузки nginx блог откроется по адресу http://example.com. HTTPS-сертификат бесплатно выдаёт Let's Encrypt через утилиту certbot.

Доверие прокси

Теперь все запросы приходят в Express от nginx, и req.ip показывает 127.0.0.1. Скажите Express, что перед ним один прокси, которому можно верить:

// src/app.js
app.set('trust proxy', 1);

Express начнёт брать адрес посетителя и протокол из заголовков X-Forwarded-For и X-Forwarded-Proto. Без этого не будут работать ограничение частоты по IP и cookie с флагом secure.

Обновление

git pull
npm ci --omit=dev
pm2 restart blog

Частая ошибка

Не запускайте Node.js-приложение от пользователя root и не открывайте порт 3000 наружу. Приложение должно быть доступно только через nginx: так весь трафик проходит через HTTPS, а ошибка в коде не даст злоумышленнику прав администратора на сервере.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.