Казалось бы, что развёртывание приложений на 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 приложения оказалась не такой уж и сложной. Мы отделили обработку динамических данных от статичных, облегчив работу Ноде, и даже смогли уменьшить количество запросов к серверу за счёт кэширования в браузере.

При небольших нагрузках вряд ли это даст ощутимый прирост в производительности, но с ростом числа пользователей эффект будет всё более заметным.

Комментарии (1)


  1. Max_JK
    21.12.2022 13:29
    +2

    А есть инфа на сколько выросла или упала производительность, может там такие крохи что даже этого не стоит делать.

    например тот же try_files вдруг наоборот замедлит запрос, из за того что будет каждый раз проверять файловую систему перед обращением к серверу.