Казалось бы, что развёртывание приложений на Next.js не влечёт за собой трудностей - установил зависимости, сделал "npm run build && npm run start" и проксируешь запросы на 3000-ый порт, но для оптимальной работы предстоит сделать кое-что ещё.
В данной статье мы рассмотрим как правильно сконфигурировать веб-сервер для Next.js приложения на примере Nginx.
Минимальная конфигурация выглядит так (для упрощения обойдёмся без https):
server {
server_name example.com;
location / {
include proxy_params;
proxy_pass http://127.0.0.1:3000;
}
listen 80;
}
С этим конфигом вы действительно сможете увидеть на "example.com" свой сайт на Next.js, но есть загвоздка. Next позволяет нам генерировать статичные файлы - css, js, html и даже медиа файлы. В примере выше Node.js будет обрабатывать всю эту статику самостоятельно, но зачем нам это, когда у нас есть Nginx, которому нет равных в обработке статики? Нужно отдать эту задачу ему.
После "npm run build" наш фреймворк сгенерирует директорию ".next", в которой помимо всего прочего будут нужные нам статичные файлы.
Страницы
Начнём со статичных страниц. Они будут расположены в ".next/server/pages". Пути к ним будут такими же как и в файловой структуре вашего проекта.
server {
server_name example.com;
root /var/www/nextjs/.next/server/pages;
location @proxy {
include proxy_params;
proxy_pass http://127.0.0.1:3000;
}
location / {
try_files $uri $uri/ $uri/index.html @proxy;
}
listen 80;
}
В примере выше мы добавили именованное расположение "@proxy", которое изначально являлось корневым расположение, а в блок "location /" поместили обычный "try_files" с фоллбэком в "@proxy". То есть если страница не была найдена в .next/server/pages, то отдаём обработку запроса Нексту, чтобы он поискал её среди динамических страниц.
CSS, JS и медиа
С html страницами мы разобрались, теперь пришло время стилей, JavaScript и медиа. Всё это находится в ".next/static" и нам нужно будет просто искать файлы, запрашиваемые в "example.com/_next/static", в этой директории.
server {
server_name example.com;
set $root /var/www/nextjs/.next;
location @proxy {
include proxy_params;
proxy_pass http://127.0.0.1:3000;
}
location / {
root $root;
try_files $uri $uri/ $uri/index.html @proxy;
}
location /_next/static {
alias $root/static;
expires 1y;
try_files $uri $uri/ =404;
}
listen 80;
}
Теперь наш веб-сервер обрабатывает все файлы, которые размещены в ".next/static", и они даже кэшируются браузером клиента на 1 год.
Для удобства в отдельную переменную был выделен путь к root директории, она нам понадобится и дальше, ведь это ещё не всё.
Public
Большая часть работы сделана — страницы, css, JavaScript и меди файлы обрабатываются Nginx'ом, но у нас скорее всего остались файлы в "./public", которые Next.js не сгенерировал, например, "favicon", "manifest" и т.д. Исправим это.
server {
server_name example.com;
set $root /var/www/nextjs;
set $build $root/.next;
location @proxy {
include proxy_params;
proxy_pass http://127.0.0.1:3000;
}
location @public {
root $root/public;
try_files $uri @proxy;
}
location / {
root $build;
try_files $uri $uri/ $uri/index.html @public;
}
location /_next/static {
alias $build/static;
expires 1y;
try_files $uri $uri/ =404;
}
listen 80;
}
Что изменили:
Поменяли значение переменной "$root" на "/var/www/nextjs"
Создали переменную "$build" со значением "$root/.next"
Добавили блок "location @public", который ищет файлы в "/var/www/nextjs/public", а если не находит, то передаёт обработку блоку "location @proxy"
В "location /" фоллбэк "@proxy" был заменён на "@public"
В расположениях "/" и "/_next/static" "$root" был заменён на "$build"
Сравнение
Изначально наш конфиг был таким:
server {
server_name example.com;
location / {
include proxy_params;
proxy_pass http://127.0.0.1:3000;
}
listen 80;
}
И в итоге превратился в такой:
server {
server_name example.com;
set $root /var/www/nextjs;
set $build $root/.next;
location @proxy {
include proxy_params;
proxy_pass http://127.0.0.1:3000;
}
location @public {
root $root/public;
try_files $uri @proxy;
}
location / {
root $build;
try_files $uri $uri/ $uri/index.html @public;
}
location /_next/static {
alias $build/static;
expires 1y;
try_files $uri $uri/ =404;
}
listen 80;
}
Заключение
Настройка Nginx для Next.js приложения оказалась не такой уж и сложной. Мы отделили обработку динамических данных от статичных, облегчив работу Ноде, и даже смогли уменьшить количество запросов к серверу за счёт кэширования в браузере.
При небольших нагрузках вряд ли это даст ощутимый прирост в производительности, но с ростом числа пользователей эффект будет всё более заметным.