Environment variables are simple settings that control how your application behaves without changing its core code. In n8n workflow automation , they act as the control panel that defines how your automation system runs, connects, and secures itself. When you install n8n on a VPS using Docker, you don’t hardcode things like your domain, port, or login credentials. Instead, you define them using environment variables. This keeps your setup flexible, secure, and easy to manage.
You’ll use environment variables in:
- Docker container ecosystem and Docker Compose setups
- VPS or cloud deployments
- Self-hosted production environments
Environment variables let you configure and control n8n without touching the application code.
What Are Environment Variables?
Environment variables follow a simple key = value format.
They tell your system what settings to use.
Example:
N8N_PORT=5678
This means: “Run n8n on port 5678.” Think of environment variables like a settings panel on your phone.You don’t change the phone’s software.You just toggle settings like Wi-Fi, brightness, or notifications
Environment variables work the same way. They let you adjust how n8n behaves without rewriting anything.
Where are environment variables stored?
You can define them in different places depending on your setup:
1. .env file (cleanest method)
A simple file where all variables are stored in one place.
N8N_HOST=yourdomain.com
N8N_PROTOCOL=https
2. docker-compose.yml (most common)
Used when running n8n with Docker.
environment:
- N8N_HOST=yourdomain.com
- N8N_PORT=5678
3. Server environment (advanced)
Set directly in your VPS terminal:
export N8N_HOST=yourdomain.com
Why Environment Variables Matter in n8n
Environment variables are essential because they let you control everything about your n8n setup without modifying the application itself.
1. Control behavior without editing code
You can change how n8n runs (port, domain, features) instantly just by updating values.
2. Security (authentication & credentials)
Instead of hardcoding usernames and passwords, you define them securely:
N8N_BASIC_AUTH_USER=admin
N8N_BASIC_AUTH_PASSWORD=yourpassword
3. URLs & domain configuration
Environment variables define how users and external services access your n8n instance:
- Domain name
- Protocol (HTTP/HTTPS)
- Webhook URLs
4. Database connections
When moving to production, you’ll connect n8n to PostgreSQL using variables:
DB_TYPE=postgresdb
DB_POSTGRESDB_HOST=localhost
5. Feature control (toggle settings)
You can enable or disable features easily:
- Secure cookies
- Execution settings
- Logging behavior
Why this matters in real projects
Without environment variables:
- You’d edit code every time you change settings
- Your setup becomes messy and risky
With environment variables:
- Your setup is clean
- Changes are instant
- Deployment becomes predictable

Essential n8n Environment Variables (The Must-Have List)
1. N8N_HOST
Tells n8n what URL users access it from.Webhooks break without this. n8n generates webhook URLs like http://undefined/webhook/xxx instead of https://yourdomain.com/webhook/xxx.
# If you have a domain
N8N_HOST=n8n.yourdomain.com
# If using IP address only (testing)
N8N_HOST=45.123.456.789
# If running locally
N8N_HOST=localhost
2. N8N_PORT
Defines what port n8n listens on inside the container. Port conflicts cause n8n to fail silently or refuse connections. Default value: 5678
When to change it:
# Default (recommended)
N8N_PORT=5678
# If 5678 is already used by another service
N8N_PORT=5679
# Non-standard port for security through obscurity
N8N_PORT=8888
Port mapping in Docker Compose:
services:
n8n:
ports:
- "5678:5678" # host:container
environment:
- N8N_PORT=5678 # Must match container port
External port 5678 → Internal port 5678
3. N8N_PROTOCOL -HTTP or HTTPS
Tells n8n whether it’s running over HTTP or HTTPS. Affects webhook URL generation and security warnings.
Values:
# For production with SSL certificate
N8N_PROTOCOL=https
# For local development
N8N_PROTOCOL=http
When HTTPS is required:
- Webhook integrations (Stripe, Shopify, Typeform)
- OAuth authentication flows
- Secure credential transmission
- Production deployments
Setup flow:
# Initial setup (testing)
N8N_PROTOCOL=http
N8N_HOST=45.123.456.789
# After setting up SSL (production)
N8N_PROTOCOL=https
N8N_HOST=n8n.yourdomain.com
4. WEBHOOK_URL
Overrides automatic webhook URL generation. Useful when running behind reverse proxy or using non-standard setup.
When to use it:
# Most cases - n8n auto-generates from N8N_HOST + N8N_PROTOCOL
# No need to set WEBHOOK_URL
# Behind Nginx reverse proxy with custom path
WEBHOOK_URL=https://yourdomain.com/automation/
# Using Cloudflare Tunnel
WEBHOOK_URL=https://n8n-tunnel.yourdomain.com/
# Multiple n8n instances on same domain
WEBHOOK_URL=https://yourdomain.com/n8n-prod/
Structure:
WEBHOOK_URL = protocol + host + path (optional)
Example:
WEBHOOK_URL=https://api.yourcompany.com/webhooks/
Generates webhook URLs like:
https://api.yourcompany.com/webhooks/webhook/abc123
5. GENERIC_TIMEZONE
What it does: Sets the timezone for scheduled workflows and timestamps.
Your “9 AM daily report” runs at 9 AM UTC (4 AM EST) instead of your actual 9 AM. Standard timezone identifier (IANA format)
Common values:
# United States
GENERIC_TIMEZONE=America/New_York # EST/EDT
GENERIC_TIMEZONE=America/Chicago # CST/CDT
GENERIC_TIMEZONE=America/Denver # MST/MDT
GENERIC_TIMEZONE=America/Los_Angeles # PST/PDT
# Europe
GENERIC_TIMEZONE=Europe/London # GMT/BST
GENERIC_TIMEZONE=Europe/Paris # CET/CEST
GENERIC_TIMEZONE=Europe/Berlin # CET/CEST
# Asia
GENERIC_TIMEZONE=Asia/Tokyo # JST
GENERIC_TIMEZONE=Asia/Shanghai # CST
GENERIC_TIMEZONE=Asia/Kolkata # IST
# Australia
GENERIC_TIMEZONE=Australia/Sydney # AEDT/AEST
# UTC (not recommended for business use)
GENERIC_TIMEZONE=UTC
6. N8N_BASIC_AUTH_ACTIVE -Enable Authentication
Turns on basic username/password authentication. Without this, anyone who finds your n8n URL can access and modify your workflows.
Values:
# Enable authentication (production)
N8N_BASIC_AUTH_ACTIVE=true
# Disable authentication (local development only)
N8N_BASIC_AUTH_ACTIVE=false
7. N8N_BASIC_AUTH_USER – Username
Sets the username for basic authentication. This is what you type to log into n8n.
Best practices:
# Too obvious
N8N_BASIC_AUTH_USER=admin
N8N_BASIC_AUTH_USER=n8n
N8N_BASIC_AUTH_USER=user
# Better
N8N_BASIC_AUTH_USER=automation_admin
N8N_BASIC_AUTH_USER=yourname_n8n
N8N_BASIC_AUTH_USER=workflow_master
Bots scan for common usernames. Using “admin” makes brute-force attacks easier.
Example configuration:
N8N_BASIC_AUTH_ACTIVE=true
N8N_BASIC_AUTH_USER=john_workflows
N8N_BASIC_AUTH_PASSWORD=super_secure_password_here
8. N8N_BASIC_AUTH_PASSWORD – Password
Sets the password for basic authentication. Weak password = compromised n8n = compromised integrations = compromised business.
Password requirements:
# Terrible passwords
N8N_BASIC_AUTH_PASSWORD=password
N8N_BASIC_AUTH_PASSWORD=123456
N8N_BASIC_AUTH_PASSWORD=n8n
# ⚠️ Weak passwords
N8N_BASIC_AUTH_PASSWORD=MyPassword123
# Strong passwords
N8N_BASIC_AUTH_PASSWORD=XK9$mP#2vN8qL@4wR
N8N_BASIC_AUTH_PASSWORD=correct-horse-battery-staple-7829
Generate strong password:
# Linux/Mac
openssl rand -base64 32
# Output example:
# 7vK9pL2mQ4xR8nT6wY3zC5vB1nM0qP9o
9. NODE_ENV – Production or Development Mode
Tells Node.js (which n8n runs on) whether this is production or development. Affects logging, error handling, and performance optimizations.
Values:
# Production deployment (recommended)
NODE_ENV=production
# Development/testing
NODE_ENV=development
Differences:
| Feature | production | development |
|---|---|---|
| Error messages | Generic | Detailed stack traces |
| Logging | Minimal | Verbose |
| Performance | Optimized | Slower (more checks) |
| Caching | Aggressive | Minimal |
| Security | Strict | Relaxed |
When to use each:
# On your VPS serving real workflows
NODE_ENV=production
# On your laptop testing new workflows
NODE_ENV=development
Most users should always use production.
Database Configuration Variables
10. DB_TYPE – Which Database to Use
Chooses between SQLite (simple) or PostgreSQL (powerful). SQLite breaks under high load. PostgreSQL scales to millions of workflows.
Values:
# SQLite (default) - good for small deployments
DB_TYPE=sqlite
# PostgreSQL - recommended for production
DB_TYPE=postgresdb
# MySQL/MariaDB (also supported)
DB_TYPE=mysqldb
When to use each:
| Scenario | Recommended Database |
|---|---|
| < 50 workflows | SQLite |
| < 10,000 executions/day | SQLite |
| Single user | SQLite |
| 100+ workflows | PostgreSQL |
| 50,000+ executions/day | PostgreSQL |
| Multiple users | PostgreSQL |
| Mission-critical | PostgreSQL |
SQLite configuration (simple):
DB_TYPE=sqlite
DB_SQLITE_DATABASE=/home/node/.n8n/database.sqlite
PostgreSQL configuration (complete example):
DB_TYPE=postgresdb
DB_POSTGRESDB_HOST=localhost
DB_POSTGRESDB_PORT=5432
DB_POSTGRESDB_DATABASE=n8n
DB_POSTGRESDB_USER=n8n
DB_POSTGRESDB_PASSWORD=secure_db_password
11. DB_POSTGRESDB_- PostgreSQL Connection Settings
Configure connection to PostgreSQL database.
Full set of variables:
# Required PostgreSQL settings
DB_TYPE=postgresdb
DB_POSTGRESDB_HOST=localhost # Database server address
DB_POSTGRESDB_PORT=5432 # PostgreSQL port (default 5432)
DB_POSTGRESDB_DATABASE=n8n # Database name
DB_POSTGRESDB_USER=n8n # Database username
DB_POSTGRESDB_PASSWORD=your_password # Database password
# Optional PostgreSQL settings
DB_POSTGRESDB_SCHEMA=public # Database schema (default: public)
DB_POSTGRESDB_SSL_CA=/path/to/ca.crt # SSL certificate (if required)
DB_POSTGRESDB_SSL_CERT=/path/to/cert.crt
DB_POSTGRESDB_SSL_KEY=/path/to/key.key
DB_POSTGRESDB_SSL_REJECT_UNAUTHORIZED=true
Common configurations:
Local PostgreSQL (same VPS):
DB_POSTGRESDB_HOST=localhost
DB_POSTGRESDB_PORT=5432
Docker Compose setup (PostgreSQL + n8n):
version: '3.8'
services:
postgres:
image: postgres:15-alpine
restart: unless-stopped
environment:
- POSTGRES_DB=n8n
- POSTGRES_USER=n8n
- POSTGRES_PASSWORD=n8n_password
volumes:
- postgres-data:/var/lib/postgresql/data
n8n:
image: n8nio/n8n:latest
restart: unless-stopped
ports:
- "5678:5678"
environment:
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=n8n
- DB_POSTGRESDB_PASSWORD=n8n_password
volumes:
- n8n-data:/home/node/.n8n
depends_on:
- postgres
volumes:
postgres-data:
n8n-data:
Execution & Performance Variables
12. EXECUTIONS_PROCESS – How Workflows Execute
Controls whether workflows run in main process or separate processes. Affects reliability and resource usage.
Values:
# Run in main process (simpler, recommended for small deployments)
EXECUTIONS_PROCESS=main
# Run in separate processes (more isolated, better for large deployments)
EXECUTIONS_PROCESS=own
Comparison:
| Mode | Pros | Cons | Best For |
|---|---|---|---|
| main | Simpler, lower overhead | One crash affects everything | < 50 workflows |
| own | Isolation, crash protection | Higher memory usage | 100+ workflows |
Most users should use main.
13. EXECUTIONS_TIMEOUT – Maximum Workflow Runtime
Kills workflows that run longer than specified time. Prevents infinite loops from consuming all resources. Format: Time in seconds
Values:
# Default: No timeout (not recommended)
# EXECUTIONS_TIMEOUT not set
# Recommended: 5 minutes for most workflows
EXECUTIONS_TIMEOUT=300
# For long-running workflows (data processing, API syncs)
EXECUTIONS_TIMEOUT=1800 # 30 minutes
# For simple workflows
EXECUTIONS_TIMEOUT=60 # 1 minute
Example scenarios:
Quick automation:
# Form submission → email → Slack notification
EXECUTIONS_TIMEOUT=60 # Should complete in seconds
Data processing:
# Process 10,000 database records
EXECUTIONS_TIMEOUT=1800 # May take 20+ minutes
If workflows time out frequently:
- Increase timeout
- Or optimize workflow (reduce API calls, add pagination)
14. EXECUTIONS_DATA_SAVE_ON_ – Execution History
Control what execution data gets saved to database. Saving everything uses lots of disk space. Saving nothing makes debugging impossible.
Variables:
# Save successful workflow executions
EXECUTIONS_DATA_SAVE_ON_SUCCESS=all # Save all data
EXECUTIONS_DATA_SAVE_ON_SUCCESS=none # Save nothing
# Save failed workflow executions
EXECUTIONS_DATA_SAVE_ON_ERROR=all # Save all data (recommended)
EXECUTIONS_DATA_SAVE_ON_ERROR=none # Save nothing
# Save manually triggered executions
EXECUTIONS_DATA_SAVE_MANUAL_EXECUTIONS=true # Save (recommended)
EXECUTIONS_DATA_SAVE_MANUAL_EXECUTIONS=false # Don't save
Recommended configuration:
# Keep errors for debugging, discard successful runs to save space
EXECUTIONS_DATA_SAVE_ON_ERROR=all
EXECUTIONS_DATA_SAVE_ON_SUCCESS=none
EXECUTIONS_DATA_SAVE_MANUAL_EXECUTIONS=true
If disk space isn’t a concern:
# Keep everything (useful for analytics)
EXECUTIONS_DATA_SAVE_ON_ERROR=all
EXECUTIONS_DATA_SAVE_ON_SUCCESS=all
EXECUTIONS_DATA_SAVE_MANUAL_EXECUTIONS=true
15. EXECUTIONS_DATA_MAX_AGE – How Long to Keep History
Automatically deletes old execution data. Prevents database from growing infinitely. Format: Time in hours
Values:
# Keep execution history for 7 days
EXECUTIONS_DATA_MAX_AGE=168
# Keep for 30 days
EXECUTIONS_DATA_MAX_AGE=720
# Keep for 90 days
EXECUTIONS_DATA_MAX_AGE=2160
# Keep forever (not recommended)
# EXECUTIONS_DATA_MAX_AGE not set
Recommended based on workflow volume:
| Executions/Day | Recommended Retention |
|---|---|
| < 100 | 30-90 days |
| 100-1,000 | 14-30 days |
| 1,000-10,000 | 7-14 days |
| 10,000+ | 3-7 days |
Enable automatic pruning:
EXECUTIONS_DATA_MAX_AGE=168 # Delete after 7 days
EXECUTIONS_DATA_PRUNE=true # Enable auto-deletion
EXECUTIONS_DATA_PRUNE_TIMEOUT=3600 # Check every hour
16. N8N_CONCURRENCY_PRODUCTION_LIMIT – Parallel Executions
Limits how many workflows can run simultaneously. Running too many parallel workflows crashes n8n on small VPS . Format: Number of workflows
Values:
# VPS with 1GB RAM
N8N_CONCURRENCY_PRODUCTION_LIMIT=5
# VPS with 2GB RAM
N8N_CONCURRENCY_PRODUCTION_LIMIT=10
# VPS with 4GB+ RAM
N8N_CONCURRENCY_PRODUCTION_LIMIT=20
# Unlimited (dangerous on small VPS)
N8N_CONCURRENCY_PRODUCTION_LIMIT=-1
Security & Advanced Variables
17. N8N_PAYLOAD_SIZE_MAX – Webhook Data Limit
Limits maximum size of data sent to webhooks. Prevents attacks that send huge payloads to crash n8n. Format: Size in megabytes
Values:
# Default: 16MB (reasonable for most uses)
N8N_PAYLOAD_SIZE_MAX=16
# For large file uploads via webhooks
N8N_PAYLOAD_SIZE_MAX=50
# For small data only
N8N_PAYLOAD_SIZE_MAX=5
When to increase:
- Receiving large JSON payloads from APIs
- Handling file uploads via webhooks
- Processing base64-encoded images
When to decrease:
- Only handling small form submissions
- Security-focused deployment
- Limited VPS resources
18. N8N_METRICS – Enable Prometheus Metrics
Exposes metrics for monitoring with Prometheus/Grafana. Essential for production monitoring and alerting.
Values:
# Disable metrics (default)
N8N_METRICS=false
# Enable metrics endpoint
N8N_METRICS=true
N8N_METRICS_PORT=9100
Once enabled, metrics available at:
http://your-n8n-instance:9100/metrics
Metrics exposed:
- Workflow execution count
- Execution duration
- Success/failure rates
- Database query times
- Memory usage
- CPU usage
Useful for:
- Setting up automated alerts
- Tracking performance over time
- Identifying slow workflows
- Capacity planning
19. N8N_LOG_LEVEL – Logging Verbosity
Controls how detailed logs are. Too verbose fills disk; too quiet makes debugging impossible.
Values:
# Minimal logging (production)
N8N_LOG_LEVEL=info
# Detailed logging (troubleshooting)
N8N_LOG_LEVEL=debug
# Everything (development only)
N8N_LOG_LEVEL=verbose
# Errors only
N8N_LOG_LEVEL=error
# Silent (not recommended)
N8N_LOG_LEVEL=silent
Recommended levels:
| Situation | Level | Why |
|---|---|---|
| Production | info | Balance detail vs disk usage |
| Debugging issues | debug | See detailed execution flow |
| Development | verbose | Everything for troubleshooting |
| Disk space critical | error | Only problems logged |
View logs:
# Docker
docker logs -f n8n
# Docker Compose
docker-compose logs -f n8n
# Filter for errors only
docker logs n8n 2>&1 | grep ERROR
20. N8N_USER_FOLDER – Custom Data Directory
Changes where n8n stores workflows, credentials, and database. Useful for custom backup locations or separating data.
Default: /home/node/.n8n
Custom location:
N8N_USER_FOLDER=/data/n8n-production
# Or multiple instances
N8N_USER_FOLDER=/data/n8n-staging
Docker volume mapping required:
services:
n8n:
environment:
- N8N_USER_FOLDER=/data/n8n-custom
volumes:
- /path/on/host:/data/n8n-custom
Use cases:
- Running multiple n8n instances
- Storing data on specific disk partition
- Separating production and staging data
Queue Mode Variables (Advanced Scaling)
21. EXECUTIONS_MODE – Enable Queue Mode
Switches from direct execution to queue-based processing. Enables horizontal scaling with multiple workers.
Values:
# Direct execution (default, simpler)
EXECUTIONS_MODE=regular
# Queue mode (scalable)
EXECUTIONS_MODE=queue
When to use queue mode:
- Processing 100,000+ executions per day
- Need to scale horizontally (multiple workers)
- Want execution resilience (workers can restart without losing jobs)
Requires Redis:
EXECUTIONS_MODE=queue
QUEUE_BULL_REDIS_HOST=localhost
QUEUE_BULL_REDIS_PORT=6379
QUEUE_BULL_REDIS_PASSWORD=redis_password # if Redis has auth
22. QUEUE_BULL_REDIS_ – Redis Connection Settings
Configure connection to Redis (required for queue mode).
Full configuration:
QUEUE_BULL_REDIS_HOST=localhost # Redis server address
QUEUE_BULL_REDIS_PORT=6379 # Redis port (default 6379)
QUEUE_BULL_REDIS_DB=0 # Redis database number
QUEUE_BULL_REDIS_PASSWORD=password # Redis password (if set)
QUEUE_BULL_REDIS_TIMEOUT_THRESHOLD=10000 # Connection timeout (ms)
Docker Compose with Redis:
version: '3.8'
services:
redis:
image: redis:7-alpine
restart: unless-stopped
command: redis-server --requirepass your_redis_password
volumes:
- redis-data:/data
n8n-main:
image: n8nio/n8n:latest
restart: unless-stopped
ports:
- "5678:5678"
environment:
- EXECUTIONS_MODE=queue
- QUEUE_BULL_REDIS_HOST=redis
- QUEUE_BULL_REDIS_PORT=6379
- QUEUE_BULL_REDIS_PASSWORD=your_redis_password
volumes:
- n8n-data:/home/node/.n8n
n8n-worker:
image: n8nio/n8n:latest
restart: unless-stopped
command: worker
environment:
- EXECUTIONS_MODE=queue
- QUEUE_BULL_REDIS_HOST=redis
- QUEUE_BULL_REDIS_PORT=6379
- QUEUE_BULL_REDIS_PASSWORD=your_redis_password
volumes:
- n8n-data:/home/node/.n8n
volumes:
redis-data:
n8n-data:
Workflows queued in Redis, executed by worker processes. Scale by adding more workers.
Complete Production-Ready Configuration Example
Here’s a docker-compose.yml with proper environment variables:
version: '3.8'
services:
postgres:
image: postgres:15-alpine
restart: unless-stopped
environment:
- POSTGRES_DB=n8n
- POSTGRES_USER=n8n
- POSTGRES_PASSWORD=secure_db_password_here
volumes:
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U n8n"]
interval: 10s
timeout: 5s
retries: 5
n8n:
image: n8nio/n8n:latest
restart: unless-stopped
ports:
- "5678:5678"
environment:
# Basic Configuration
- N8N_HOST=n8n.yourdomain.com
- N8N_PORT=5678
- N8N_PROTOCOL=https
- NODE_ENV=production
- WEBHOOK_URL=https://n8n.yourdomain.com/
# Timezone
- GENERIC_TIMEZONE=America/New_York
# Security
- N8N_BASIC_AUTH_ACTIVE=true
- N8N_BASIC_AUTH_USER=admin_username
- N8N_BASIC_AUTH_PASSWORD=super_secure_password_here
# Database (PostgreSQL)
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=n8n
- DB_POSTGRESDB_PASSWORD=secure_db_password_here
# Execution Settings
- EXECUTIONS_PROCESS=main
- EXECUTIONS_TIMEOUT=300
- EXECUTIONS_DATA_SAVE_ON_SUCCESS=none
- EXECUTIONS_DATA_SAVE_ON_ERROR=all
- EXECUTIONS_DATA_SAVE_MANUAL_EXECUTIONS=true
- EXECUTIONS_DATA_MAX_AGE=168
- EXECUTIONS_DATA_PRUNE=true
# Performance
- N8N_CONCURRENCY_PRODUCTION_LIMIT=10
- N8N_PAYLOAD_SIZE_MAX=16
# Logging
- N8N_LOG_LEVEL=info
volumes:
- n8n-data:/home/node/.n8n
- ./backups:/backups
depends_on:
postgres:
condition: service_healthy
# Resource limits (adjust based on VPS)
deploy:
resources:
limits:
cpus: '2'
memory: 2G
reservations:
memory: 1G
volumes:
postgres-data:
n8n-data:
This configuration:
- Uses PostgreSQL (not SQLite)
- Enables authentication
- Sets correct timezone
- Configures HTTPS webhooks
- Manages execution history
- Limits concurrent executions
- Production logging level
- Auto-restart on failure
- Health checks for database
Replace these values:
n8n.yourdomain.com→ Your actual domainadmin_username→ Your chosen usernamesuper_secure_password_here→ Strong password (useopenssl rand -base64 32)secure_db_password_here→ Database passwordAmerica/New_York→ Your timezone
Environment Variables Quick Reference Table
| Variable | Purpose | Common Value | Required? |
|---|---|---|---|
N8N_HOST | Your domain/IP | n8n.yourdomain.com | Yes |
N8N_PORT | Port n8n runs on | 5678 | Yes |
N8N_PROTOCOL | HTTP or HTTPS | https | Yes |
WEBHOOK_URL | Custom webhook base | Usually auto-generated | No |
GENERIC_TIMEZONE | Timezone | America/New_York | Yes |
N8N_BASIC_AUTH_ACTIVE | Enable auth | true | Yes |
N8N_BASIC_AUTH_USER | Username | Your choice | Yes |
N8N_BASIC_AUTH_PASSWORD | Password | Strong password | Yes |
NODE_ENV | Environment mode | production | Yes |
DB_TYPE | Database type | postgresdb | Yes |
DB_POSTGRESDB_HOST | DB server | localhost | If PostgreSQL |
DB_POSTGRESDB_DATABASE | DB name | n8n | If PostgreSQL |
EXECUTIONS_TIMEOUT | Max runtime (seconds) | 300 | Recommended |
EXECUTIONS_DATA_MAX_AGE | Keep history (hours) | 168 | Recommended |
N8N_CONCURRENCY_PRODUCTION_LIMIT | Parallel workflows | 5-10 | Recommended |
N8N_LOG_LEVEL | Logging detail | info | Optional |
EXECUTIONS_MODE | Regular or queue | regular | Optional |
Common Environment Variable Mistakes & Fixes
Mistake 1: Forgetting to Set Timezone
Symptom: Scheduled workflows run at wrong time.
# No timezone set (defaults to UTC)
# Scheduled for 9 AM → runs at 9 AM UTC
# Timezone explicitly set
GENERIC_TIMEZONE=America/New_York
# Scheduled for 9 AM → runs at 9 AM EST
Mistake 2: Disabling Authentication in Production
Symptom: Anyone can access your n8n instance.
# DANGEROUS - publicly accessible
N8N_BASIC_AUTH_ACTIVE=false
# SECURE - authentication required
N8N_BASIC_AUTH_ACTIVE=true
N8N_BASIC_AUTH_USER=admin
N8N_BASIC_AUTH_PASSWORD=strong_password
Mistake 3: Protocol Mismatch
Symptom: Webhooks don’t work, browser shows security warnings.
# Says HTTPS but no SSL certificate
N8N_PROTOCOL=https
# Result: "Your connection is not private"
# Match actual setup
# If no SSL yet:
N8N_PROTOCOL=http
# After setting up Let's Encrypt:
N8N_PROTOCOL=https
Mistake 4: Wrong PostgreSQL Host
Symptom: n8n fails to start with “connection refused” error.
# Wrong when using Docker Compose
DB_POSTGRESDB_HOST=localhost
# Correct - use service name
DB_POSTGRESDB_HOST=postgres
Docker Compose creates a network where services communicate by name, not “localhost”.
Mistake 5: Not Setting Execution Limits
Symptom: n8n crashes on small VPS under load.
# Unlimited concurrent executions
# N8N_CONCURRENCY_PRODUCTION_LIMIT not set
# Limited based on VPS resources
N8N_CONCURRENCY_PRODUCTION_LIMIT=5 # For 1GB RAM VPS
How to Update Environment Variables
Method 1: Edit docker-compose.yml
1. Edit the file:
nano docker-compose.yml
2. Change the variable:
environment:
- GENERIC_TIMEZONE=America/Los_Angeles # Changed from New_York
3. Restart n8n:
docker-compose down
docker-compose up -d
Changes take effect immediately.
Method 2: Using .env File
1. Create/edit .env file:
nano .env
2. Add variables:
N8N_HOST=n8n.yourdomain.com
GENERIC_TIMEZONE=America/New_York
DB_PASSWORD=secure_password
3. Reference in docker-compose.yml:
environment:
- N8N_HOST=${N8N_HOST}
- GENERIC_TIMEZONE=${GENERIC_TIMEZONE}
- DB_POSTGRESDB_PASSWORD=${DB_PASSWORD}
4. Restart:
docker-compose down
docker-compose up -d
Benefit: Sensitive values (passwords) separate from main config file.
Method 3: Environment Variables in Docker Command
For quick testing:
docker run -d \
-p 5678:5678 \
-e N8N_HOST=n8n.yourdomain.com \
-e N8N_PROTOCOL=https \
-e GENERIC_TIMEZONE=America/New_York \
-v n8n-data:/home/node/.n8n \
n8nio/n8n
Not recommended for production (hard to manage, easy to forget what you set).
Debugging Environment Variable Issues
Check What Variables Are Actually Set
View all environment variables inside running container:
docker exec n8n env | grep N8N
Example output:
N8N_HOST=n8n.yourdomain.com
N8N_PORT=5678
N8N_PROTOCOL=https
N8N_BASIC_AUTH_ACTIVE=true
If a variable doesn’t appear, it wasn’t set correctly.
Check n8n Startup Logs
View logs for configuration errors:
docker logs n8n | head -50
Look for:
UserSettings were generated and saved
Server is now listening on: 0.0.0.0:5678
Version: 1.x.x
Or errors like:
Error: Cannot connect to database
Error: Invalid timezone specified
Test Specific Settings
Test webhook URL generation:
- Create workflow with webhook trigger
- Check webhook URL in node settings
- Should show:
https://n8n.yourdomain.com/webhook/...
If shows http://undefined/webhook/...:
N8N_HOSTnot setN8N_PROTOCOLnot set
Test timezone:
- Create schedule trigger for “tomorrow at 9 AM”
- Check workflow execution list
- Time shown should match your local time, not UTC
Conclusion
Environment variables are the backbone of any self-hosted n8n setup. They give you full control over how your automation system runs without touching the core application.
Once you understand how to use them, everything becomes easier:
- You can switch from testing to production smoothly
- You can secure your instance properly
- You can connect domains, databases, and external services without confusion
Start your properly configured n8n instance today with Ucartz KVM VPS hosting. $10/month. Production-ready. Environment variables explained. Stop fighting configuration issues. Start building workflows that actually work.
FAQ
1. What are environment variables in n8n?
Environment variables are configuration settings used to control how n8n runs. They define things like port, domain, authentication, and database connections without modifying the application code.
6. Do I need all environment variables to run n8n?
No. You only need a few basic variables to start. Advanced variables are used for production setups like databases, scaling, and security.
7. Can I change environment variables after installation?
Yes. Update the values and restart your Docker container:
docker-compose down
docker-compose up -d




