Docker Compose Environment Variables: Best Practices

Environment variables are essential for configuring containerized applications. This guide covers various approaches to manage them in Docker Compose.

Basic Environment Configuration

services:
  app:
    image: node:alpine
    environment:
      - NODE_ENV=production
      - DATABASE_URL=postgres://user:pass@db:5432
      - API_KEY=${API_KEY}
    env_file:
      - .env
      - .env.production

Environment Variable Sources

  1. Direct Definition
    environment:
      - KEY=value
      - ANOTHER_KEY=another_value
    
  2. Environment Files
    env_file:
      - .env
      - .env.${ENVIRONMENT}
    
  3. Shell Variables
    environment:
      - API_KEY=${API_KEY}
    

Environment File Priority

  1. File Loading Order
    • .env (default)
    • .env.local
    • .env.${ENVIRONMENT}
    • .env.${ENVIRONMENT}.local
  2. Variable Override Rules
    • Later files override earlier ones
    • Direct environment variables override files
    • Shell variables override all

Docker Compose 3.x Features

  1. Extended Environment Syntax
    environment:
      NODE_ENV: production
      DATABASE_URL: postgres://user:pass@db:5432
    
  2. Conditional Environment
    environment:
      - NODE_ENV=${NODE_ENV:-development}
      - API_URL=${API_URL:-http://localhost:3000}
    
  3. Environment Templates
    environment:
      - CONFIG_PATH=/config/${ENVIRONMENT}
      - LOG_LEVEL=${LOG_LEVEL:-info}
    

Secrets Management

1. Docker Secrets

services:
  db:
    image: postgres
    secrets:
      - db_password
    environment:
      POSTGRES_PASSWORD_FILE: /run/secrets/db_password

secrets:
  db_password:
    file: ./secrets/db_password.txt

2. External Secrets

services:
  app:
    image: myapp
    secrets:
      - source: vault_secret
        target: vault_token

secrets:
  vault_secret:
    external: true

Docker Swarm Mode Considerations

  1. Secret Management
    services:
      app:
        secrets:
          - source: db_password
            target: db_password
            mode: 0440
    
  2. Environment Variables
    services:
      app:
        environment:
          - NODE_ENV=production
        env_file:
          - .env.production
    
  3. Config Management
    services:
      app:
        configs:
          - source: app_config
            target: /app/config.json
    

Best Practices

  1. Security
    • Never commit sensitive data
    • Use secrets for credentials
    • Implement proper access controls
  2. Organization
    • Use descriptive variable names
    • Group related variables
    • Document required variables
  3. Maintenance
    • Version control .env.example
    • Use environment-specific files
    • Implement validation

Common Patterns

1. Development vs Production

services:
  app:
    env_file:
      - .env.${NODE_ENV:-development}

2. Multi-stage Configuration

services:
  app:
    environment:
      <<: *base_env
      <<: *${ENVIRONMENT}_env

3. Dynamic Configuration

services:
  app:
    environment:
      - CONFIG_PATH=/config/${ENVIRONMENT}

Troubleshooting

  1. Variable Substitution
    # Check variable values
    docker compose config
    
  2. Missing Variables
    # List all environment variables
    docker compose exec app env
    
  3. File Permissions
    # Set proper permissions
    chmod 600 .env
    

Advanced Topics

  1. Variable Interpolation
    • Nested variables
    • Default values
    • Conditional values
  2. Secret Rotation
    • Automated updates
    • Zero-downtime deployment
    • Audit logging
  3. Configuration Validation
    • Required variables
    • Type checking
    • Value constraints

Remember to always follow the principle of least privilege and implement proper security measures when handling sensitive data.

© 2025 Compose-it. All rights reserved.

Docker are registered trademarks of Docker, Inc. in the United States and/or other countries. The tool 'compose-it' is not affiliated with, endorsed by, or sponsored by Docker, Inc.