Деплоим Next.js приложение через PM2

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Недавно мне посчастливилось развернуть Next.js на сервере с помощью PM2. Этот способ я не нашел в документации фреймворка, хотя считаю его довольно удобным, при этом гайдов по теме оказалось очень мало. Рассказываю, как всё сделать, и привожу рабочие примеры.

Заманчивое предложение

В конце весны в команде появилась задача на разработку веб-приложения с игровыми механиками для одного крупного клиента. К тому моменту давно хотел попробовать Next.js, но руки всё никак не доходили. В этот раз появился триггер — в официальной документации по React с недавних пор настойчиво предлагают начинать проекты сразу на фреймворке, и теперь я не мог отказаться.

Администраторы нашего севера сразу же предложили уйти от способов деплоя из документации (там их всего три вместе со статическим экспортом), и вместо них распробовать демонизацию кода при помощи PM2. Про эту технологию раньше никогда не слышал, а поиск в интернете не дал ясных инструкций, как связать её с Next.js. От этого изучить заморскую штуковину стало только интереснее, и теперь я могу поделиться всеми настройками и болями от их создания.

Работаем с PM2

Для тех людей, вроде меня, кто никогда не слышал про PM2, — это менеджер процессов, с помощью которого можно запускать приложения на NodeJS. Каждое такое приложение-процесс можно перезапускать, останавливать и мониторить отдельно от другого, а ещё с PM2 удобно распределять нагрузку: есть режим кластера.

После того, как поставили пакет PM2 на сервере (в моём случае под пользователя, с которого будет выполняться деплой), заходим в директорию нашего Next.js приложения и создаём в корне файл ecosystem.config.js. Там будут лежать настройки, которые PM2 возьмёт для запуска процесса. Внутрь добавляем два главных поля:

module.exports = {
  apps: [
    {
      name: 'Моё прекрасное приложение',
      script: 'node_modules/next/dist/bin/next'
    }
  ]
}

В name указываем название приложения, оно появится в списке процессов. Следующий затем script содержит путь, куда PM2 постучится для запуска Next.js. В своём конфиге я дополнительно указал порт 4000 вместо 3000 — это перестраховка, чтобы не случилось конфликтов за дефолтный. Дополнительно можно указать exec_mode: 'cluster' для распределения нагрузки, подробнее об этом можно почитать тут. Вот финальный вид:

module.exports = {
  apps: [
    {
      name: 'Моё прекрасное приложение',
      script: 'node_modules/next/dist/bin/next',
      args: '-p 4000',
      exec_mode: 'cluster',
      instances: 'max'
    }
  ]
}

На этом всё, теперь команда pm2 start приведет к запуску того и с теми настройками, что мы указали в корне внутри ecosystem.config.js.

Nginx — заводись!

С Nginx пришлось повозиться: сперва казалось непонятным, на какой файл вести пользователя. Но чтобы всё завелось, вести нужно на порт, а не на файл. Поскольку я выбрал 4000 вместо дефолтного 3000, то два важных нам кусочка nginx.conf обрели такой вид (всё остальное опустил в троеточиях):

...

upstream nextjs_upstream {
  server 127.0.0.1:4000;
  keepalive 64;
}

...

location / {
  ...
  proxy_pass http://nextjs_upstream/;
  proxy_redirect off;
  proxy_read_timeout 240s;
}

...

С этими настройками 502-я ошибка навсегда ушла, и Nginx стал корректно отрабатывать запросы.

Запускаем Next.js

В документации по деплою приложений на Next.js с помощью Node.js сервера нам приводят две главные команды:

npm run build 
npm run start

После start запускается сервер с поддержкой всех Next.js фич. Но для нас это не актуально, потому что запускаем мы процесс PM2:

npm run build
pm2 start

Здесь важно вот что: если мы заливаем код повторно и снова выполняем npm run build, то PM2 процесс нужно остановить командой pm2 stop <название приложения>. Без этого у меня жил коварный баг, который я не мог отловить несколько дней: пайплайн то успешно переходил в passed, то спонтанно падал по таймауту на этапе npm run build. Причём изменения подгружались на сайт, что ещё больше путало.

Пока искал в интернете, наткнулся на множество тем в духе Next build hangs forever, но моего решения не нашел. Позже вспомнил, что PM2 процесс как работал, так и работет во время сборки, и фикс этого нюанса навсегда избавил меня от проблемы.

Вот и всё! Хотя поначалу деплой Next.js таким способом казался тернистым, сейчас я считаю это довольно удобным и быстрым вариантом запускать будущие приложения на сервере. Надеюсь, эта статья поможет вам комфортно развернуть свои работы на готовых примерах.

Источник: https://habr.com/ru/articles/820841/


Интересные статьи

Интересные статьи

Мэдс Кристенсен из команды Visual Studio сообщил, что Microsoft теперь стремится предоставить возможность доставлять обновления для своей основной интегрированной среды разработки (IDE) через Центр об...
«Билайн» (бренд «Вымпелкома») разработал приложение на отечественной мобильной операционной системе «Аврора». Оно доступно на устройствах четвёртого поколения, пишут «Ведомости». Представите...
Всегда ли вы берете с собой смартфон? Наверное да, ведь это удобно, когда под руками есть все каналы связи.Но что, если вы собираете автономно работающее устройство с микрокомпьютером, такое как как р...
Переименовав недавно Яндекс.Такси в «Яндекс Go», разработчики приложения сделали невозможным его поиск через Spotlight по главному ключевому слову — «такси». Однако дело ...
В эту субботу 1 февраля 2020 г. в нашем Хакспейсе Нейрон в Москве пройдет мастер-класс по практическому использованию DMA-атак. Вместе мы будем взламывать реальный компьютер с зашифрованной фай...