Developer Tools - Free Online Utilities

    Multiline Formatter
    Text Case Converter
    Lorem Ipsum Generator
    Text Sort & Dedup Tool
    Unicode & Emoji Browser
    CSV to JSON/XML Converter
DevOps
14 min read

Environment Variables and Configuration Management

Complete guide to managing application configuration securely across development, staging, and production environments

Environment variables are the cornerstone of modern application configuration. They enable the same codebase to run in different environments while keeping sensitive information secure. Whether you're deploying to Docker containers, Kubernetes clusters, or traditional servers, proper environment variable management is crucial for security, scalability, and maintainability.

This comprehensive guide covers everything from basic .env file management to advanced secrets handling in production environments, helping you build robust configuration systems that grow with your application.


Table of Contents

  • 1. Environment Variables Fundamentals
  • 2. .env Files and Local Development
  • 3. Security Best Practices
  • 4. Docker Configuration
  • 5. Kubernetes Secrets Management
  • 6. Cloud Platform Configuration
  • 7. Configuration Validation
  • 8. Deployment Strategies

1. Environment Variables Fundamentals

What Are Environment Variables?

Environment variables are key-value pairs that exist outside your application code but can be accessed by your application at runtime. They provide a way to configure your application without hardcoding values into your source code.

Why Use Environment Variables?

  • Security

    Keep sensitive data like API keys and passwords out of source code

  • Flexibility

    Same codebase runs in different environments with different configurations

  • Deployment

    Change configuration without rebuilding or redeploying code

  • Compliance

    Meet security standards by separating config from code

Common Environment Variables

# Application Configuration
NODE_ENV=production
PORT=3000
APP_URL=https://myapp.com

# Database Configuration
DATABASE_URL=postgresql://user:pass@localhost:5432/mydb
REDIS_URL=redis://localhost:6379

# API Keys and Secrets
JWT_SECRET=your-super-secure-secret-key
STRIPE_SECRET_KEY=sk_live_...
SENDGRID_API_KEY=SG.abc123...

# External Services
AWS_ACCESS_KEY_ID=AKIA...
AWS_SECRET_ACCESS_KEY=...
AWS_REGION=us-east-1

2. .env Files and Local Development

Creating .env Files

.env files provide a convenient way to manage environment variables during development. They should be in your project root and follow this format:

# .env file structure
# Comments start with #
DATABASE_URL=postgresql://localhost:5432/myapp_dev
API_KEY=dev-api-key-123
DEBUG=true

# Use quotes for values with spaces
APP_NAME="My Awesome App"

# Multi-line values use escaped newlines
PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC7...\n-----END PRIVATE KEY-----"

Environment-Specific Files

Create separate .env files for different environments:

  • .env

    Default values and non-sensitive configuration

  • .env.local

    Local development overrides (gitignored)

  • .env.development

    Development environment specific

  • .env.production

    Production environment template

3. Security Best Practices

Identifying Sensitive Variables

Some environment variables contain sensitive information that requires special handling:

🔐 Sensitive

• API keys and tokens
• Database passwords
• JWT secrets
• Private keys
• OAuth credentials

✅ Safe

• Application names
• Public URLs
• Feature flags
• Timeout values
• Debug settings

Secret Management Best Practices

  • Use a secrets manager

    AWS Secrets Manager, Azure Key Vault, HashiCorp Vault

  • Rotate secrets regularly

    Implement automatic rotation for API keys and tokens

  • Principle of least privilege

    Grant minimal access required for each environment

  • Audit access

    Log and monitor who accesses sensitive configuration

4. Docker Configuration

Docker Environment Variables

Docker provides several ways to pass environment variables to containers:

# Method 1: Command line
docker run -e NODE_ENV=production -e PORT=3000 myapp

# Method 2: Environment file
docker run --env-file .env.production myapp

# Method 3: Docker Compose
version: '3.8'
services:
  app:
    build: .
    environment:
      - NODE_ENV=production
      - PORT=3000
    env_file:
      - .env.production
    ports:
      - "3000:3000"

Docker Secrets

For sensitive data in Docker Swarm, use Docker secrets:

# Create a secret
echo "my-secret-password" | docker secret create db_password -

# Use in docker-compose.yml
version: '3.8'
services:
  app:
    image: myapp
    secrets:
      - db_password
    environment:
      - DB_PASSWORD_FILE=/run/secrets/db_password

secrets:
  db_password:
    external: true

5. Kubernetes Secrets Management

Kubernetes ConfigMaps vs Secrets

ConfigMaps

For non-sensitive configuration data like application settings, feature flags, and public configuration.

Secrets

For sensitive data like passwords, API keys, and certificates. Base64 encoded and encrypted at rest.

Creating Kubernetes Secrets

# Create secret from literal values
kubectl create secret generic app-secrets \
  --from-literal=database-password=secretpassword \
  --from-literal=api-key=abc123

# Create secret from .env file
kubectl create secret generic app-config --from-env-file=.env.production

# Secret YAML manifest
apiVersion: v1
kind: Secret
metadata:
  name: app-secrets
type: Opaque
data:
  database-password: c2VjcmV0cGFzc3dvcmQ=  # base64 encoded
  api-key: YWJjMTIz  # base64 encoded

Using Secrets in Deployments

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  template:
    spec:
      containers:
      - name: app
        image: myapp:latest
        env:
        # From ConfigMap
        - name: NODE_ENV
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: environment
        # From Secret
        - name: DATABASE_PASSWORD
          valueFrom:
            secretKeyRef:
              name: app-secrets
              key: database-password
        # Mount entire secret as volume
        volumeMounts:
        - name: secret-volume
          mountPath: /etc/secrets
      volumes:
      - name: secret-volume
        secret:
          secretName: app-secrets

6. Cloud Platform Configuration

AWS Configuration

  • AWS Systems Manager Parameter Store

    Hierarchical storage with encryption and versioning

  • AWS Secrets Manager

    Automatic rotation and fine-grained access control

  • ECS Task Definitions

    Environment variables in container definitions

  • Lambda Environment Variables

    Built-in encryption with AWS KMS

Azure Configuration

  • Azure Key Vault

    Centralized secrets and certificate management

  • App Configuration

    Feature flags and dynamic configuration

  • Container Apps Environment Variables

    Secret and non-secret configuration

7. Configuration Validation

Runtime Validation

Always validate environment variables at application startup:

// Node.js validation example
const requiredEnvVars = [
  'DATABASE_URL',
  'JWT_SECRET',
  'STRIPE_SECRET_KEY'
];

function validateEnvironment() {
  const missing = requiredEnvVars.filter(varName => !process.env[varName]);
  
  if (missing.length > 0) {
    console.error('Missing required environment variables:', missing);
    process.exit(1);
  }
  
  // Validate formats
  if (process.env.PORT && isNaN(parseInt(process.env.PORT))) {
    console.error('PORT must be a number');
    process.exit(1);
  }
  
  if (process.env.DATABASE_URL && !process.env.DATABASE_URL.startsWith('postgresql://')) {
    console.error('DATABASE_URL must be a valid PostgreSQL connection string');
    process.exit(1);
  }
}

// Run validation on startup
validateEnvironment();

Configuration Schema

Define a schema for your configuration to catch errors early:

// Using Joi for validation
const Joi = require('joi');

const configSchema = Joi.object({
  NODE_ENV: Joi.string().valid('development', 'production', 'test').required(),
  PORT: Joi.number().port().default(3000),
  DATABASE_URL: Joi.string().uri().required(),
  JWT_SECRET: Joi.string().min(32).required(),
  REDIS_URL: Joi.string().uri().optional(),
  LOG_LEVEL: Joi.string().valid('error', 'warn', 'info', 'debug').default('info')
});

const { error, value } = configSchema.validate(process.env, {
  allowUnknown: true,
  abortEarly: false
});

if (error) {
  console.error('Configuration validation error:', error.details);
  process.exit(1);
}

module.exports = value;

8. Deployment Strategies

Configuration Deployment Pipeline

  • Development

    Local .env files with default values

  • Staging

    CI/CD pipeline injects staging secrets

  • Production

    Secrets manager or encrypted storage

GitOps Configuration Management

# Repository structure for GitOps
config/
├── base/
│   ├── configmap.yaml
│   └── kustomization.yaml
├── environments/
│   ├── development/
│   │   ├── configmap.yaml
│   │   ├── secrets.yaml (encrypted)
│   │   └── kustomization.yaml
│   ├── staging/
│   │   ├── configmap.yaml
│   │   ├── secrets.yaml (encrypted)
│   │   └── kustomization.yaml
│   └── production/
│       ├── configmap.yaml
│       ├── secrets.yaml (encrypted)
│       └── kustomization.yaml

Zero-Downtime Configuration Updates

  • Rolling Updates

    Gradually replace instances with new configuration

  • Configuration Reload

    Hot-reload configuration without restart (where possible)

  • Canary Deployments

    Test configuration changes with subset of traffic

  • Rollback Strategy

    Quick rollback mechanism for configuration issues


Conclusion

Effective environment variable management is crucial for secure, scalable applications. By following best practices for local development, implementing proper security measures, and using the right tools for each deployment environment, you can build robust configuration systems that support your application's growth.

Remember that configuration management is an ongoing process. Regularly audit your environment variables, rotate secrets, and update your configuration strategy as your application and infrastructure evolve.

Related Tools

Environment Variables Manager - Validate and manage .env files
Kubernetes YAML Generator - Create ConfigMaps and Secrets
Base64 Encoder/Decoder - Encode secrets for Kubernetes
Hash Generator - Generate secure secret values
Password Generator - Create strong passwords for configs