Tips > Ops & Security

Use Docker Secrets Instead of Plain-Text Environment Variables

Environment variables in `docker-compose.yml` or `.env` files are stored in plaintext on disk.

Store n8n secrets with Docker secrets instead of plaintext environment variables. Secrets are encrypted at rest and mounted into the container only at runtime, unlike values in docker-compose.yml or .env, which anyone with filesystem access can read. n8n supports the Docker _FILE suffix convention, so you point variables such as N8N_ENCRYPTION_KEY_FILE at the mounted secret file.

Why avoid plaintext environment variables for secrets?

Environment variables in docker-compose.yml or .env files are stored in plaintext on disk. Anyone with access to the host filesystem can read every secret. Docker secrets provide encrypted at-rest storage and are only available inside the container at runtime.

Real-world example: A developer accidentally commits the docker-compose.yml containing the database password and encryption key to a public Git repository.

How do you configure Docker secrets for n8n?

# docker-compose.yml with Docker secrets

version: "3.9"

secrets:
  n8n_encryption_key:
    file: ./secrets/n8n_encryption_key.txt
  db_password:
    file: ./secrets/db_password.txt
  redis_password:
    file: ./secrets/redis_password.txt

services:
  n8n:
    image: n8nio/n8n:latest
    secrets:
      - n8n_encryption_key
      - db_password
    environment:
      # Reference secrets via file path

      - N8N_ENCRYPTION_KEY_FILE=/run/secrets/n8n_encryption_key
      - DB_POSTGRESDB_PASSWORD_FILE=/run/secrets/db_password
      # Non-sensitive config can remain as environment variables

      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_DATABASE=n8n
      - DB_POSTGRESDB_USER=n8n_user

  postgres:
    image: postgres:16-alpine
    secrets:
      - db_password
    environment:
      - POSTGRES_PASSWORD_FILE=/run/secrets/db_password
      - POSTGRES_DB=n8n
      - POSTGRES_USER=n8n_user

Info: The _FILE Suffix Convention. n8n supports the Docker _FILE suffix convention for many environment variables. When you set N8N_ENCRYPTION_KEY_FILE=/run/secrets/n8n_encryption_key, n8n reads the file contents as the value. Check n8n's documentation for which variables support this pattern. If a variable does not support the _FILE suffix, use an entrypoint script to export the secret as an environment variable at container startup.

Create the secret files and keep the directory out of version control:

# Create secrets directory (exclude from version control)

mkdir -p secrets
echo "your-encryption-key" > secrets/n8n_encryption_key.txt
echo "your-db-password" > secrets/db_password.txt
chmod 600 secrets/*.txt

# Add to .gitignore

echo "secrets/" >> .gitignore

Related: Use Docker Compose with Health Checks for n8n and PostgreSQL · Use Path Parameters in Webhook URLs for Dynamic Routing

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