- Home »

Node.js: использование команды с env и cmd
Если вы когда-нибудь разворачивали Node.js приложения на серверах, то наверняка сталкивались с необходимостью настройки переменных окружения и выполнения команд в разных средах. Это может стать настоящей головной болью, особенно когда нужно быстро переключаться между development, staging и production окружениями. Сегодня разберём, как правильно работать с переменными окружения в Node.js, используя env и cmd подходы, чтобы ваши деплои проходили гладко, а конфигурация была предсказуемой.
Как это работает: основы переменных окружения
Переменные окружения — это способ передачи конфигурационных данных в приложение без хардкода значений прямо в коде. В Node.js они доступны через объект process.env
.
Базовый принцип работы:
// Проверяем переменную окружения
console.log(process.env.NODE_ENV); // 'development', 'production', etc.
console.log(process.env.PORT); // 3000, 8080, etc.
// Используем в коде
const port = process.env.PORT || 3000;
const dbUrl = process.env.DATABASE_URL || 'mongodb://localhost:27017/myapp';
Способы установки переменных окружения
Есть несколько способов задать переменные окружения для Node.js приложения:
1. Прямо в командной строке (Linux/macOS)
NODE_ENV=production PORT=8080 node app.js
2. В Windows (CMD)
set NODE_ENV=production
set PORT=8080
node app.js
3. В Windows (PowerShell)
$env:NODE_ENV="production"
$env:PORT="8080"
node app.js
4. Используя cross-env (кроссплатформенное решение)
npm install --save-dev cross-env
# В package.json
{
"scripts": {
"start": "cross-env NODE_ENV=production PORT=8080 node app.js",
"dev": "cross-env NODE_ENV=development PORT=3000 node app.js"
}
}
Пошаговая настройка с dotenv
Самый популярный и удобный способ — использование пакета dotenv:
Шаг 1: Установка
npm install dotenv
Шаг 2: Создание .env файла
# .env
NODE_ENV=development
PORT=3000
DATABASE_URL=mongodb://localhost:27017/myapp
JWT_SECRET=your-secret-key
REDIS_HOST=localhost
REDIS_PORT=6379
Шаг 3: Подключение в приложении
// app.js
require('dotenv').config();
const express = require('express');
const app = express();
const port = process.env.PORT || 3000;
const dbUrl = process.env.DATABASE_URL;
console.log(`Server starting on port ${port}`);
console.log(`Database URL: ${dbUrl}`);
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
Продвинутые техники и практические кейсы
Конфигурация для разных окружений
Создайте отдельные файлы для каждого окружения:
// config/config.js
const path = require('path');
const env = process.env.NODE_ENV || 'development';
// Загружаем соответствующий .env файл
require('dotenv').config({
path: path.resolve(__dirname, `../.env.${env}`)
});
module.exports = {
port: process.env.PORT || 3000,
database: {
url: process.env.DATABASE_URL,
options: {
useNewUrlParser: true,
useUnifiedTopology: true
}
},
redis: {
host: process.env.REDIS_HOST || 'localhost',
port: parseInt(process.env.REDIS_PORT) || 6379
},
jwt: {
secret: process.env.JWT_SECRET,
expiresIn: process.env.JWT_EXPIRES_IN || '24h'
}
};
Валидация переменных окружения
Добавьте проверку критически важных переменных:
// utils/validateEnv.js
function validateEnv() {
const required = ['DATABASE_URL', 'JWT_SECRET'];
for (const variable of required) {
if (!process.env[variable]) {
console.error(`Missing required environment variable: ${variable}`);
process.exit(1);
}
}
// Проверка валидности PORT
const port = parseInt(process.env.PORT);
if (isNaN(port) || port < 1 || port > 65535) {
console.error('PORT must be a valid number between 1 and 65535');
process.exit(1);
}
}
module.exports = validateEnv;
Сравнение различных подходов
Подход | Плюсы | Минусы | Лучше всего для |
---|---|---|---|
Прямо в CLI | Быстро, без зависимостей | Неудобно для множества переменных | Быстрое тестирование |
dotenv | Удобно, гибко, популярно | Дополнительная зависимость | Разработка и staging |
cross-env | Кроссплатформенность | Ограничен для множества переменных | CI/CD и скрипты |
Системные переменные | Безопасность, persistence | Сложность настройки | Production окружение |
Интересные факты и нестандартные применения
Динамическая загрузка модулей
// Загружаем разные модули в зависимости от окружения
const logger = process.env.NODE_ENV === 'production'
? require('./logger/production')
: require('./logger/development');
// Условная загрузка middleware
if (process.env.NODE_ENV === 'development') {
const morgan = require('morgan');
app.use(morgan('dev'));
}
Фичи флаги через переменные окружения
// Feature flags
const features = {
enableNewFeature: process.env.ENABLE_NEW_FEATURE === 'true',
debugMode: process.env.DEBUG_MODE === 'true',
maintenanceMode: process.env.MAINTENANCE_MODE === 'true'
};
// Условная логика
if (features.maintenanceMode) {
app.use((req, res) => {
res.status(503).send('Service temporarily unavailable');
});
}
Интеграция с Docker
# Dockerfile
FROM node:16-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
# Переменные окружения по умолчанию
ENV NODE_ENV=production
ENV PORT=3000
EXPOSE 3000
CMD ["node", "app.js"]
# docker-compose.yml
version: '3.8'
services:
app:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DATABASE_URL=mongodb://mongo:27017/myapp
- REDIS_HOST=redis
depends_on:
- mongo
- redis
mongo:
image: mongo:4.4
ports:
- "27017:27017"
redis:
image: redis:6-alpine
ports:
- "6379:6379"
Автоматизация и DevOps интеграция
GitHub Actions пример
# .github/workflows/deploy.yml
name: Deploy to Production
on:
push:
branches: [ main ]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: '16'
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test
env:
NODE_ENV: test
DATABASE_URL: ${{ secrets.TEST_DATABASE_URL }}
- name: Deploy to server
run: |
echo "Deploying with production environment variables"
env:
NODE_ENV: production
DATABASE_URL: ${{ secrets.PROD_DATABASE_URL }}
JWT_SECRET: ${{ secrets.JWT_SECRET }}
PM2 интеграция
// ecosystem.config.js
module.exports = {
apps: [{
name: 'myapp',
script: 'app.js',
instances: 'max',
exec_mode: 'cluster',
env: {
NODE_ENV: 'development',
PORT: 3000
},
env_production: {
NODE_ENV: 'production',
PORT: 8080,
DATABASE_URL: 'mongodb://prod-server:27017/myapp'
}
}]
};
Безопасность и лучшие практики
Важные моменты безопасности:
- Никогда не коммитьте .env файлы — добавьте их в .gitignore
- Используйте разные секреты для каждого окружения
- Ротация ключей — регулярно меняйте секретные ключи
- Валидация типов — проверяйте типы переменных при запуске
# .gitignore
.env
.env.local
.env.development
.env.test
.env.production
# Исключение: можно коммитить .env.example
!.env.example
Альтернативные решения
Кроме dotenv, существуют и другие инструменты:
- node-config — более мощная система конфигурации
- cosmiconfig — поиск и загрузка конфигурации из различных источников
- dotenv-expand — расширение dotenv с поддержкой переменных
- env-cmd — выполнение команд с переменными из файлов
Возможности для автоматизации
Переменные окружения открывают широкие возможности для автоматизации:
- A/B тестирование — включение/выключение функций через переменные
- Мониторинг — настройка уровней логирования
- Масштабирование — динамическая настройка пулов соединений
- Интеграции — переключение между сервисами (например, разные API ключи)
Для серверных решений рекомендую рассмотреть аренду VPS или выделенного сервера для более серьёзных нагрузок.
Заключение и рекомендации
Правильная работа с переменными окружения — это основа надёжного Node.js приложения. Вот основные рекомендации:
- Для разработки — используйте dotenv с отдельными файлами для каждого окружения
- Для production — устанавливайте переменные на уровне системы или контейнера
- Для CI/CD — используйте секреты репозитория и cross-env для кроссплатформенности
- Всегда валидируйте критически важные переменные при запуске
- Документируйте все переменные в .env.example файле
Такой подход обеспечит гибкость, безопасность и упростит деплой вашего приложения в любое окружение. Переменные окружения — это не просто способ передачи конфигурации, это инструмент для создания по-настоящему переносимых и масштабируемых приложений.
В этой статье собрана информация и материалы из различных интернет-источников. Мы признаем и ценим работу всех оригинальных авторов, издателей и веб-сайтов. Несмотря на то, что были приложены все усилия для надлежащего указания исходного материала, любая непреднамеренная оплошность или упущение не являются нарушением авторских прав. Все упомянутые товарные знаки, логотипы и изображения являются собственностью соответствующих владельцев. Если вы считаете, что какой-либо контент, использованный в этой статье, нарушает ваши авторские права, немедленно свяжитесь с нами для рассмотрения и принятия оперативных мер.
Данная статья предназначена исключительно для ознакомительных и образовательных целей и не ущемляет права правообладателей. Если какой-либо материал, защищенный авторским правом, был использован без должного упоминания или с нарушением законов об авторском праве, это непреднамеренно, и мы исправим это незамедлительно после уведомления. Обратите внимание, что переиздание, распространение или воспроизведение части или всего содержимого в любой форме запрещено без письменного разрешения автора и владельца веб-сайта. Для получения разрешений или дополнительных запросов, пожалуйста, свяжитесь с нами.