ngrok ile Yerel Webhook Geliştirme Ortamı Kurulumu
Webhook geliştirirken en can sıkıcı problem şu: yazdığın kodu test etmek için her seferinde bir sunucuya deploy etmek zorunda kalıyorsun. GitHub’dan push event’i gelecek, Stripe’tan ödeme bildirimi gelecek, Slack’ten bir mesaj tetiklenecek ama senin localhost:3000’in dış dünyaya kapalı. İşte tam bu noktada ngrok devreye giriyor ve hayatını kurtarıyor.
ngrok Nedir ve Nasıl Çalışır?
ngrok, lokal makinendeki bir portu güvenli bir tünel aracılığıyla internete açan bir araç. Teknik olarak konuşursak: ngrok sunucuları üzerinden encrypted bir tünel kuruyor ve sana https://abc123.ngrok.io gibi geçici bir public URL veriyor. Bu URL’e gelen tüm istekler lokal makinendeki uygulamana iletiliyor.
Webhook geliştirme senaryosunda şöyle çalışıyor:
- Stripe bir ödeme işlemi tamamlandığında
https://abc123.ngrok.io/webhook/stripeadresine POST isteği gönderiyor - ngrok bu isteği alıyor ve lokal
localhost:3000/webhook/stripeadresine iletiiyor - Uygulamandan dönen yanıt da aynı şekilde geri gönderiliyor
Araya production deploy atmadan, gerçek webhook verisiyle lokal ortamda debug yapabiliyorsun. Bu iş akışını bir kez tattıktan sonra eskiye dönmek istemiyorsun.
Kurulum
Linux Kurulumu
# Snap ile kurulum (Ubuntu/Debian)
sudo snap install ngrok
# Ya da doğrudan binary indirme
curl -s https://ngrok-agent.s3.amazonaws.com/ngrok.asc | sudo tee /etc/apt/trusted.gpg.d/ngrok.asc >/dev/null
echo "deb https://ngrok-agent.s3.amazonaws.com buster main" | sudo tee /etc/apt/sources.list.d/ngrok.list
sudo apt update && sudo apt install ngrok
# Arch Linux
yay -S ngrok
macOS Kurulumu
# Homebrew ile
brew install ngrok/ngrok/ngrok
Windows Kurulumu
# Chocolatey ile
choco install ngrok
# Ya da Scoop ile
scoop install ngrok
Kurulum sonrası ngrok hesabı oluşturman gerekiyor. [ngrok.com](https://ngrok.com) adresinden ücretsiz hesap açabilirsin. Ücretsiz plan çoğu geliştirme senaryosu için yeterli ama bazı kısıtlamaları var (buna sonra değineceğiz).
Authentication Token’ı Yapılandırma
Hesap oluşturduktan sonra dashboard’dan authtoken’ını alıp ayarlaman gerekiyor:
ngrok config add-authtoken YOUR_AUTH_TOKEN_BURADA
# Config dosyasının nerede olduğunu görmek için
ngrok config check
Token ~/.config/ngrok/ngrok.yml dosyasına yazılıyor. Linux’ta bu dosyayı doğrudan da düzenleyebilirsin:
# ~/.config/ngrok/ngrok.yml
version: "2"
authtoken: YOUR_AUTH_TOKEN_BURADA
İlk Tüneli Başlatmak
En basit kullanım şekli şu:
# 3000 portunu internete aç
ngrok http 3000
# HTTPS tüneli (varsayılan olarak zaten HTTPS açıyor)
ngrok http --bind-tls=true 3000
Komutu çalıştırdığında terminalde şöyle bir çıktı göreceksin:
Session Status online
Account [email protected] (Plan: Free)
Update update available
Version 3.3.0
Region Europe (eu)
Latency 23ms
Web Interface http://127.0.0.1:4040
Forwarding https://abc123def456.ngrok-free.app -> http://localhost:3000
Connections ttl opn rt1 rt5 p50 p90
0 0 0.00 0.00 0.00 0.00
Burada kritik iki şey var:
- Forwarding URL: Dış dünyaya verdiğin adres, bu adresi webhook servislerine tanımlayacaksın
- Web Interface:
http://127.0.0.1:4040adresinde ngrok’un yerel dashboard’u açılıyor, tüm istekleri buradan izleyebilirsin
Web Interface ile Debug Yapmak
ngrok’un en güçlü özelliklerinden biri web arayüzü. Tarayıcıdan http://localhost:4040 adresini açtığında her gelen isteğin detayını görebiliyorsun:
- HTTP method ve path
- Request headers
- Request body (JSON, form data, hepsi)
- Response status kodu
- Response body
- Gecikme süresi
Özellikle Stripe veya GitHub webhook’larını test ederken bu arayüz inanılmaz işe yarıyor. Bir istek geldiğinde tam payload’u görüp kendi kodunda ne beklediğini anlıyorsun.
Daha da güzeli: Replay butonu var. Bir isteği tekrar tekrar gönderebiliyorsun. Webhook handler’ında bir bug buldun, düzelttdin, uygulamayı yeniden başlattın ve aynı isteği replay edebiliyorsun. Gerçek webhook servisini tekrar tetiklemene gerek kalmıyor.
Gerçek Dünya Senaryosu 1: Stripe Webhook Entegrasyonu
Stripe ile çalışıyorsun ve ödeme başarılı olduğunda kendi uygulamana bildirim gelsin istiyorsun. Normalde bunu test etmek için ya production ortamına deploy atmak ya da Stripe’ın test event’lerini kullanmak gerekiyor. ngrok ile çok daha kolay.
Önce basit bir webhook handler yazalım (Node.js/Express örneği):
// webhook-server.js
const express = require('express');
const app = express();
// Stripe webhook için raw body gerekli
app.use('/webhook/stripe', express.raw({ type: 'application/json' }));
app.use(express.json());
app.post('/webhook/stripe', (req, res) => {
const event = JSON.parse(req.body);
console.log(`Event type: ${event.type}`);
console.log(`Event data:`, JSON.stringify(event.data, null, 2));
switch (event.type) {
case 'payment_intent.succeeded':
const paymentIntent = event.data.object;
console.log(`Ödeme başarılı! Amount: ${paymentIntent.amount}`);
// Veritabanı güncellemesi, email gönderimi vs.
break;
case 'customer.subscription.deleted':
console.log('Abonelik iptal edildi');
break;
default:
console.log(`Bilinmeyen event: ${event.type}`);
}
res.json({ received: true });
});
app.listen(3000, () => {
console.log('Webhook server 3000 portunda çalışıyor');
});
Sunucuyu başlat, ngrok’u aç:
node webhook-server.js &
ngrok http 3000
Aldığın URL’i (örneğin https://abc123.ngrok-free.app) Stripe Dashboard’da Developers > Webhooks bölümüne ekle. Endpoint URL olarak https://abc123.ngrok-free.app/webhook/stripe yaz.
Artık Stripe’ta test ödeme yapabilir ve lokal terminalde event’in geldiğini görebilirsin. Hem Stripe’ın arayüzünde hem de ngrok’un web arayüzünde her şeyi izleyebilirsin.
Gerçek Dünya Senaryosu 2: GitHub Webhook ile CI/CD Testi
GitHub repository’ne push atıldığında tetiklenmesini istediğin bir script var. Bunu production’da test etmeden önce lokal ortamda doğrulamak istiyorsun.
# github_webhook.py
from flask import Flask, request, jsonify
import hashlib
import hmac
import json
import os
app = Flask(__name__)
GITHUB_SECRET = os.environ.get('GITHUB_SECRET', 'mysecrettoken')
def verify_signature(payload, signature):
"""GitHub webhook imzasını doğrula"""
mac = hmac.new(
GITHUB_SECRET.encode('utf-8'),
msg=payload,
digestmod=hashlib.sha256
)
expected = f"sha256={mac.hexdigest()}"
return hmac.compare_digest(expected, signature)
@app.route('/webhook/github', methods=['POST'])
def github_webhook():
signature = request.headers.get('X-Hub-Signature-256', '')
if not verify_signature(request.data, signature):
return jsonify({'error': 'Invalid signature'}), 401
event_type = request.headers.get('X-GitHub-Event')
payload = request.json
if event_type == 'push':
branch = payload['ref'].split('/')[-1]
commits = len(payload['commits'])
pusher = payload['pusher']['name']
print(f"Push event! Branch: {branch}, Commits: {commits}, By: {pusher}")
if branch == 'main':
print("Main branch'e push var, deployment tetikleniyor...")
# os.system("./deploy.sh") gibi bir şey çalıştırabilirsin
elif event_type == 'pull_request':
action = payload['action']
pr_title = payload['pull_request']['title']
print(f"PR Event: {action} - {pr_title}")
return jsonify({'status': 'ok'})
if __name__ == '__main__':
app.run(port=3000, debug=True)
# Secret'ı ayarla ve sunucuyu başlat
export GITHUB_SECRET="mysecrettoken"
python github_webhook.py &
# Tüneli aç
ngrok http 3000
GitHub’da repository Settings > Webhooks > Add webhook kısmına gidip ngrok URL’ini ekle. Content type olarak application/json seç, secret’ı gir ve hangi event’leri almak istediğini seç.
ngrok Config Dosyası ile Çoklu Tünel
Birden fazla servisi aynı anda dışarıya açman gerekebilir. Örneğin backend 3000’de, webhook handler 4000’de çalışıyor. Her birini ayrı terminalde açmak yerine config dosyası kullanabilirsin:
# ~/.config/ngrok/ngrok.yml
version: "2"
authtoken: YOUR_AUTH_TOKEN
tunnels:
backend:
addr: 3000
proto: http
inspect: true
webhook-handler:
addr: 4000
proto: http
inspect: true
grpc-service:
addr: 5000
proto: http
inspect: true
Tüm tünelleri aynı anda başlatmak için:
# Tüm tünelleri başlat
ngrok start --all
# Sadece belirli tünelleri başlat
ngrok start backend webhook-handler
Custom Subdomain Kullanımı
Ücretsiz planda her ngrok başlatışında farklı bir URL alıyorsun. Bu durum şunu zorlaştırıyor: her seferinde webhook URL’ini ilgili servise tekrar girmek gerekiyor. Paid planlarda sabit subdomain tanımlayabiliyorsun:
# Paid plan ile sabit subdomain
ngrok http --subdomain=mywebhooks 3000
# Bu şekilde her zaman aynı URL alırsın
# https://mywebhooks.ngrok.io
Eğer free plan kullanıyorsan ve bu can sıkıcı geliyorsa, webhook URL’ini her değiştiğinde otomatik güncelleyen basit bir script yazabilirsin. Örneğin ngrok’un API’sini kullanarak:
#!/bin/bash
# get-ngrok-url.sh
# ngrok başladıktan sonra aktif tünel URL'ini getir
sleep 2 # ngrok'un başlaması için bekle
NGROK_URL=$(curl -s http://localhost:4040/api/tunnels |
python3 -c "import sys, json; tunnels = json.load(sys.stdin)['tunnels'];
print([t['public_url'] for t in tunnels if t['proto'] == 'https'][0])")
echo "Aktif ngrok URL: $NGROK_URL"
echo "Webhook endpoint: $NGROK_URL/webhook"
# Otomatik olarak clipboard'a kopyala (Linux)
echo "$NGROK_URL/webhook" | xclip -selection clipboard
echo "URL clipboard'a kopyalandı!"
chmod +x get-ngrok-url.sh
ngrok http 3000 &
./get-ngrok-url.sh
ngrok’u Systemd Service Olarak Çalıştırmak
Geliştirme ortamında ngrok’u her oturumda manuel başlatmak istemiyorsan systemd service tanımlayabilirsin:
# /etc/systemd/system/ngrok-webhook.service
sudo tee /etc/systemd/system/ngrok-webhook.service << 'EOF'
[Unit]
Description=ngrok Webhook Tunnel
After=network.target
[Service]
Type=simple
User=youruser
ExecStart=/usr/local/bin/ngrok http 3000 --log=stdout
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable ngrok-webhook
sudo systemctl start ngrok-webhook
# Durumu kontrol et
sudo systemctl status ngrok-webhook
# Logları takip et
sudo journalctl -u ngrok-webhook -f
Güvenlik Konuları
ngrok kullanırken aklında bulundurman gereken birkaç önemli nokta var.
Kimlik doğrulama ekle: Tüneli açık bırakırsın ve başkası keşfederse uygulamana istek gönderebilir. ngrok’un basic auth özelliğini kullan:
# Basic auth ile tünel aç
ngrok http 3000 --basic-auth="kullanici:sifre"
# Ya da config dosyasında
# tunnels:
# myapp:
# addr: 3000
# proto: http
# auth: "kullanici:sifre"
IP kısıtlaması: Belirli IP’lerden gelen isteklere izin ver. Örneğin sadece Stripe’ın IP aralıklarından istek bekliyorsun:
# Sadece belirli IP'ye izin ver
ngrok http 3000 --cidr-allow=140.238.1.0/24
Webhook secret doğrulaması: Yukarıdaki GitHub örneğinde gördüğün gibi, webhook imzasını her zaman doğrula. ngrok bir tünel açıyor ama bu gelecek isteklerin meşru olduğunu garanti etmiyor.
Inspection’ı kapat: Bazı durumlarda web arayüzünde görünen veriler hassas olabilir (API key, kullanıcı verisi vs.). Production benzeri verilerle çalışıyorsan inspection’ı kapatabilirsin:
ngrok http 3000 --inspect=false
Docker ile ngrok Kullanımı
Dockerize edilmiş bir uygulamayla çalışıyorsan ngrok’u da container olarak çalıştırabilirsin:
# docker-compose.yml
version: '3.8'
services:
app:
build: .
ports:
- "3000:3000"
networks:
- app-network
ngrok:
image: ngrok/ngrok:latest
command: http app:3000 --log=stdout
ports:
- "4040:4040"
environment:
- NGROK_AUTHTOKEN=${NGROK_AUTHTOKEN}
depends_on:
- app
networks:
- app-network
networks:
app-network:
driver: bridge
# NGROK_AUTHTOKEN'ı ayarla
export NGROK_AUTHTOKEN=your_token_here
# Compose'u başlat
docker compose up -d
# ngrok URL'ini öğren
curl -s http://localhost:4040/api/tunnels | python3 -m json.tool
Ücretsiz Plan Kısıtlamaları
ngrok’un ücretsiz planını kullanıyorsan şunları bilmen gerekiyor:
- Rastgele URL: Her başlatışta farklı bir URL alıyorsun
- Aylık bant genişliği: 1 GB transfer limiti var
- Eşzamanlı bağlantı: Aynı anda 1 tünel açabiliyorsun
- Inspect süresi: İnceleme verisi 8 saatlik geçmişi saklıyor
- Request rate: Dakikada 40 istek sınırı var
Geliştirme aşamasında bu limitler genellikle yeterli oluyor. Ama yoğun webhook testleri yapıyorsan ya da birden fazla tünel gerekiyorsa paid plana geçmeyi düşünebilirsin. Starter plan aylık 10 dolar civarı ve bu noktadaki en büyük avantaj sabit domain ve çoklu tünel.
Alternatifler
ngrok’u sevmiyorsan ya da daha fazla kontrol istiyorsan alternatiflere bakabilirsin:
- localtunnel: Açık kaynak, ücretsiz ama bazen kararsız
- Cloudflare Tunnel: Cloudflare hesabın varsa çok iyi bir seçenek, ücretsiz ve kalıcı URL veriyor
- telebit: Self-hosted seçenek, kendi sunucunda kuruyorsun
- frp: Çin kaynaklı açık kaynak, self-hosted, çok esnek
Özellikle Cloudflare Tunnel’ı öneriyorum. Eğer bir domainin varsa ve Cloudflare kullanıyorsan, cloudflared tunnel komutuyla çok benzer bir çözüm elde edebiliyorsun. Üstelik permanent URL verdiği için webhook URL’ini bir kez tanımlıyorsun ve bir daha değiştirmiyorsun.
Hata Ayıklama İpuçları
ngrok ile çalışırken karşılaşabileceğin yaygın sorunlar:
“ERR_NGROK_108” hatası: Genellikle authtoken problemi. ngrok config check ile token’ın doğru ayarlandığından emin ol.
Tünel aniden kapanıyor: Ücretsiz planda 8 saatlik oturum süresi var. Uzun geliştirme seansları için yeni tünel başlatman gerekiyor.
Webhook gelmiyor gibi görünüyor: Önce http://localhost:4040 arayüzünü kontrol et. İstek geliyor mu? Geliyorsa uygulamanın problemi. Gelmiyorsa webhook URL’ini tekrar kontrol et.
Local uygulama HTTPS bekliyor: ngrok HTTPS tüneli açıyor ama lokal uygulamana HTTP ile yönlendiriyor. Bu normalde sorun olmaz ama --host-header parametresini kullanman gerekebilir:
# Host header'ı yeniden yaz
ngrok http 3000 --host-header=rewrite
# Ya da özel host header belirt
ngrok http 3000 --host-header="localhost:3000"
Sonuç
ngrok, webhook geliştirme sürecindeki en büyük acıyı ortadan kaldırıyor. Her test için sunucuya deploy atmak zorunda kalmıyorsun, üretim ortamına benzer gerçek verilerle lokal ortamda çalışabiliyorsun ve ngrok’un web arayüzü sayesinde her isteğin detayını anında inceleyip replay edebiliyorsun.
Kurulum beş dakika sürüyor, temel kullanım tek bir komutla başlıyor. Stripe’tan ödeme event’i bekliyorsun, GitHub’dan push bildirimi gelecek ya da herhangi bir webhook entegrasyonu geliştiriyorsun; ngrok olmadan bu işleri yapmak gerçekten zahmetli. Bir kez alıştıktan sonra geliştirme iş akışının ayrılmaz bir parçası haline geliyor.
Eğer self-hosted çözüm arıyorsan Cloudflare Tunnel’a da göz at, özellikle kalıcı URL ihtiyacın varsa daha iyi bir seçenek olabilir. Ama hızlıca bir tünel açıp test yapmak istiyorsan ngrok hala en pratik seçenek.
