Zapier charges $20/month for 750 tasks. Their business plan? $600/month. Meanwhile, n8n does everything Zapier does — and more — and you can self-host it for free. No task limits. No per-execution fees. Your data stays on your server.
This guide walks you through deploying n8n with Docker, PostgreSQL for reliability, a reverse proxy for HTTPS, and building your first real workflow.
What is n8n?
n8n (pronounced “nodemation”) is an open-source workflow automation platform. Think Zapier or Make.com, but:
- Self-hosted: Runs on your hardware
- No task limits: Run millions of automations for free
- 400+ integrations: Email, Slack, databases, APIs, AI models, RSS, webhooks
- Visual editor: Drag-and-drop workflow builder
- Code when needed: Write JavaScript/Python in any node
- AI-native: Built-in LLM nodes for Ollama, OpenAI, and more
n8n vs Zapier vs Make
| Feature | n8n (Self-Hosted) | Zapier | Make |
|---|---|---|---|
| Cost | Free | $20-600/mo | $9-300/mo |
| Task limits | Unlimited | 750-50K/mo | 1K-10K/mo |
| Integrations | 400+ | 6000+ | 1500+ |
| Custom code | Full JS/Python | Limited | Limited |
| Data privacy | 100% yours | Cloud | Cloud |
| AI/LLM nodes | Yes (Ollama, OpenAI) | Yes (OpenAI) | Limited |
| Self-host | Yes | No | No |
The tradeoff: Zapier has more pre-built integrations. n8n has fewer, but you can hit any API with the HTTP node, and custom code gives you unlimited flexibility.
Prerequisites
- A Linux server with Docker and Docker Compose
- A domain name (optional, but needed for webhooks)
- Reverse proxy like Traefik or Caddy (for HTTPS)
- 1GB RAM minimum, 2GB recommended
Docker Compose Setup
Here’s a production-ready setup with PostgreSQL (don’t use SQLite for anything serious):
# docker-compose.yml
version: '3.8'
services:
n8n:
image: n8nio/n8n:latest
container_name: n8n
restart: unless-stopped
ports:
- "5678:5678"
environment:
# Database
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=n8n-db
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=n8n
- DB_POSTGRESDB_PASSWORD=changeme_use_strong_password
# General
- N8N_HOST=n8n.yourdomain.com
- N8N_PORT=5678
- N8N_PROTOCOL=https
- WEBHOOK_URL=https://n8n.yourdomain.com/
# Security
- N8N_BASIC_AUTH_ACTIVE=true
- N8N_BASIC_AUTH_USER=admin
- N8N_BASIC_AUTH_PASSWORD=changeme_strong_password
# Timezone
- GENERIC_TIMEZONE=America/New_York
- TZ=America/New_York
volumes:
- n8n_data:/home/node/.n8n
depends_on:
n8n-db:
condition: service_healthy
n8n-db:
image: postgres:16-alpine
container_name: n8n-db
restart: unless-stopped
environment:
- POSTGRES_DB=n8n
- POSTGRES_USER=n8n
- POSTGRES_PASSWORD=changeme_use_strong_password
volumes:
- n8n_db_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U n8n"]
interval: 10s
timeout: 5s
retries: 5
volumes:
n8n_data:
n8n_db_data:
Deploy it:
mkdir -p ~/n8n && cd ~/n8n
# Save the compose file above, then:
docker compose up -d
Check it’s running:
docker compose logs -f n8n
# Wait for "n8n ready on 0.0.0.0, port 5678"
Visit http://your-server:5678 and log in with the basic auth credentials you set.
Reverse Proxy Configuration
For production use with HTTPS and webhooks, put n8n behind a reverse proxy.
Caddy (Simplest)
Traefik Labels
Add these labels to the n8n service in your compose file if you’re using Traefik:
labels:
- "traefik.enable=true"
- "traefik.http.routers.n8n.rule=Host(`n8n.yourdomain.com`)"
- "traefik.http.routers.n8n.tls.certresolver=letsencrypt"
- "traefik.http.services.n8n.loadbalancer.server.port=5678"
Building Your First Workflow
Let’s build something practical: a webhook that receives data, processes it, and sends a notification.
Example: RSS → Summary → Telegram Notification
This workflow checks an RSS feed every hour, summarizes new posts with a local LLM, and sends them to Telegram.
- Open n8n and click “New Workflow”
- Add trigger: Search for “Schedule Trigger” → Set to every 1 hour
- Add RSS node: Feed URL →
https://news.ycombinator.com/rss - Add IF node: Filter for posts with score > 100 (or any criteria)
- Add HTTP Request node: POST to your local Ollama instance:
- URL:
http://host.docker.internal:11434/api/generate - Body:
{"model": "llama3.1", "prompt": "Summarize in 2 sentences: {{$json.title}} - {{$json.contentSnippet}}"}
- URL:
- Add Telegram node: Send message to your channel/chat
- Activate the workflow
Example: Webhook → Process → Email
- Add Webhook node → Copy the webhook URL
- Add Set node → Map incoming JSON fields
- Add IF node → Check required fields exist
- Add Gmail node → Send formatted email
- Test with
curl -X POST your-webhook-url -d '{"name":"test","email":"[email protected]"}'
Useful Workflow Ideas
- Server monitoring: Ping endpoints every 5 min → alert on failure
- Content pipeline: RSS feeds → AI summary → publish to blog/social
- Invoice processing: Email attachment → OCR → add to spreadsheet
- Social media: Schedule posts across platforms from one workflow
- Backup alerts: Check backup status → notify if stale
- Price tracking: Scrape prices → alert on drops
- AI chatbot: Webhook → Ollama → respond (build your own API)
Connecting to Local AI (Ollama)
n8n has built-in LLM nodes. To use your self-hosted Ollama:
- Go to Settings → Credentials → Add Credential
- Search “Ollama” → Add with base URL
http://host.docker.internal:11434 - In workflows, use the AI Agent, Chat Model, or HTTP Request nodes
If n8n and Ollama are in the same Docker network, use the container name instead:
# Add to n8n's docker-compose.yml
networks:
default:
external:
name: ollama_default
Then use http://ollama:11434 as the base URL.
Backup Strategy
Your workflows and credentials live in two places:
1. Database Backup (PostgreSQL)
# Dump the database
docker exec n8n-db pg_dump -U n8n n8n > n8n-backup-$(date +%Y%m%d).sql
# Automate with cron
0 3 * * * docker exec n8n-db pg_dump -U n8n n8n | gzip > /backups/n8n/n8n-$(date +\%Y\%m\%d).sql.gz
2. Export Workflows (JSON)
n8n can export all workflows via the API:
curl -u admin:yourpassword https://n8n.yourdomain.com/api/v1/workflows \
| jq '.data' > workflows-backup.json
3. Volume Backup
docker compose stop
tar czf n8n-volumes-$(date +%Y%m%d).tar.gz \
/var/lib/docker/volumes/n8n_n8n_data \
/var/lib/docker/volumes/n8n_n8n_db_data
docker compose start
Performance Tuning
For heavy workloads:
environment:
# Increase execution concurrency
- EXECUTIONS_PROCESS=main
- EXECUTIONS_TIMEOUT=600
- EXECUTIONS_TIMEOUT_MAX=1200
# Queue mode for high throughput
# - EXECUTIONS_MODE=queue
# - QUEUE_BULL_REDIS_HOST=redis
For very high throughput (10K+ executions/day), enable queue mode with Redis.
Troubleshooting
Webhooks not working: Ensure WEBHOOK_URL matches your public URL exactly. Check reverse proxy is forwarding to port 5678.
Can’t connect to external services: If n8n is in Docker, use host.docker.internal to reach services on the host. On Linux, add extra_hosts: ["host.docker.internal:host-gateway"] to the compose file.
Workflows stop running: Check that the workflow is activated (toggle in top-right). Check execution logs in the n8n UI under “Executions.”
Database connection errors: Verify PostgreSQL is healthy: docker exec n8n-db pg_isready -U n8n. Check password matches between services.
Out of memory: n8n can be memory-hungry with complex workflows. Increase container memory limit or add swap.
Updating n8n
cd ~/n8n
docker compose pull
docker compose up -d
Always check the release notes before major version updates. Back up your database first.
What’s Next?
With n8n running, you’ve got an automation engine that rivals enterprise tools:
- Connect it to your Ollama instance for AI-powered workflows
- Set up Uptime Kuma and trigger n8n workflows on downtime
- Build an AI content pipeline: RSS → summarize → publish
- Create webhook endpoints for external services
- Explore the n8n community workflows for inspiration
Zero monthly fees. Unlimited executions. Your data, your server, your rules.