Как правильно настроить переменные окружения Next.js на продакшене
Полный гайд: настройка, разграничение доступа, деплой и защита секретов
Введение
Переменные окружения — это основа конфигурации любого современного веб-приложения. В Next.js они позволяют хранить API-ключи, строки подключения к базе данных, URL внешних сервисов и другие параметры, которые не должны попадать в репозиторий. Однако при переносе проекта на продакшен многие разработчики сталкиваются с тем, что переменные «не подхватываются», оказываются доступны на клиенте или вовсе ломают сборку.
В этом руководстве мы разберём, как правильно настроить env-переменные Next.js для продакшена: какие бывают типы переменных, как их использовать в коде, как деплоить на разные платформы и каких ошибок избегать. Материал актуален для Next.js 13+ (App Router) и 12+ (Pages Router) — различия будут отмечены отдельно.
Требования
Node.js 18.17 или новее (для Next.js 14+).
Проект на Next.js (версия 12 и выше).
Базовое понимание процесса сборки (
next build) и запуска (next start).Доступ к панели управления хостингом (Vercel, Docker, VPS и т.п.).
Текстовый редактор или IDE.
Шаг 1. Разберитесь с типами переменных в Next.js
Next.js делит переменные окружения на две большие категории:
1. Серверные — доступны только в серверном коде: API-роуты, серверные компоненты, getServerSideProps, getStaticProps, middleware. Они не попадают в клиентский бандл. 2. Клиентские — доступны в браузере. Чтобы переменная стала клиентской, её имя должно начинаться с префикса NEXT_PUBLIC_.
Важно: любые переменные без префикса NEXT_PUBLIC_ не будут доступны в клиентском коде, даже если вы попытаетесь к ним обратиться. Это сделано для безопасности.
Также существует понятие «встроенных» переменных, которые Next.js подставляет автоматически: NODE_ENV, NEXT_PUBLIC_VERCEL_URL (на Vercel) и другие.
Шаг 2. Создайте файлы .env для разных окружений
Next.js поддерживает несколько файлов окружения, которые загружаются в определённом порядке:
.env— общие настройки для всех окружений..env.local— локальные переопределения, игнорируются Git..env.development— для режима разработки..env.production— для продакшен-сборки..env.test— для тестов.
Приоритет загрузки: .env.$(NODE_ENV).local > .env.local > .env.$(NODE_ENV) > .env.
Создайте в корне проекта файл .env.local для секретов разработки и .env.production для продакшен-значений (без секретов, если файл попадает в репозиторий). Не забывайте добавлять .env*.local в .gitignore.
Пример .env.local:
DATABASE_URL=postgres://user:pass@localhost:5432/mydb
NEXT_PUBLIC_API_URL=http://localhost:3000/api
SECRET_KEY=dev-secretШаг 3. Используйте переменные в серверном коде
В серверных компонентах, API-роутах и функциях вроде getServerSideProps переменные доступны через process.env:
// app/api/data/route.js
export async function GET() {
const dbUrl = process.env.DATABASE_URL;
// ...
}В Pages Router:
export async function getServerSideProps() {
const key = process.env.SECRET_KEY;
// ...
}Серверные переменные не инлайнятся в клиентский бандл, поэтому их безопасно использовать для секретов.
Шаг 4. Настройте клиентские переменные с префиксом NEXT_PUBLIC_
Если значение нужно в браузере (например, публичный URL API), добавьте префикс NEXT_PUBLIC_:
NEXT_PUBLIC_API_URL=https://api.example.comИспользование в компоненте:
const apiUrl = process.env.NEXT_PUBLIC_API_URL;Next.js заменит process.env.NEXT_PUBLIC_API_URL на конкретное значение во время сборки. Это значит, что после изменения переменной требуется пересобрать приложение.
Важно: не добавляйте префикс NEXT_PUBLIC_ к секретам — они станут видны любому пользователю в исходниках страницы.
Шаг 5. Учтите особенности App Router (Next.js 13+)
В App Router серверные компоненты по умолчанию выполняются на сервере, поэтому process.env работает как обычно. Однако если вы используете клиентские компоненты ('use client'), доступны только переменные с NEXT_PUBLIC_.
Для динамических значений на сервере можно применять unstable_noStore или динамический рендеринг, чтобы переменные читались в рантайме, а не на этапе сборки. Но помните: в серверных компонентах process.env читается при каждом запросе, если страница динамическая.
Шаг 6. Настройте переменные для продакшен-сборки
При запуске next build Next.js загружает .env.production (и .env.local, если он есть). Если вы собираете проект в CI/CD, убедитесь, что все нужные переменные доступны в окружении сборки.
Для серверных переменных, которые должны читаться в рантайме (например, при запуске next start), они должны быть заданы в окружении процесса. Next.js не подгружает .env.production автоматически при next start — только при сборке. Поэтому на продакшене переменные обычно передают через панель хостинга или системные env.
Шаг 7. Деплой на Vercel
Vercel — самый простой способ. В настройках проекта (Settings → Environment Variables) добавьте переменные для окружений Production, Preview и Development. После добавления нужно перезапустить деплой, чтобы изменения вступили в силу.
Особенности:
Переменные с
NEXT_PUBLIC_доступны на клиенте.Секреты без префикса доступны только серверным функциям.
Можно задавать разные значения для Preview и Production.
Шаг 8. Деплой в Docker
При сборке Docker-образа передавайте переменные через ARG и ENV:
ARG NEXT_PUBLIC_API_URL
ENV NEXT_PUBLIC_API_URL=$NEXT_PUBLIC_API_URL
RUN npm run buildСерверные секреты лучше передавать в рантайме через docker run -e или docker-compose, чтобы они не попали в слои образа. Помните: переменные, использованные на этапе сборки, «запекаются» в бандл.
Шаг 9. Деплой на собственный сервер (VPS)
Если вы используете next start на VPS, задайте переменные в systemd-юните, в файле .env.production рядом с проектом (но тогда Next.js не загрузит его автоматически при старте) или через менеджер процессов (PM2).
Надёжный вариант — экспортировать переменные в shell перед запуском:
export DATABASE_URL=...
export NEXT_PUBLIC_API_URL=...
npm run startЛибо используйте пакет dotenv и загружайте .env.production вручную в кастомном сервере.
Шаг 10. Проверьте, что переменные не утекли в клиент
После сборки можно проанализировать клиентский бандл на наличие секретов. Ищите строки, которые не должны быть публичными. Если секрет попал в .next/static, значит, вы случайно использовали его в клиентском компоненте или дали префикс NEXT_PUBLIC_.
Также полезно добавить в CI шаг с grep по собранным файлам на предмет запрещённых значений.
Шаг 11. Валидируйте переменные при старте
Чтобы приложение не падало в рантайме из-за отсутствующей переменной, добавьте проверку. Например, создайте файл env.js:
const required = ['DATABASE_URL', 'SECRET_KEY'];
for (const key of required) {
if (!process.env[key]) {
throw new Error(`Missing env: ${key}`);
}
}Импортируйте его в next.config.js или в серверной точке входа. Это поможет выявить проблему сразу после деплоя.
Шаг 12. Используйте типизацию для TypeScript
Чтобы избежать опечаток, объявите типы для process.env в env.d.ts:
declare namespace NodeJS {
interface ProcessEnv {
DATABASE_URL: string;
NEXT_PUBLIC_API_URL: string;
}
}Это даст автодополнение и проверку на этапе компиляции.
Типичные ошибки
1. Использование секретов с префиксом NEXT_PUBLIC_ — приводит к утечке ключей в клиентский бандл. 2. Ожидание, что .env.production загрузится при next start — Next.js загружает env-файлы только на этапе сборки; в рантайме переменные нужно передавать через окружение. 3. Изменение переменной без пересборки — клиентские переменные инлайнятся при сборке, поэтому после изменения требуется новый билд. 4. Отсутствие переменных в CI/CD — сборка падает или получает неверные значения. 5. Хранение .env.local в Git — секреты попадают в репозиторий. 6. Использование process.env в клиентском компоненте без префикса — переменная будет undefined. 7. Забыли добавить переменные в Vercel/хостинг — приложение работает локально, но не на проде. 8. Динамическое чтение серверных переменных в статически сгенерированных страницах — значения фиксируются на этапе сборки.
FAQ
В: Можно ли использовать переменные окружения в next.config.js? О: Да, но они доступны только на этапе сборки. Для клиента их нужно явно прокинуть через env в конфиге (не рекомендуется для секретов).
В: Как передать переменные в middleware? О: Middleware выполняется на сервере (Edge), поэтому process.env доступен. Учтите, что на Edge некоторые Node.js API недоступны.
В: Что делать, если переменная нужна и на клиенте, и на сервере? О: Создайте две переменные: одну с NEXT_PUBLIC_ для клиента, другую без префикса для сервера, если значения различаются. Либо используйте одну NEXT_PUBLIC_, если значение не секретное.
В: Как обновить переменные на Vercel без пересборки? О: Никак для клиентских переменных — нужен редеплой. Серверные переменные в Serverless Functions подхватываются при следующем вызове функции, но для надёжности лучше перезапустить деплой.
В: Поддерживает ли Next.js переменные из системного окружения? О: Да, process.env включает как переменные из .env-файлов, так и системные.
Итог
Правильная настройка переменных окружения в Next.js на продакшене строится на трёх принципах: чёткое разделение серверных и клиентских переменных, передача секретов только через защищённые каналы и обязательная пересборка при изменении клиентских значений. Используйте префикс NEXT_PUBLIC_ только для действительно публичных данных, валидируйте переменные при старте и не храните секреты в репозитории. Следуя шагам из этого руководства, вы сможете безопасно конфигурировать приложение на Vercel, в Docker или на собственном сервере.
Читайте также
Комментарии
Комментарии доступны только зарегистрированным пользователям. Войти
- Пока нет комментариев. Будьте первым.



