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

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 the 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.

How do you move Docker Compose configuration into a .env file?

Define the configuration values in a .env file that sits next to docker-compose.yml:


# 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

Reference the variables in docker-compose.yml with ${VARIABLE} syntax:

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}

How do you keep the .env file out of version control?

Add the .env file to .gitignore so secrets are never committed:

.gitignore


# Never commit secrets

.env

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 · Configure Payload Size and Binary Data Mode for Large Files

Showcase builds

19 complete workflows from my own projects, each with its n8n workflow JSON to import. Showcase entries link the file at the end of the article.

See the showcase builds

Keep reading

190 entries grouped by topic, from first workflow to queue mode. Free, no signup.

Browse the encyclopedia

Need it built?

I design, build and run n8n systems for clients. Every engagement starts with a $1,500 diagnostic audit, credited toward the build.

Book an introductory call