Как настроить переменные окружения Next.js на продакшене: полное руководство
Env-переменные в Next.js: секреты, публичные ключи и деплой без головной боли
Введение
Переменные окружения (env) — это способ передать приложению конфиденциальные данные (ключи API, строки подключения к БД) или настройки, зависящие от среды (URL бэкенда, режим отладки). В Next.js работа с ними имеет свои особенности: фреймворк разделяет переменные на серверные и клиентские, а также автоматически подгружает .env файлы. Если настроить неправильно, можно либо засветить секреты в браузере, либо получить ошибку undefined на продакшене.
В этом руководстве мы разберём, как правильно организовать env-переменные в Next.js для локальной разработки, тестирования и продакшена. Вы узнаете, чем отличаются NEXT_PUBLIC_ переменные от обычных, как деплоить на Vercel, Docker и VPS, и каких ошибок избегать.
Требования
Базовое знакомство с Next.js (версии 13+ с App Router или Pages Router).
Установленный Node.js 18+ и npm/yarn/pnpm.
Понимание, что такое переменные окружения в ОС.
Доступ к платформе деплоя (Vercel, Docker, VPS и т.п.).
Шаг 1: Разберитесь, какие переменные бывают в Next.js
Next.js делит переменные на два типа:
Серверные — доступны только в серверном коде (API routes,
getServerSideProps, серверные компоненты, middleware). Не попадают в клиентский бандл. Пример:DATABASE_URL,STRIPE_SECRET_KEY.Клиентские (публичные) — должны начинаться с
NEXT_PUBLIC_. Инлайнятся в JavaScript на этапе сборки и доступны в браузере. Пример:NEXT_PUBLIC_API_URL,NEXT_PUBLIC_GA_ID.
Важно: любые данные, попавшие в клиентский бандл, видны всем пользователям. Никогда не добавляйте префикс NEXT_PUBLIC_ к секретам.
Шаг 2: Создайте файлы .env для разных сред
Next.js автоматически загружает файлы в таком порядке (приоритет сверху вниз):
1. .env.$(NODE_ENV).local 2. .env.local (игнорируется при NODE_ENV=test) 3. .env.$(NODE_ENV) 4. .env
Пример структуры:
.env # общие настройки для всех сред
.env.local # локальные переопределения (не коммитить!)
.env.development # для development
.env.production # для productionДобавьте .env*.local в .gitignore, чтобы не закоммитить секреты.
Шаг 3: Задайте переменные для локальной разработки
Создайте .env.local в корне проекта:
DATABASE_URL=postgres://localhost:5432/mydb
NEXT_PUBLIC_API_URL=http://localhost:3000/apiNext.js подхватит их при next dev. Перезапустите сервер после изменения файла — hot-reload не применяет новые env.
Шаг 4: Используйте переменные в коде правильно
Серверный код (API route, серверный компонент):
// app/api/users/route.js
export async function GET() {
const dbUrl = process.env.DATABASE_URL;
// ...
}Клиентский код (компонент с 'use client'):
'use client';
export default function Page() {
const apiUrl = process.env.NEXT_PUBLIC_API_URL;
// ...
}Обращение к серверной переменной в клиентском компоненте вернёт undefined — это защита от утечки.
Шаг 5: Настройте переменные для продакшена на Vercel
Если вы используете Vercel:
1. Откройте проект в панели Vercel. 2. Перейдите в Settings → Environment Variables. 3. Добавьте каждую переменную, выбрав окружения (Production, Preview, Development). 4. Для секретов используйте тип Encrypted. 5. После добавления перезапустите деплой (Redeploy), чтобы изменения вступили в силу.
Vercel не читает .env.production из репозитория — переменные задаются только через дашборд или CLI (vercel env add).
Шаг 6: Передайте переменные при деплое в Docker
В Dockerfile не копируйте .env файлы в образ. Вместо этого передавайте переменные при запуске контейнера:
docker run -p 3000:3000 \
-e DATABASE_URL=postgres://prod-db:5432/mydb \
-e NEXT_PUBLIC_API_URL=https://api.example.com \
my-next-appИли используйте --env-file .env.production. Убедитесь, что .env.production не попал в образ (добавьте в .dockerignore).
Особенность: NEXT_PUBLIC_ переменные инлайнятся при сборке (next build). Если вы передаёте их только при запуске контейнера, они не попадут в бандл. Решение: передавайте их как build-args или используйте runtime-конфигурацию (например, через window.__ENV).
Шаг 7: Настройте переменные на VPS или выделенном сервере
При деплое на VPS (без Docker) используйте менеджер процессов (PM2, systemd) и файл .env.production:
1. Создайте .env.production на сервере вручную (не через git). 2. Установите права chmod 600 .env.production. 3. Запустите приложение с NODE_ENV=production.
Пример для PM2 (ecosystem.config.js):
module.exports = {
apps: [{
name: 'next-app',
script: 'node_modules/next/dist/bin/next',
args: 'start',
env: {
NODE_ENV: 'production',
},
}],
};PM2 автоматически загрузит .env.production? Нет, PM2 не читает env-файлы. Используйте пакет dotenv в самом приложении или передавайте переменные через env в конфиге PM2.
Шаг 8: Обеспечьте безопасность переменных
Никогда не коммитьте
.env.local,.env.productionс секретами.Используйте разные значения для development и production.
Ограничьте доступ к дашборду Vercel / серверу.
Регулярно ротируйте ключи.
Для клиентских переменных помните: они публичны. Не кладите туда API-ключи без ограничений.
Шаг 9: Проверьте сборку и работу на продакшене
Перед деплоем выполните локально:
npm run build
npm run startУбедитесь, что все переменные определены. Если чего-то не хватает, приложение может упасть с ошибкой. Добавьте валидацию env в код (например, с помощью zod):
// lib/env.js
import { z } from 'zod';
const envSchema = z.object({
DATABASE_URL: z.string().url(),
NEXT_PUBLIC_API_URL: z.string().url(),
});
export const env = envSchema.parse(process.env);Вызывайте этот модуль при старте сервера, чтобы сразу увидеть проблему.
Шаг 10: Организуйте совместную работу команды
Храните список необходимых переменных в
.env.example(без значений).Документируйте каждую переменную в README.
Используйте секрет-менеджеры (Vault, Doppler, 1Password) для команд.
Настройте CI/CD так, чтобы переменные подставлялись из защищённого хранилища.
Типичные ошибки
1. Использование `NEXT_PUBLIC_` для секретов. Ключи попадают в клиентский бандл и видны в DevTools. 2. Ожидание, что `.env.production` загрузится на Vercel. Vercel игнорирует файлы env из репозитория. 3. Забыли перезапустить dev-сервер после изменения `.env`. Next.js не подхватывает изменения на лету. 4. Передача `NEXT_PUBLIC_` переменных только в runtime Docker. Они инлайнятся при сборке, поэтому в контейнере их уже поздно менять. 5. Коммит `.env.local` в git. Секреты утекают в историю репозитория. 6. Отсутствие валидации env. Приложение падает в рантайме с неинформативной ошибкой.
FAQ
В: Можно ли использовать переменные окружения в `next.config.js`? О: Да, но помните, что next.config.js выполняется на сервере при сборке и запуске. Для клиентских переменных используйте env или publicRuntimeConfig (устарел в новых версиях).
В: Как передать переменные в клиентский компонент, если они не `NEXT_PUBLIC_`? О: Никак — это противоречит безопасности. Если данные нужны на клиенте, они должны быть публичными. Для чувствительных данных используйте API-роуты как прокси.
В: Что делать, если переменная `undefined` на продакшене? О: Проверьте, добавлена ли она в панели хостинга (Vercel, Docker env, PM2). Убедитесь, что имя совпадает, и перезапустите приложение.
В: Можно ли менять `NEXT_PUBLIC_` переменные без пересборки? О: Нет, они встраиваются в бандл при next build. Для динамических настроек используйте серверные переменные и передавайте их на клиент через API или SSR.
В: Как тестировать с разными env? О: Используйте .env.test и запускайте тесты с NODE_ENV=test. Next.js загрузит .env.test, но не .env.local.
Итог
Правильная настройка переменных окружения в Next.js — это баланс между удобством и безопасностью. Чётко разделяйте серверные и клиентские переменные, используйте .env файлы для локальной разработки и передавайте секреты через защищённые панели хостинга на продакшене. Не забывайте про валидацию и документацию — это сэкономит часы отладки. Следуя шагам из этого руководства, вы настроите env-переменные так, чтобы приложение работало стабильно в любой среде.
Читайте также
Комментарии
Комментарии доступны только зарегистрированным пользователям. Войти
- Пока нет комментариев. Будьте первым.



