n8n ile İlk Otomasyon Workflow’unuzu Oluşturun

Otomasyon dünyasına ilk adımı atmak her zaman biraz ürkütücü hissettiriyor. Kod yazacaksın, API’larla boğuşacaksın, hata ayıklamak için saatler harcayacaksın… n8n bu algıyı tamamen değiştiren bir araç. Ama dikkat: “kolay” demek “güçsüz” demek değil. Birkaç ay önce bir müşterimizin ERP sistemi ile Slack ve e-posta altyapısını n8n ile entegre ettik. Yazacağım iş akışı bu deneyimin sadeleştirilmiş bir versiyonu.

n8n Nedir ve Neden Önemli?

n8n (telaffuz: “n-eight-n”), açık kaynaklı, self-hosted çalıştırılabilen bir iş akışı otomasyon platformu. Zapier veya Make.com gibi bulut tabanlı alternatiflerine kıyasla en büyük avantajı: veriniz sizde kalıyor. KVKK uyumluluğu açısından bu özellikle kritik.

Türkiye’deki şirketlerin büyük çoğunluğu müşteri verilerini, fatura bilgilerini veya HR datasını üçüncü taraf bulut servislerinden geçirmekten çekiniyor. Haklılar da. n8n’i kendi sunucunuzda çalıştırdığınızda bu sorun ortadan kalkıyor.

Temel özellikleri şöyle sıralayabilirim:

  • Görsel iş akışı tasarımı: Düğümleri sürükle-bırak ile bağlayarak karmaşık entegrasyonlar oluşturabiliyorsunuz
  • 400+ entegrasyon: Slack, Gmail, PostgreSQL, HTTP Request, GitHub ve çok daha fazlası
  • JavaScript desteği: Özel kod yazmak gerektiğinde Function düğümü ile tam kontrol
  • Webhook desteği: Dış sistemlerin n8n’i tetiklemesine olanak tanıyor
  • Hata yönetimi: Başarısız iş akışları için özel hata rotaları tanımlanabiliyor

Kurulum: Docker ile Hızlı Başlangıç

Production ortamı için Docker Compose kullanmayı öneriyorum. Hem yönetimi kolaylaşıyor hem de backup/restore işlemleri çok daha temiz oluyor.

Önce bir dizin oluşturun ve gerekli dosyaları hazırlayın:

mkdir -p /opt/n8n && cd /opt/n8n
mkdir -p ./data/n8n
chmod 777 ./data/n8n

Şimdi docker-compose.yml dosyasını oluşturun:

cat > docker-compose.yml << 'EOF'
version: '3.8'

services:
  n8n:
    image: n8nio/n8n:latest
    restart: unless-stopped
    ports:
      - "5678:5678"
    environment:
      - N8N_HOST=n8n.sirketiniz.com
      - N8N_PORT=5678
      - N8N_PROTOCOL=https
      - NODE_ENV=production
      - WEBHOOK_URL=https://n8n.sirketiniz.com/
      - GENERIC_TIMEZONE=Europe/Istanbul
      - TZ=Europe/Istanbul
      - N8N_BASIC_AUTH_ACTIVE=true
      - N8N_BASIC_AUTH_USER=admin
      - N8N_BASIC_AUTH_PASSWORD=guclu_bir_sifre_koyun
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_PORT=5432
      - DB_POSTGRESDB_DATABASE=n8n
      - DB_POSTGRESDB_USER=n8n
      - DB_POSTGRESDB_PASSWORD=db_sifreniz
    volumes:
      - ./data/n8n:/home/node/.n8n
    depends_on:
      - postgres

  postgres:
    image: postgres:15
    restart: unless-stopped
    environment:
      - POSTGRES_DB=n8n
      - POSTGRES_USER=n8n
      - POSTGRES_PASSWORD=db_sifreniz
    volumes:
      - ./data/postgres:/var/lib/postgresql/data

EOF

Servisi ayağa kaldırın:

docker compose up -d
docker compose logs -f n8n

Birkaç dakika sonra http://sunucu-ip:5678 adresinden arayüze erişebilirsiniz. İlk açılışta hesap oluşturmanızı isteyecek.

İlk Workflow: Günlük Sunucu Raporu

Şimdi gerçek bir senaryo üzerinden gidelim. Amacımız her sabah 08:00’de sunucu disk kullanım bilgilerini Slack kanalına otomatik olarak gönderen bir iş akışı oluşturmak.

Bu iş akışı şu düğümlerden oluşacak:

  • Schedule Trigger: Her sabah 08:00’de tetikler
  • HTTP Request: Sunucu API’sinden ya da bir script çıktısından veri çeker
  • Code düğümü: Veriyi Slack formatına dönüştürür
  • Slack: Mesajı ilgili kanala gönderir

Schedule Trigger Ayarları

n8n arayüzünde “+” butonuna tıklayın ve “Schedule Trigger” düğümünü seçin. Ayarlar şöyle olmalı:

  • Trigger at: Every Day
  • Hour: 8
  • Minute: 0

Bu kadar. Cron ifadesi yazmak zorunda değilsiniz ama isterseniz “Custom (Cron)” seçeneğiyle 0 8 1-5 gibi sadece hafta içi çalıştırma da yapabilirsiniz.

Sunucu Metrik Verisi Çekmek

Gerçek ortamda bu aşamada Prometheus, Netdata veya kendi yazdığınız bir API olabilir. Basit bir örnek olarak Linux sunucunuzda çalışan küçük bir shell script ile HTTP endpoint oluşturalım.

Sunucuda aşağıdaki scripti /usr/local/bin/disk-metrics.sh olarak kaydedin:

#!/bin/bash
# Disk kullanim bilgilerini JSON olarak dondurur

OUTPUT='{"hostname":"'$(hostname)'","timestamp":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","disks":['

FIRST=true
while IFS= read -r line; do
    FILESYSTEM=$(echo $line | awk '{print $1}')
    SIZE=$(echo $line | awk '{print $2}')
    USED=$(echo $line | awk '{print $3}')
    AVAIL=$(echo $line | awk '{print $4}')
    PERCENT=$(echo $line | awk '{print $5}' | tr -d '%')
    MOUNT=$(echo $line | awk '{print $6}')

    if [ "$FIRST" = true ]; then
        FIRST=false
    else
        OUTPUT="$OUTPUT,"
    fi

    OUTPUT="$OUTPUT"'{"filesystem":"'$FILESYSTEM'","size":"'$SIZE'","used":"'$USED'","available":"'$AVAIL'","percent":'$PERCENT',"mountpoint":"'$MOUNT'"}'

done < <(df -h | grep -v "tmpfs|udev|Filesystem")

OUTPUT="$OUTPUT]}"
echo $OUTPUT
chmod +x /usr/local/bin/disk-metrics.sh
# Test edin
/usr/local/bin/disk-metrics.sh

Bu scripti basit bir Python HTTP servisi ile dışarıya açabilirsiniz:

cat > /usr/local/bin/metrics-server.py << 'EOF'
#!/usr/bin/env python3
from http.server import HTTPServer, BaseHTTPRequestHandler
import subprocess
import json

class MetricsHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        if self.path == '/disk':
            result = subprocess.run(
                ['/usr/local/bin/disk-metrics.sh'],
                capture_output=True, text=True
            )
            self.send_response(200)
            self.send_header('Content-Type', 'application/json')
            self.end_headers()
            self.wfile.write(result.stdout.encode())
        else:
            self.send_response(404)
            self.end_headers()

    def log_message(self, format, *args):
        pass  # Sessiz mod

if __name__ == '__main__':
    server = HTTPServer(('0.0.0.0', 9090), MetricsHandler)
    print('Metrics server port 9090 uzerinde calisıyor')
    server.serve_forever()
EOF

chmod +x /usr/local/bin/metrics-server.py

Bunu systemd servisi olarak tanımlamak daha doğru:

cat > /etc/systemd/system/metrics-server.service << 'EOF'
[Unit]
Description=Disk Metrics HTTP Server
After=network.target

[Service]
Type=simple
ExecStart=/usr/bin/python3 /usr/local/bin/metrics-server.py
Restart=always
User=nobody

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable --now metrics-server
systemctl status metrics-server

n8n’de HTTP Request Düğümü

Schedule Trigger’dan sonra “HTTP Request” düğümü ekleyin:

  • Method: GET
  • URL: http://sunucu-ip:9090/disk
  • Authentication: None (iç ağdaysanız)

Düğümü çalıştırdığınızda JSON verisini alacaksınız. n8n bunu otomatik olarak parse ediyor.

Code Düğümü ile Veri Dönüşümü

HTTP Request’ten gelen ham veriyi Slack’in anlayacağı formata çevirmemiz gerekiyor. “Code” düğümü ekleyin ve aşağıdaki JavaScript kodunu yapıştırın:

// Onceki dugumden gelen veriyi al
const data = $input.first().json;
const hostname = data.hostname;
const timestamp = data.timestamp;
const disks = data.disks;

// Kritik diskler icin uyari
const criticalDisks = disks.filter(d => d.percent >= 80);
const warningDisks = disks.filter(d => d.percent >= 60 && d.percent < 80);
const healthyDisks = disks.filter(d => d.percent < 60);

// Slack mesaj bloklari olustur
let diskLines = disks.map(disk => {
  let emoji = '🟢';
  if (disk.percent >= 80) emoji = '🔴';
  else if (disk.percent >= 60) emoji = '🟡';

  return `${emoji} *${disk.mountpoint}*: %${disk.percent} dolu (${disk.used}/${disk.size})`;
}).join('n');

let alertSection = '';
if (criticalDisks.length > 0) {
  const mounts = criticalDisks.map(d => d.mountpoint).join(', ');
  alertSection = `nn⚠️ *Kritik Uyari:* ${mounts} bolumu %80 uzerinde!`;
}

const message = {
  text: `📊 *Gunluk Disk Raporu - ${hostname}*n_${timestamp}_nn${diskLines}${alertSection}`
};

return [{ json: message }];

Slack Entegrasyonu

Slack düğümünü eklemeden önce bir Slack App oluşturmanız gerekiyor. Slack’in developer portalına gidin, yeni bir app oluşturun ve “Incoming Webhooks” özelliğini aktive edin. Size bir webhook URL’si verecek.

n8n’de “Slack” düğümünü ekleyin:

  • Resource: Message
  • Operation: Post
  • Authentication: Webhook URL’nizi credential olarak ekleyin
  • Channel: #sunucu-bildirimleri
  • Text: {{ $json.text }}

Workflow’u Test Etmek

Arayüzün sağ üstündeki “Test workflow” butonuna tıklayın. Her düğümün çıktısını tek tek görebilirsiniz. Bir şeyler yanlış giderse hangi düğümde hata oluştuğunu hemen görürsünüz.

Her şey yolundaysa “Save” ve ardından “Activate” butonuna basın. Artık iş akışınız her sabah 08:00’de otomatik olarak çalışacak.

İkinci Senaryo: Webhook ile Anlık Bildirim

Bir önceki örnek zamanlanmış çalışıyordu. Şimdi daha reactive bir senaryo: bir sunucuda disk kullanımı %90’ı geçtiğinde anlık bildirim gönderme.

n8n’de “Webhook” düğümüyle başlayan yeni bir workflow oluşturun. n8n size şöyle bir URL verecek:

https://n8n.sirketiniz.com/webhook/disk-alert

Bu URL’yi sunucunuzdaki monitoring scriptinizden çağırabilirsiniz:

#!/bin/bash
# /usr/local/bin/check-disk-alert.sh
# cron ile her 15 dakikada bir calistirilir

THRESHOLD=90
WEBHOOK_URL="https://n8n.sirketiniz.com/webhook/disk-alert"

while IFS= read -r line; do
    PERCENT=$(echo $line | awk '{print $5}' | tr -d '%')
    MOUNT=$(echo $line | awk '{print $6}')
    HOSTNAME=$(hostname)

    if [ "$PERCENT" -ge "$THRESHOLD" ] 2>/dev/null; then
        curl -s -X POST "$WEBHOOK_URL" 
            -H "Content-Type: application/json" 
            -d "{"hostname":"$HOSTNAME","mountpoint":"$MOUNT","percent":$PERCENT,"severity":"critical"}"
    fi
done < <(df -h | grep -v "tmpfs|udev|Filesystem")
# Crontab'a ekleyin
echo "*/15 * * * * /usr/local/bin/check-disk-alert.sh" | crontab -

Bu script çalıştığında n8n webhook’u tetikliyor, n8n de ilgili işlemleri yapıp bildirim gönderiyor. Slack yerine PagerDuty, Telegram veya e-posta da kullanabilirsiniz.

Hata Yönetimi

Production ortamında workflow’larınıza mutlaka hata yönetimi ekleyin. n8n’de bunun iki yolu var.

İlki “Error Trigger” düğümü: Herhangi bir workflow hata verdiğinde tetiklenen ayrı bir workflow oluşturabilirsiniz. Bu workflow genellikle mail veya Slack bildirimi gönderir.

İkincisi “Try/Catch” mantığı için “IF” düğümü kullanmak. HTTP Request başarısız olduğunda alternatif bir yol izleyebilirsiniz:

Workflow ayarlarından “Error Workflow” bölümüne gidin ve hata durumunda çalışacak ikinci bir workflow seçin. Bu workflow’da şu kod işinizi görür:

// Hata bilgilerini formatla
const errorData = $input.first().json;

const message = {
  text: `🚨 *n8n Workflow Hatasi*n` +
        `*Workflow:* ${errorData.workflow.name}n` +
        `*Hata:* ${errorData.execution.error.message}n` +
        `*Zaman:* ${new Date().toLocaleString('tr-TR')}n` +
        `*Execution ID:* ${errorData.execution.id}`
};

return [{ json: message }];

Backup ve Restore

Workflow’larınızı kaybetmemek için düzenli backup alın. n8n arayüzünden “Settings > Import/Export” ile tüm workflow’ları JSON olarak export edebilirsiniz. Ama bunu otomatize etmek daha akıllıca:

#!/bin/bash
# /usr/local/bin/n8n-backup.sh
BACKUP_DIR="/backup/n8n"
DATE=$(date +%Y%m%d_%H%M%S)
CONTAINER_NAME="n8n-n8n-1"

mkdir -p "$BACKUP_DIR"

# PostgreSQL backup
docker exec n8n-postgres-1 pg_dump -U n8n n8n | 
    gzip > "$BACKUP_DIR/n8n_db_${DATE}.sql.gz"

# n8n data dizini backup
tar -czf "$BACKUP_DIR/n8n_data_${DATE}.tar.gz" 
    -C /opt/n8n/data/n8n .

# 30 gunden eski backuplari sil
find "$BACKUP_DIR" -name "*.gz" -mtime +30 -delete

echo "Backup tamamlandi: $BACKUP_DIR"
# Haftada bir pazar gunu sabah 02:00'de calisir
echo "0 2 * * 0 /usr/local/bin/n8n-backup.sh >> /var/log/n8n-backup.log 2>&1" | crontab -

Güvenlik Notları

n8n’i internete açıyorsanız birkaç önlem almanız şart:

  • Mutlaka HTTPS kullanın. Nginx reverse proxy + Let’s Encrypt kombinasyonu en kolay yol
  • N8N_BASIC_AUTH_ACTIVE=true ile basic auth açık olsun
  • Webhook URL’lerinizi tahmin edilemez tutun, n8n otomatik UUID üretiyor ama custom path kullanmayın
  • Sunucu erişimini IP whitelist ile kısıtlayabilirsiniz (Nginx allow/deny direktifleri)
  • Production’da N8N_LOG_LEVEL=warn ile log verbosity’sini azaltın, hassas veri loglarda görünmesin

Sonuç

n8n ile ilk workflow’ınızı oluşturduktan sonra “bunu daha önce neden yapmadım” diye soracaksınız. Disk raporu örneğiyle başladık ama aynı mantıkla yapabilecekleriniz çok daha geniş: yeni bir GitHub PR açıldığında Jira’da otomatik ticket oluşturma, müşteri formu doldurulduğunda CRM’e kayıt atma, SSL sertifikası sona ermeden 30 gün önce uyarı gönderme, log analizi yapıp anomali tespiti…

Önemli olan ilk adımı atmak. Bu yazıdaki örnekleri doğrudan çalıştırabilirsiniz. Bir kez çalışan bir workflow gördüğünüzde geri kalan her şey daha kolay geliyor. n8n’in community forum’u da oldukça aktif, sorun yaşadığınızda genellikle birisi aynı soruyu sormuş oluyor.

Self-hosted araçların en büyük dezavantajı maintenance sorumluluğunun size ait olması. Ama verileriniz sizde, maliyet düşük ve özelleştirme sonsuz. Bence bu tradeoff açıkça n8n lehine.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir