Запускаем Next.js приложение через PM2 на Nginx в простейшей конфигурации
После написания нашего прекрасного веб приложения встает вопрос, как запустить его покорять мир (на рабочем сервере с доменом и прочим). Здесь нам и понадобится Nginx, тк мы хотим получить полноценный вебсервер и SSL в том числе.
Для начала стоит отметить, что без SSL для тестовых запусков достаточно и npm run start на 80 порту — все заработает из коробки, ну почти, если домен напрямую прокинут на айпишники и в нашем распоряжении целый отдельный сервер.
Схема работы
Наша схема работы будет выглядеть максимально просто:
- Nginx висит, как и подобает вебсерверу, на 80 и 443 портах, обеспечивая маршрутизацию и SSL;
- Запросы мы проксируем на localhost с нужным портом, например 3000, тк он у нас по дефолту Next.
Nginx
Для простоты мы будем править напрямую основной конфигурационный файл /etc/nginx/nginx.conf, как Вы понимаете на рабочем проекте так делать не надо — разберитесь с папками /etc/nginx/sites-available/ и /etc/nginx/sites-enabled.
nano /etc/nginx/nginx.conf
Как установить Nginx , подробно описано на официальном сайте, все зависит от Вашей операционной системы очевидно.
Итак, наши настройки для сервера (выжимка), естественно *_INSERT_IP_ADRESS_* надо заменить на Ваш ip сервера и our_best_site на Ваш домен и всю структуру папок проверить (/home/our_best_site/public_html и тд):
server {
server_name our_best_site.ru www.our_best_site.ru;
listen *_INSERT_IP_ADRESS_*;
root /home/our_best_site/public_html;
index index.php index.htm index.html;
access_log /var/log/virtualmin/our_best_site.ru_access_log;
error_log /var/log/virtualmin/our_best_site.ru_error_log;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_FILENAME /home/our_best_site/public_html$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT /home/our_best_site/public_html;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param HTTPS $https;
location / {
proxy_pass http://localhost:3000/;
}
fastcgi_split_path_info ^(.+\.php)(/.+)$;
listen *_INSERT_IP_ADRESS_*:443 ssl;
ssl_certificate /home/our_best_site/ssl.combined;
ssl_certificate_key /home/our_best_site/ssl.key;
}
У Nginx куча настроек и улучшать можно постоянно, но основная магия в паре строк, те мы проксируем все запросы на «/» на наш node сервер, который мы скоро запустим:
location / {
proxy_pass http://localhost:3000/;
}
Для работы SSL, нам надо получить сертификаты в сертификационном центре и указать пути к этим файлам:
ssl_certificate /home/our_best_site/ssl.combined;
ssl_certificate_key /home/our_best_site/ssl.key;
Запускаем приложение
Какие файлы нам нужны от Next.js для запуска?
Для начала нам нужно запустить в терминале компиляцию проекта npm run build, в итоге мы увидим что-то похожее. Next создаст все необходимые файлы, статические и для рендеринга на сервере.
Осталось понять, что же нам нужно перенести на рабочий сервер в простейшем варианте, без Git и прочих полезных вещей.
Мы идем на сервер, создаем рабочую папку для Next и копируем туда файлы и папки:
- /.next — основная рабочая папка;
- /public — папка со статическими публичными файлами, например favicon.ico и robots.txt;
- next.config.js — конфигурационный файл next, куда надо не забыть включить домены для картинок и например webpack5: true;
- package.json — конфигурационный файл приложения.
Далее осталось запустить в этой папке npm install, при этом менеджер проанализирует package.json и автоматически сгенерирует папку /node_modules, со всеми необходимыми пакетами. Ее не надо копировать из среды разработки.
Все, теперь достаточно запустить npm run start или любой нужный скрипт из package.json и, если Вы правильно указали порт, а у нас Nginx проксирует на 3000, все заработает. Но, это неудобно, тк стоит закрыть терминал — все умрет. Эту проблемы нам поможет решить отличный менеджер процессов PM2.
Запускаем Nextjs через PM2 (менеджер процессов)
Подробно прочитать про этот менеджер процессов можно в мануале на официальном сайте, мы же укажем только необходимый минимум
Итак, устанавливаем pm2 командой (возможно Вам потребуется использовать sudo):
npm install pm2 -g
Запуск процессов
Для запуска проекта в простом варианте можно использовать что-то вроде, при этом не забудьте перейти в рабочую папку проекта nextjs.
pm2 start npm -- start
А так же полезные ключи:
# Указываем имя запущенного приложения
--name <app_name>
# Устанавливаем наблюдение за файлами проекта и перезапускаем приложение при их изменении
--watch
# Устанавливаем лимит памяти до перезагрузки приложения
--max-memory-restart <200MB>
# Определяем путь к файлу логов
--log <log_path>
# Прокидываем аргументы в скрипт
-- arg1 arg2 arg3
# Задержка между автоматическими перезапусками
--restart-delay <delay in ms>
# Добавлять префикс времени в логах
--time
# Не перезапускать автоматически приложение
--no-autorestart
# Определяем задачу крон для принудительного перезапуска (forced
restart)
--cron <cron_pattern>
Управление и мониторинг процессов
Для управления запущенными процессами можно использовать команды:
$ pm2 restart app_name
$ pm2 reload app_name
$ pm2 stop app_name
$ pm2 delete app_name
Вместо app_name можно использовать:
all
для управления всеми процессами;id
для управления процессом по его id.
Мониторить запущенные процессы можно парой удобных команд:
// онлайн мониторинг в экране терминала
$ pm2 monit
// список процессов
# pm2 list
Пример вывода для pm2 monit:
Итого по pm2
Теперь мы можем запустить наш проект, со всеми ключами. Представим, что наше приложение лежит в папке /home/our_best_site/public_html/nextjs:
$ cd /home/our_best_site/public_html/nextjs
$ pm2 start npm --watch --ignore-watch="node_modules" --restart-delay=10000 --name "app_name1" -- start
Из строки видно, что запускаем мы в рабочей папке наш процесс npm start с именем app_name1, при этом следим за изменениями с задержкой перезапуска 10000мс и игнорируем папку node_modules.
При этом в терминале мы увидим наше приложение:
Заключение
В результате мы получаем nextjs приложение, которое работает на 3000 порту и все запросы (80 и 443 портов) в него проксируются через nginx. Управление приложением происходит через менеджер pm2. Стоит отметить, что все написанное будет работать и для React.js приложения с минимальными правками.
Ура, все работает)