Переменные окружения vs удалённая конфигурация: когда что использовать

«Просто положи в переменную окружения» — частый совет. И часто он правильный — переменные окружения просты, безопасны и поддерживаются повсеместно. Но иногда это неподходящий инструмент.

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

Интересное
Последние новости в мире программирования
Самые свежие новости и полезные материалы в моем telegram канале.
go

Как работают переменные окружения

Переменные окружения — это пары ключ-значение, доступные процессу:

const databaseUrl = process.env.DATABASE_URL
const apiKey = process.env.API_KEY
const logLevel = process.env.LOG_LEVEL ?? 'INFO'

Они устанавливаются вне вашего кода — в shell-скриптах, файлах Docker Compose или настройках облачной платформы:

# docker-compose.yml
services:
  app:
    environment:
      - DATABASE_URL=postgresql://localhost/mydb
      - LOG_LEVEL=DEBUG

Переменные окружения:

  • Читаются один раз при старте процесса
  • Статичны на протяжении жизни процесса
  • Ограничены одним процессом (и его дочерними)

Как работает удалённая конфигурация

Удалённая конфигурация получает значения с внешнего сервера:

import { Replane } from '@replanejs/sdk'

interface Configs {
  'rate-limit': number
  'new-feature-enabled': boolean
}

const replane = new Replane<Configs>()

await replane.connect({
  sdkKey: process.env.REPLANE_SDK_KEY!,
  baseUrl: 'https://cloud.replane.dev',
})

const rateLimit = replane.get('rate-limit')
const featureEnabled = replane.get('new-feature-enabled')

Удалённая конфигурация:

  • Читается во время работы (постоянно обновляется)
  • Динамична (меняется без перезапуска)
  • Общая для всех экземпляров

В чём ключевое отличие между переменными окружения и удалённой конфигурацией?

Переменные окружения безопаснее
Удалённая конфигурация использует меньше памяти
Переменные окружения статичны, удалённая конфигурация динамична
Переменные окружения читаются быстрее

Когда использовать переменные окружения

Переменные окружения — правильный выбор для:

Интересное
Последние новости в мире программирования
Самые свежие новости и полезные материалы в моем telegram канале.
go

Секреты и учётные данные

API-ключи, пароли баз данных и ключи шифрования должны храниться в переменных окружения (или менеджере секретов):

// Хорошо: секреты в переменных окружения
const stripeKey = process.env.STRIPE_API_KEY
const dbPassword = process.env.DATABASE_PASSWORD

Почему? Секреты чувствительны и должны:

  • Никогда не появляться в панелях управления или логах
  • Ротироваться через безопасные каналы
  • Иметь строгий контроль доступа

Системы удалённой конфигурации не предназначены для управления секретами.

Строки подключения и эндпоинты

URL баз данных и эндпоинты сервисов редко меняются во время работы:

// Хорошо: информация о подключении в переменных окружения
const databaseUrl = process.env.DATABASE_URL
const redisUrl = process.env.REDIS_URL
const apiGateway = process.env.API_GATEWAY_URL

Эти значения привязаны к инфраструктуре. При их изменении обычно нужно перезапустить соединения в любом случае.

Настройки, специфичные для среды

Настройки, различающиеся между dev/staging/production, но не меняющиеся внутри среды:

// Хорошо: конфигурация среды в переменных окружения
const environment = process.env.ENVIRONMENT ?? 'development'
const debugMode = process.env.DEBUG === 'true'
Интересное
Последние новости в мире программирования
Самые свежие новости и полезные материалы в моем telegram канале.
go

Конфигурация времени сборки

Настройки, нужные при сборке (не во время работы):

# Сборка с определёнными настройками
NEXT_PUBLIC_API_URL=https://api.example.com npm run build

Когда использовать удалённую конфигурацию

Удалённая конфигурация — правильный выбор для:

Feature flags

Переключатели, которые должны меняться мгновенно без деплоя:

// Хорошо: feature flags в удалённой конфигурации
if (replane.get('new-checkout-enabled')) {
  showNewCheckout()
}

Вы хотите включить функцию для 10% пользователей, следить за метриками, затем увеличить до 100% — всё без деплоя.

Интересное
Последние новости в мире программирования
Самые свежие новости и полезные материалы в моем telegram канале.
go

Операционные параметры

Настройки, которые вы подстраиваете под реальные условия:

// Хорошо: операционная настройка в удалённой конфигурации
const rateLimit = replane.get('api-rate-limit')
const cacheTtl = replane.get('cache-ttl-seconds')
const batchSize = replane.get('worker-batch-size')

При всплеске трафика может потребоваться снизить лимиты. При замедлении базы данных — увеличить таймауты. Удалённая конфигурация позволяет реагировать за секунды.

Kill switches

Аварийные элементы управления для отключения функций:

// Хорошо: kill switch в удалённой конфигурации
if (replane.get('payments-enabled', { default: true })) {
  processPayment()
} else {
  showMaintenanceMessage()
}

Когда платежи ломаются в 2 часа ночи, вы переключаете флаг вместо аварийного деплоя.

Настройки для пользователей или клиентов

Разные клиенты получают разные значения:

// Хорошо: конфигурация по клиентам в удалённой конфигурации
const maxUsers = replane.get('max-users', {
  context: { tenant: tenant.id }
})

Enterprise-клиенты могут получить 10 000 пользователей, а бесплатный тариф — 10.

Где хранить пароль подключения к базе данных?

Переменная окружения или менеджер секретов
Удалённая конфигурация
Захардкодить в приложении
В JSON-файле конфигурации
Интересное
Последние новости в мире программирования
Самые свежие новости и полезные материалы в моем telegram канале.
go

Структура принятия решений

Вот простая схема для выбора места хранения конфигурации:

Это секрет? ──────Да──────► Переменная окружения
      │                      (или менеджер секретов)
      Нет
      ▼
Должно меняться ──Да──► Удалённая конфигурация
без перезапуска?
      │
      Нет
      ▼
Переменная окружения

Или в виде таблицы:

| Тип конфигурации | Где хранить | |------------------|-------------| | API-ключи, пароли | Переменная окружения / Менеджер секретов | | URL баз данных | Переменная окружения | | Feature flags | Удалённая конфигурация | | Лимиты, таймауты | Удалённая конфигурация | | Kill switches | Удалённая конфигурация | | Настройки сборки | Переменная окружения | | Настройки по пользователям | Удалённая конфигурация |

Комбинирование подходов

На практике вы будете использовать оба. Вот типичный паттерн:

import { Replane } from '@replanejs/sdk'

// Статическая конфигурация из окружения (секреты, подключения)
const DATABASE_URL = process.env.DATABASE_URL!
const STRIPE_KEY = process.env.STRIPE_API_KEY!
const ENVIRONMENT = process.env.ENVIRONMENT ?? 'development'

interface Configs {
  'rate-limit': number
  'feature-enabled': boolean
}

// Сам SDK-ключ берётся из переменной окружения
const replane = new Replane<Configs>()

await replane.connect({
  sdkKey: process.env.REPLANE_SDK_KEY!,
  baseUrl: 'https://cloud.replane.dev',
})

// Динамическая конфигурация из удалённого источника (функции, настройки)
function getRateLimit(): number {
  return replane.get('rate-limit', { default: 100 })
}

function isFeatureEnabled(name: keyof Configs, userContext?: Record<string, unknown>): boolean {
  if (userContext) {
    return replane.get(name, { context: userContext, default: false }) as boolean
  }
  return replane.get(name, { default: false }) as boolean
}

Обратите внимание, что даже SDK-ключ удалённой конфигурации берётся из переменной окружения — вы используете переменные окружения для действительно статичных, секретных значений.

Распространённые ошибки

Интересное
Последние новости в мире программирования
Самые свежие новости и полезные материалы в моем telegram канале.
go

Секреты в удалённой конфигурации

// Плохо: секреты в удалённой конфигурации
const stripeKey = replane.get('stripe-api-key')

Панели удалённой конфигурации показывают значения открытым текстом. Логи могут их захватить. Используйте переменные окружения или менеджер секретов для секретов.

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

// Плохо: динамические значения как переменные окружения требуют перезапуска
const FEATURE_NEW_CHECKOUT = process.env.FEATURE_NEW_CHECKOUT === 'true'
const RATE_LIMIT = parseInt(process.env.RATE_LIMIT ?? '100', 10)

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

Нет значений по умолчанию для удалённой конфигурации

// Плохо: выбросит ошибку, если сервер конфигурации недоступен
const rateLimit = replane.get('rate-limit')

// Хорошо: есть значение по умолчанию
const rateLimit = replane.get('rate-limit', { default: 100 })

Приложение должно работать (пусть и ограниченно), даже если удалённая конфигурация временно недоступна.

Интересное
Последние новости в мире программирования
Самые свежие новости и полезные материалы в моем telegram канале.
go

Инструменты для удалённой конфигурации

Если вы решили использовать удалённую конфигурацию, вот некоторые варианты:

  • Replane — Open-source, обновления в реальном времени через SSE, self-hosted или облако
  • LaunchDarkly — Enterprise feature flags
  • AWS AppConfig — Управляется AWS, хорош для AWS-окружений
  • Consul — Service mesh с KV-хранилищем

Для self-hosting и open-source Replane стоит рассмотреть — он обрабатывает версионирование, откат и имеет SDK для нескольких языков.

Итоги

Используйте переменные окружения для:

  • Секретов и учётных данных
  • Строк подключения и эндпоинтов
  • Настроек, специфичных для среды (dev/staging/prod)
  • Конфигурации времени сборки

Используйте удалённую конфигурацию для:

  • Feature flags
  • Операционной настройки (лимиты, таймауты)
  • Kill switches
  • Настроек по пользователям или клиентам

Ключевой вопрос: «Должно ли это меняться без перезапуска приложения?» Если да — используйте удалённую конфигурацию. Если нет — переменные окружения проще.

Упражнения

  1. Проведите аудит конфигурации: Посмотрите на приложение, над которым работали. Категоризируйте каждое значение конфигурации как «должно быть переменной окружения» или «должно быть удалённой конфигурацией».

  2. Мигрируйте значение: Возьмите одно значение, которое сейчас в переменной окружения, но должно быть динамическим, и реализуйте его через удалённую конфигурацию.

  3. Спроектируйте архитектуру конфигурации: Для нового приложения спроектируйте стратегию конфигурации. Что идёт в переменные окружения? Что в удалённую конфигурацию? Задокументируйте свои решения.

Если хотите всегда быть в курсе последних новостей в мире программирования и IT, подписываетесь на мой Telegram-канал, где я делюсь свежими статьями, новостями и полезными советами. Буду рад видеть вас среди подписчиков!

Обсуждение