n8n is the automation platform that developers actually want to use. Self-hostable, open-source, with a visual editor and full code access. Here's how to build production workflows that handle real business logic.
Why n8n Over Zapier
- Self-hosted: Your data never leaves your infrastructure
- Code nodes: Write real JavaScript/Python when visual nodes aren't enough
- Free tier: No per-task pricing — unlimited executions on self-hosted
- API-first: Every workflow is a REST endpoint
- Version control: Export workflows as JSON, commit to git
Self-Hosting with Docker
# docker-compose.yml
version: '3.8'
services:
n8n:
image: docker.n8n.io/n8nio/n8n
restart: always
ports:
- '5678:5678'
environment:
- N8N_BASIC_AUTH_ACTIVE=true
- N8N_BASIC_AUTH_USER=admin
- N8N_BASIC_AUTH_PASSWORD=${N8N_PASSWORD}
- N8N_HOST=${DOMAIN}
- N8N_PROTOCOL=https
- WEBHOOK_URL=https://${DOMAIN}/
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=db
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=n8n
- DB_POSTGRESDB_PASSWORD=${DB_PASSWORD}
volumes:
- n8n_data:/home/node/.n8n
depends_on:
- db
db:
image: postgres:15
environment:
POSTGRES_DB: n8n
POSTGRES_USER: n8n
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
n8n_data:
postgres_data:
Webhook Trigger Workflow
Every workflow can be triggered by an HTTP request:
Webhook (POST /webhook/new-signup)
-> Code Node (validate + enrich data)
-> IF Node (paid vs free tier)
-> [paid] HTTP Request (provision GitHub repo access)
-> [paid] Send Email (welcome + repo link)
-> [free] Send Email (welcome + upgrade CTA)
-> Postgres (log to database)
Code Node for Custom Logic
// Code node -- runs in n8n's sandboxed environment
const items = $input.all()
return items.map(item => {
const { email, plan, stripeCustomerId } = item.json
// Enrich with computed fields
return {
json: {
...item.json,
tier: plan === 'pro' ? 'paid' : 'free',
onboardingUrl: `https://app.example.com/onboard?email=${encodeURIComponent(email)}`,
createdAt: new Date().toISOString(),
}
}
})
Calling n8n from Your App
// Trigger a workflow from Next.js
async function triggerWorkflow(workflowId: string, data: unknown) {
const response = await fetch(
`${process.env.N8N_URL}/webhook/${workflowId}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data),
}
)
if (!response.ok) {
throw new Error(`n8n workflow failed: ${response.status}`)
}
return response.json()
}
// Usage after Stripe checkout
await triggerWorkflow('new-purchase', {
email: session.customer_email,
productId: session.metadata.productId,
stripeSessionId: session.id,
})
Error Alerting Workflow
A simple workflow that monitors your app and alerts on failures:
Webhook (POST /webhook/error-alert)
-> Code Node (format error message)
-> Send Email (to atlas@whoffagents.com)
-> Slack (optional: post to #alerts channel)
// In your app -- report errors to n8n
async function reportError(script: string, error: string) {
await fetch('http://localhost:5678/webhook/error-alert', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ script, error, timestamp: new Date().toISOString() }),
}).catch(() => {}) // fire and forget
}
Scheduled Workflows
Replace cron jobs with n8n schedules:
- Daily analytics aggregation at 6 AM
- Weekly email digest every Monday
- Monthly churn report on the 1st
n8n's schedule trigger handles timezone, daylight saving, and missed executions automatically.
The Workflow Automator MCP at whoffagents.com connects your Claude sessions directly to n8n, Make.com, and Zapier — trigger any workflow from natural language. $15/mo.
Top comments (0)