Tips > Ops & Security

Use a `.env` File for Docker Compose Configuration

Hardcoding database passwords, hostnames, and feature flags directly in `docker-compose.yml` makes the file non-portable and creates security risks when the ...

TipAdvanced2 min read

Hardcoding database passwords, hostnames, and feature flags directly in docker-compose.yml makes the file non-portable and creates security risks when the Compose file is committed to version control. Docker Compose natively reads a .env file in the same directory, allowing you to separate configuration from infrastructure definition.

Real-world example: You maintain a single docker-compose.yml that works across development, staging, and production by swapping only the .env file.


# n8n Configuration

N8N_VERSION=1.94.1
N8N_HOST=n8n.example.com
N8N_PROTOCOL=https
GENERIC_TIMEZONE=America/New_York

# Database

POSTGRES_DB=n8n_db
POSTGRES_USER=n8n_user
POSTGRES_PASSWORD=a-strong-random-password-here
POSTGRES_VERSION=16

# Execution Settings

EXECUTIONS_DATA_PRUNE=true
EXECUTIONS_DATA_MAX_AGE=168

# Encryption key for credentials (generate once, never change)

N8N_ENCRYPTION_KEY=your-generated-encryption-key
```text
```yaml title="docker-compose.yml"
services:
  postgres:
    image: postgres:${POSTGRES_VERSION}-alpine
    environment:
      POSTGRES_DB: ${POSTGRES_DB}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}

  n8n:
    image: n8nio/n8n:${N8N_VERSION}
    environment:
      DB_TYPE: postgresdb
      DB_POSTGRESDB_HOST: postgres
      DB_POSTGRESDB_DATABASE: ${POSTGRES_DB}
      DB_POSTGRESDB_USER: ${POSTGRES_USER}
      DB_POSTGRESDB_PASSWORD: ${POSTGRES_PASSWORD}
      N8N_HOST: ${N8N_HOST}
      N8N_PROTOCOL: ${N8N_PROTOCOL}
      GENERIC_TIMEZONE: ${GENERIC_TIMEZONE}
      EXECUTIONS_DATA_PRUNE: ${EXECUTIONS_DATA_PRUNE}
      EXECUTIONS_DATA_MAX_AGE: ${EXECUTIONS_DATA_MAX_AGE}
      N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
```text
```bash title=".gitignore"

# Never commit secrets

.env
```text
> **Danger: The Encryption Key**
>
> `N8N_ENCRYPTION_KEY` encrypts all stored credentials. If you lose this key, every credential in n8n becomes unreadable and must be re-entered. Generate it once with `openssl rand -hex 32`, store it in your `.env` file, and back it up separately from the database.

This pattern keeps secrets out of version control, makes environment promotion straightforward, and lets you generate environment-specific configs from a template.

**Related:** [Set a Unique Encryption Key and Back It Up](../security-best-practices/01-set-a-unique-encryption-key-and-back-it-up.md) | [Configure Payload Size and Binary Data Mode for Large Files](../performance-and-large-files/01-configure-payload-size-and-binary-data-mode-for-large-files.md)

Want this running in your stack?

I build production n8n and Cloudflare automation for teams — the same engineering behind HarperFlow. Fixed-price, escrow-protected, US-based.