Переменные окружения в Node.js: конфигурация и секреты

Содержание

О проверке кода. Примеры не запускались в этой сессии (по договорённости — фокус на контенте, а не прогонах). Говорим прямо, а не ставим бейдж «проверено».

Одно и то же приложение работает на ноутбуке разработчика и на боевом сервере — но с разными адресами БД, ключами и настройками. Переменные окружения в Node.js отделяют конфигурацию от кода. Разберём их и правила безопасности.

process.env: чтение конфигурации

const port = process.env.PORT || 3000;          // порт или значение по умолчанию
const dbUrl = process.env.DATABASE_URL;
const apiKey = process.env.API_KEY;

console.log(`Сервер на порту ${port}`);

process.env — объект со всеми переменными окружения процесса. В них держат то, что меняется между окружениями: порт, адрес базы, ключи внешних сервисов. Код остаётся один — настройки приходят снаружи. Задать переменную можно при запуске:

PORT=8080 DATABASE_URL=... node app.js

Ловушка: значения всегда строки.

process.env.PORT;          // '8080' — СТРОКА, не число!
Number(process.env.PORT);  // 8080 — приводим явно
process.env.DEBUG === 'true';  // флаги сравнивают со строкой

Порт, лимиты, числовые настройки приводят через Number, булевы флаги сравнивают со строкой 'true'. Забыть про это — частая ошибка.

Главное правило: секреты не в коде

// ❌ КАТАСТРОФА — ключ попадёт в git и историю навсегда
const stripeKey = 'sk_live_51H8xY2eZ...';

// ✅ ключ снаружи, в коде только ссылка на переменную
const stripeKey = process.env.STRIPE_KEY;

Секреты в коде — это утечка. Код попадает в git, виден всем с доступом к репозиторию и остаётся в истории коммитов навсегда — даже если удалить позже, он извлекается из прошлых версий. Ключи API, пароли БД, токены хранят только в переменных окружения. Публичные репозитории регулярно сканируются ботами на утёкшие ключи — счёт идёт на минуты.

Что в коде, что в переменных окружения

В коде (git)

Не секретное

  • Логика приложения
  • Ссылки process.env.X
  • Значения по умолчанию для dev
  • Файл .env.example без значений

В переменных окружения

Секретное и изменчивое

  • Ключи API, токены
  • Пароли и адрес БД
  • Порт, домены, настройки
  • .env → в .gitignore!

Файл .env

Держать десяток переменных в командной строке неудобно — их выносят в файл .env:

# .env — НЕ коммитить в git!
PORT=8080
DATABASE_URL=postgres://localhost/myapp
API_KEY=secret123
NODE_ENV=development

Загрузка — встроенным флагом Node (без пакетов):

node --env-file=.env app.js

Свежие версии Node читают .env сами через --env-file — отдельный пакет не нужен. В старых проектах для этого ставят dotenv:

require('dotenv').config();   // старый способ — заполняет process.env из .env

Обязательно добавьте .env в .gitignore — иначе секреты уедут в репозиторий, и весь смысл теряется. В git кладут только .env.example — тот же файл с именами переменных, но без значений, как шаблон для других разработчиков.

NODE_ENV: разделение окружений

const isProd = process.env.NODE_ENV === 'production';

if (isProd) {
  // продакшн: минимум логов, кэширование, оптимизации
} else {
  // разработка: подробные логи, стек ошибок, автоперезагрузка
}

NODE_ENV — соглашение для различения окружений: development на машине разработчика, production на сервере, test в тестах. По нему включают разное поведение — подробные логи и стектрейсы в разработке, оптимизации и скрытие деталей ошибок в продакшене. Многие библиотеки (включая Express) сами смотрят на NODE_ENV и меняют режим.

Проверка обязательных переменных

// приложение должно падать сразу, если секрет не задан
const required = ['DATABASE_URL', 'API_KEY'];
for (const name of required) {
  if (!process.env[name]) {
    throw new Error(`Не задана обязательная переменная ${name}`);
  }
}

Проверяйте наличие критичных переменных при старте. Лучше упасть сразу с понятной ошибкой, чем работать наполовину и рухнуть посреди обработки запроса, когда впервые понадобится API_KEY. Это дешёвая страховка от «забыл настроить окружение».

Практика

  • никогда не коммитьте .env — сразу в .gitignore;
  • храните .env.example с именами переменных как документацию;
  • на хостинге переменные задают в панели окружения (не файлом), а секреты — в защищённом хранилище;
  • значения всегда приводите к нужному типу — они строки;
  • проверяйте обязательные переменные на старте.

Это фундамент безопасного и переносимого приложения: один код, разные настройки, секреты в безопасности.


Смежные темы: HTTP-клиент fetch — где хранить токены API; логирование — режим по NODE_ENV; Express с нуля — конфигурация сервера. Полный список — в уроках Node.js.

Частые вопросы

Что такое переменные окружения в Node.js?
Значения, которые задаются вне кода — в системе или файле .env — и читаются через process.env. В них хранят конфигурацию и секреты: порт, адрес базы, ключи API. Код один, а настройки меняются под окружение.
Почему нельзя хранить секреты в коде?
Код попадает в git и виден всем, у кого есть доступ к репозиторию, а также в историю коммитов навсегда. Ключи API и пароли в коде — это утечка. Секреты держат в переменных окружения, а файл .env добавляют в gitignore.
Как загрузить файл .env в Node.js?
В свежих версиях Node есть встроенный флаг –env-file=.env, отдельный пакет не нужен. В старых проектах используют пакет dotenv, который читает .env и заполняет process.env при старте приложения.
Что такое process.env?
Объект со всеми переменными окружения текущего процесса. Значения всегда строки, поэтому число порта приводят через Number, а флаги сравнивают со строкой. Обращение к несуществующей переменной даёт undefined.
Как хранить разные настройки для разработки и продакшена?
Через переменную NODE_ENV со значением development или production и отдельные файлы .env для каждого окружения. Код читает NODE_ENV и включает нужное поведение — подробные логи в разработке, оптимизации в продакшене.