Production-деплой Next.js на VPS: пошаговое руководство
18 марта 2026 г.
После того как Next.js приложение готово и отлично работает на локальной машине, встаёт главный вопрос: как правильно выкатить его в production? Платформы вроде Vercel делают деплой максимально простым, но часто требования к инфраструктуре, стоимость или необходимость полного контроля заставляют выбирать самостоятельный хостинг на VPS.
В этом руководстве мы детально разберём production-деплой Next.js на виртуальный выделенный сервер (VPS). Вы узнаете о двух основных подходах: классической настройке с использованием PM2 и современном способе через Docker. Мы настроим веб-сервер Nginx в качестве reverse proxy, обеспечим безопасность с помощью SSL-сертификатов от Let's Encrypt и рассмотрим ключевые моменты оптимизации.
Что такое production-деплой и почему VPS?
Production-деплой — это процесс размещения вашего приложения на сервере, доступном конечным пользователям. В отличие от development-среды, production требует стабильности, безопасности, производительности и автоматического восстановления после сбоев.
VPS (Virtual Private Server) — это виртуальный сервер, который даёт вам полный контроль над окружением. Вы сами выбираете ПО, настраиваете безопасность и оптимизируете ресурсы. Это отличный выбор для проектов, которые переросли бесплатные лимиты serverless-платформ или требуют специфической инфраструктуры.
Подготовка сервера (VPS)
Для начала вам потребуется арендованный VPS. Мы будем использовать сервер с Ubuntu 22.04 LTS, так как это наиболее распространённый и стабильный дистрибутив. Подойдёт практически любой провайдер, например TimewebCloud или хостинг 1Gb.
Базовая настройка сервера
Первым делом подключаемся к серверу по SSH:
ssh root@ip-адрес-вашего-сервераСразу после входа рекомендуется обновить пакеты и создать отдельного пользователя (не рекомендуется работать под root):
apt update && apt upgrade -y
adduser deploy
usermod -aG sudo deployНастройте SSH-ключи для нового пользователя и отключите вход по паролю в файле /etc/ssh/sshd_config для повышения безопасности.
Установка зависимостей
Для работы Next.js на сервере нам понадобятся Node.js, npm, Git и, опционально, Docker. Установим Node.js 20.x (LTS):
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
apt install -y nodejs git nginxПроверьте версии: node -v, npm -v.
Метод 1: Классический деплой с PM2 и Node.js
Этот метод подразумевает запуск Next.js как Node.js-процесса под управлением менеджера процессов PM2. PM2 автоматически перезапустит приложение в случае падения и поможет управлять логами.
Подготовка приложения
Переключитесь на пользователя deploy и клонируйте репозиторий вашего проекта:
sudo -i -u deploy
cd ~
git clone ваш-репозиторий my-next-app
cd my-next-app
npm ciКоманда npm ci используется для чистой установки зависимостей точно по package-lock.json, что предпочтительнее для production-сборок.
Сборка и запуск
Соберите production-версию приложения:
npm run buildЗапустить сервер можно командой npm start, но для production мы будем использовать PM2. Установите PM2 глобально:
sudo npm i -g pm2Затем запустите Next.js через PM2:
pm2 start npm --name "next-app" -- start
pm2 save
pm2 startup systemdПоследняя команда создаст systemd-юнит, который будет автоматически запускать PM2 и ваше приложение после перезагрузки сервера.
Настройка PM2 для управления процессом
Для более тонкой настройки создайте файл ecosystem.config.js в корне проекта:
module.exports = {
apps: [
{
name: 'next-app',
script: 'node_modules/next/dist/bin/next',
args: 'start',
instances: 1,
autorestart: true,
watch: false,
max_memory_restart: '1G',
env: {
NODE_ENV: 'production',
PORT: 3000
}
}
]
};Запускать приложение теперь можно командой pm2 start ecosystem.config.js.
Метод 2: Современный деплой с Docker
Docker позволяет упаковать приложение со всеми зависимостями в изолированный контейнер. Это гарантирует идентичность окружения на всех этапах — от разработки до продакшна.
Dockerfile для Next.js
Создайте в корне проекта файл Dockerfile:
# Этап сборки
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json .
RUN npm ci
COPY . .
RUN npm run build
# Этап запуска
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV production
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
# Копируем необходимые файлы из этапа сборки
COPY --from=builder /app/public ./public
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT 3000
CMD ["node", "server.js"].dockerignore и multi-stage build
Важно создать файл .dockerignore, чтобы не копировать в образ лишние файлы:
node_modules
.git
.next
Dockerfile
.dockerignore
README.mdОбратите внимание на флаг standalone. Чтобы он работал, в файле next.config.js должна быть включена опция:
module.exports = {
output: 'standalone',
// ... остальные настройки
}Это создаст минимальную самостоятельную сборку, включающую только необходимые файлы.
Запуск контейнера
Соберите образ и запустите контейнер:
docker build -t my-next-app .
docker run -d --name next-app -p 3000:3000 my-next-appДля автоматического перезапуска можно использовать политики рестарта Docker (--restart unless-stopped) или более продвинутые инструменты оркестрации.
Настройка Nginx как reverse proxy
Независимо от того, запустили ли вы приложение через PM2 или Docker, оно слушает порт 3000. Напрямую открывать этот порт в мир — не лучшая идея. Мы используем Nginx в качестве reverse proxy: он будет принимать запросы пользователей на 80-м (HTTP) и 443-м (HTTPS) портах и перенаправлять их на наш Next.js сервер.
Конфигурация Nginx
Создайте файл конфигурации для вашего сайта:
sudo nano /etc/nginx/sites-available/my-next-appСодержимое:
server {
listen 80;
server_name your-domain.com www.your-domain.com;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Для статических файлов можно добавить кеширование
location /_next/static {
alias /path/to/your/app/.next/static;
expires 365d;
}
}Активируйте конфигурацию:
sudo ln -s /etc/nginx/sites-available/my-next-app /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginxДобавление SSL-сертификата (Let's Encrypt)
Безопасность превыше всего. Установим Certbot и получим бесплатный SSL-сертификат:
apt install -y certbot python3-certbot-nginx
certbot --nginx -d your-domain.com -d www.your-domain.comCertbot автоматически обновит конфигурацию Nginx, добавив настройки для HTTPS, и настроит автоматическое продление сертификатов.
Настройка environment-переменных
Переменные окружения для production (например, API-ключи, строки подключения к БД) не должны храниться в коде. Для Next.js важно помнить, что переменные с префиксом NEXT_PUBLIC_ встраиваются в сборку на этапе build. Поэтому для них нужно передавать значения непосредственно перед npm run build.
Самый простой способ — создать файл .env.production в корне проекта на сервере (и убедиться, что он добавлен в .gitignore!). Пример:
DATABASE_URL=postgresql://user:pass@localhost:5432/db
API_SECRET=supersecretkey
NEXT_PUBLIC_ANALYTICS_ID=UA-XXXXXПри использовании Docker переменные можно передать через -e или использовать файл .env.
Оптимизация для production
Простой деплой — это только начало. Для боевого проекта стоит обратить внимание на следующие моменты:
- Кеширование: Настройте Nginx для кеширования статических файлов (
_next/static, изображения). - Сжатие: Включите gzip или brotli сжатие в Nginx для уменьшения размера передаваемых данных.
- Мониторинг: Используйте
pm2 monit, логи Docker или подключайте специализированные сервисы для отслеживания состояния приложения. - Балансировка: Для высоких нагрузок можно запустить несколько экземпляров приложения (через
pm2сinstances: maxили несколько Docker-контейнеров) и настроить Nginx для балансировки нагрузки между ними.
Типичные ошибки и их решение
| Проблема | Вероятная причина | Решение |
|---|---|---|
| 502 Bad Gateway от Nginx | Next.js сервер не запущен или упал | Проверьте pm2 status или docker ps. Посмотрите логи: pm2 logs или docker logs. |
| 404 на страницах, кроме главной | Неверная конфигурация Nginx для клиентской маршрутизации | Убедитесь, что в location / настроен proxy_pass и передаются все необходимые заголовки. |
| Ошибки, связанные с переменными окружения | Переменные NEXT_PUBLIC_* не были доступны на этапе сборки | Передайте их в команду npm run build или определите в файле .env.production перед сборкой. |
| Приложение не стартует после перезагрузки сервера | PM2 не настроен на автозапуск или Docker контейнер не имеет политики restart | Выполните pm2 startup и pm2 save. Для Docker используйте флаг --restart unless-stopped. |
Заключение
Мы рассмотрели два основных подхода к деплою Next.js приложения на VPS: классический с PM2 и современный с Docker. Каждый из них имеет право на жизнь. PM2 проще для понимания, если вы только начинаете, Docker же даёт большую воспроизводимость и изоляцию.
Выбор VPS-провайдера — важный шаг. Обратите внимание на репутацию, качество поддержки и удобство панели управления. Например, TimewebCloud предлагает гибкие тарифы и удобные инструменты для управления серверами.
Помните, что деплой — это не разовая задача. Регулярно обновляйте зависимости, следите за логами и безопасностью сервера. Автоматизируйте процессы с помощью CI/CD (например, GitHub Actions) — это тема для отдельной статьи.
Что почитать дальше
Дополнительные материалы из архива, которые могут быть полезны после этой статьи.
Настройка Nginx на VPS сервере
Пошаговое руководство по установке, настройке и оптимизации веб-сервера Nginx на VPS. Базовая конфигурация, виртуальные…
Читать далее
Полное руководство по CI/CD для Next.js в GitLab: от базовой настройки до продакшн-пайплайна
Подробное руководство по настройке CI/CD для Next.js приложений с GitLab CI. Разбираем каждый этап пайплайна, кэширован…
Читать далее
Работа с Docker на хостинге: от локального контейнера до продакшен-сервера
Полное руководство по запуску Docker на VPS: установка, настройка volume'ов, работа с Docker Compose, обеспечение безоп…
Читать далее