Переменные окружения: .env
Переменные окружения — способ хранения конфигурации и секретов (паролей, API-ключей) вне кода:
.env-файл содержит их локально, в продакшне задаются через сервер или CI/CD.
Зачем нужно
Хардкодить пароли и ключи в коде опасно: они попадают в Git и становятся публичными. .env-файл хранит конфигурацию отдельно и добавляется в .gitignore. Разные среды (development, staging, production) имеют разные значения одних и тех же переменных — это стандартный паттерн 12-factor app.
Где используется
- Строки подключения к БД (
DATABASE_URL) - API-ключи внешних сервисов (Stripe, Twilio, SendGrid)
- JWT secrets, session secrets
- Параметры конфигурации среды (
NODE_ENV,PORT,LOG_LEVEL)
Основной контент
Файл .env
# .env — только для локальной разработки, в .gitignore!
NODE_ENV=development
PORT=3000
DATABASE_URL=postgres://user:password@localhost:5432/mydb
REDIS_URL=redis://localhost:6379
JWT_SECRET=local-dev-secret-not-for-production
STRIPE_SECRET_KEY=sk_test_...
SENDGRID_API_KEY=SG.xxx...
# Опциональные с дефолтами
LOG_LEVEL=debug
MAX_CONNECTIONS=10
.env.example — шаблон для команды
# .env.example — КОММИТИТСЯ в Git (без реальных значений)
NODE_ENV=
PORT=3000
DATABASE_URL=postgres://user:password@localhost:5432/mydb
REDIS_URL=redis://localhost:6379
JWT_SECRET=
STRIPE_SECRET_KEY=
SENDGRID_API_KEY=
.gitignore
.env
.env.local
.env.*.local
# НЕ игнорировать:
# .env.example — шаблон для команды
Node.js: доступ к переменным
// Нативно — Node.js 20.6+ (без dotenv!)
// запуск: node --env-file=.env server.js
// Или через dotenv
// npm install dotenv
require('dotenv').config;
// Доступ
const port = process.env.PORT || 3000;
const dbUrl = process.env.DATABASE_URL;
if (!dbUrl) {
throw new Error('DATABASE_URL is required');
}
Валидация переменных при старте (Zod)
const { z } = require('zod');
const envSchema = z.object({
NODE_ENV: z.enum(['development', 'staging', 'production']),
PORT: z.coerce.number.default(3000),
DATABASE_URL: z.string.url,
JWT_SECRET: z.string.min(32),
});
const env = envSchema.parse(process.env);
// Если переменная отсутствует — выбросит ошибку при старте, а не при первом использовании
module.exports = { env };
В продакшне: GitHub Actions Secrets
# .github/workflows/deploy.yml
- name: Deploy
run: npm run deploy
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
JWT_SECRET: ${{ secrets.JWT_SECRET }}
Docker / docker-compose
# docker-compose.yml
services:
api:
env_file:
- .env # загрузить из файла
environment:
NODE_ENV: production # или переопределить конкретные
# Передать при запуске контейнера
docker run -e NODE_ENV=production --env-file .env myapp:latest
Частые ошибки
- Закоммитить
.envс реальными секретами — сразу добавить в.gitignoreи ротировать ключи - Не иметь
.env.example— новый разработчик не знает какие переменные нужны - Читать
process.envв разных местах кода без валидации — лучше парсить один раз при старте - Одинаковые
JWT_SECRETв development и production — секреты должны отличаться по средам