Uptime Kuma ile Özel Durum Sayfası Oluşturma

Birkaç yıl önce gece 2’de telefon açılışı yaşamıştım. Müşterilerden biri arayıp “siteniz çökmüş, hiçbir şey görünmüyor” diyordu. Biz de zaten biliyorduk, müdahale ediyorduk. Ama müşteri bilmiyordu. O andan itibaren durum sayfasını “isteğe bağlı güzel bir şey” değil, zorunlu bir altyapı bileşeni olarak görmeye başladım.

Uptime Kuma’nın status page özelliği bu iş için gerçekten yeterli. Üstelik kendi sunucunda çalışıyor, dışarıya veri vermiyor ve görsel olarak gayet temiz. Bu yazıda sıfırdan özel bir durum sayfası oluşturmayı, domain bağlamayı, bildirimleri yapılandırmayı ve sayfayı üretim ortamına hazır hale getirmeyi anlatacağım.

Uptime Kuma Kurulumunu Hatırlayalım

Zaten kurulu bir Uptime Kuma örneğiniz varsa bu bölümü atlayabilirsiniz. Yoksa Docker ile hızlıca ayağa kaldıralım.

docker run -d 
  --restart=always 
  -p 3001:3001 
  -v uptime-kuma:/app/data 
  --name uptime-kuma 
  louislam/uptime-kuma:1

Kalıcı veri için volume kullanmak şart. Container yeniden başladığında her şeyin sıfırlanmasını istemezsiniz. Eğer Docker Compose tercih ediyorsanız:

version: '3.8'

services:
  uptime-kuma:
    image: louislam/uptime-kuma:1
    container_name: uptime-kuma
    restart: always
    ports:
      - "3001:3001"
    volumes:
      - ./data:/app/data
    environment:
      - TZ=Europe/Istanbul

TZ=Europe/Istanbul satırını atlamayın. Zaman dilimi yanlış olursa olayların timestamp’leri de yanlış görünür ve inceleme yaparken kafa karışıklığı yaratır.

Container ayağa kalktıktan sonra http://sunucu-ip:3001 adresine gidip admin hesabınızı oluşturun.

İzlenecek Servislerin Eklenmesi

Durum sayfası oluşturmadan önce izleyeceğiniz servislerin sisteme eklenmiş olması gerekiyor. Dashboard’da Add New Monitor butonuna tıklayın.

Tipik bir web uygulaması için şu ayarları kullanıyorum:

Monitor Type: HTTP(s)
URL: https://uygulama.sirket.com
Friendly Name: Ana Uygulama
Heartbeat Interval: 60
Retries: 3
Heartbeat Retry Interval: 20

Retries: 3 ayarı önemli. Tek bir başarısız istekte alarm vermek yerine, 3 ardışık başarısızlıktan sonra “down” durumuna geçiyor. Bu sayede geçici ağ titremelerinden kaynaklanan yanlış alarmlar epey azalıyor.

HTTP monitörün yanı sıra, eğer bir veritabanı TCP portu izliyorsanız:

Monitor Type: TCP Port
Hostname: db.sirket.com
Port: 5432
Friendly Name: PostgreSQL

DNS çözümlemesi izlemek için:

Monitor Type: DNS
Hostname: sirket.com
Resolver Server: 8.8.8.8
Resolve Type: A

Bu DNS monitörünü özellikle CDN veya load balancer arkasındaki sistemler için kullanıyorum. Bazen uygulama ayakta ama DNS kaydı bozuk olabiliyor ve bunu ancak ayrı bir DNS monitörüyle yakalayabiliyorsunuz.

Durum Sayfası Oluşturma

Sol menüden Status Pages seçeneğine gidin. New Status Page butonuna tıklayın.

İlk ekranda sadece bir isim girmeniz yeterli. Ben genellikle şirket adı veya ürün adını kullanıyorum: “Acme Hizmet Durumu” gibi.

Sayfa oluşturulduktan sonra düzenleme ekranına düşüyorsunuz. Bu ekranı bölüm bölüm inceleyelim.

Genel Ayarlar

Title alanına müşterinizin göreceği başlığı yazın. “Sistem Durumu” veya “Hizmet Durumu” sade ama anlaşılır seçenekler.

Description alanı çok kullanılmıyor ama ben buraya bir iletişim adresi veya destek saati bilgisi yazıyorum:

Teknik destek: [email protected] | Pazartesi-Cuma 09:00-18:00
Acil durum: +90 5XX XXX XX XX

Icon kısmına şirket logonuzun URL’ini girebilirsiniz. Logo dosyasını aynı sunucuda bir nginx ile serve ediyorsanız:

# Logo dosyasını nginx'in serve ettiği dizine koyun
cp sirket-logo.png /var/www/html/assets/logo.png

Sonra icon URL olarak https://sirket.com/assets/logo.png yazabilirsiniz.

Monitörlerin Gruplara Eklenmesi

Bu kısım durum sayfasının gerçek değerini ortaya koyuyor. Monitörlerinizi anlamlı gruplara bölebiliyorsunuz.

Düzenleme ekranında Add Group butonuna tıklayın. Ben tipik olarak şu grupları oluşturuyorum:

  • Web Hizmetleri: Müşteriye dönük web uygulamaları
  • API Servisleri: Backend API endpoint’leri
  • Veritabanı: DB bağlantı kontrolleri
  • Altyapı: DNS, CDN, email servisleri

Her grubun altına ilgili monitörleri sürükle-bırak ile ekleyebiliyorsunuz. Müşteriye sadece “web hizmetleri” grubunu göstermek, “veritabanı” grubunu ise sadece dahili ekip için tutmak isteyebilirsiniz. Bunu Public toggle’ı ile kontrol ediyorsunuz.

Monitörü gruba ekledikten sonra yanındaki göz ikonuna tıklayarak o monitörü sayfadan gizleyebilirsiniz. Örneğin internal bir test monitörünü izlemek ama müşteriye göstermemek için kullanışlı.

Özel Alan Adı (Custom Domain) Bağlama

Uptime Kuma durum sayfanıza varsayılan olarak http://sunucu-ip:3001/status/sayfa-slug adresinden erişilir. Bu müşteriye göstermek için pek profesyonel durmuyor. Ben bu iş için genellikle status.sirket.com veya durum.sirket.com gibi bir subdomain kullanıyorum.

Bunun için Uptime Kuma önüne bir reverse proxy koymak gerekiyor. Nginx ile:

server {
    listen 80;
    server_name status.sirket.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name status.sirket.com;

    ssl_certificate /etc/letsencrypt/live/status.sirket.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/status.sirket.com/privkey.pem;

    location / {
        proxy_pass http://localhost:3001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
    }
}

WebSocket header’larını (Upgrade ve Connection) eklemeyi unutmayın. Uptime Kuma real-time güncellemeler için WebSocket kullanıyor ve bu satırlar olmadan canlı güncelleme çalışmıyor.

Let’s Encrypt sertifikası almak için:

certbot --nginx -d status.sirket.com --email [email protected] --agree-tos

Nginx konfigürasyonunu test edip yeniden yükleyin:

nginx -t && systemctl reload nginx

Durum sayfasının ayarlarında Domain alanına status.sirket.com yazın. Artık bu adrese gittiğinizde direkt olarak durum sayfanız açılacak.

Özel CSS ile Görünümü Kişiselleştirme

Uptime Kuma’nın durum sayfası varsayılan haliyle güzel ama kurumsal kimliğe uyarlamak isteyebilirsiniz. Düzenleme ekranında Custom CSS alanı var.

Şirket renklerini ve font’unu özelleştirmek için temel bir CSS:

:root {
  --primary: #1a56db;
  --success: #0e9f6e;
  --warning: #c27803;
  --danger: #e02424;
}

.logo {
  max-height: 60px;
}

body {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
}

.overall-status {
  border-radius: 8px;
}

.card {
  border-radius: 12px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}

Dark mode’u zorla açmak isterseniz:

body {
  background-color: #1a1a2e !important;
  color: #e0e0e0 !important;
}

.card {
  background-color: #16213e !important;
  border: 1px solid #0f3460 !important;
}

CSS’i değiştirdikten sonra sayfayı kaydedin ve birkaç saniye sonra değişikliklerin yansıdığını göreceksiniz. Deneme yanılma için uygundur.

Bakım Penceresi (Maintenance) Ayarlama

Planlı bakım yaparken durum sayfasında bunu önceden bildirmek müşteri deneyimini ciddi ölçüde iyileştiriyor. Uptime Kuma’da Maintenance özelliği tam olarak bunun için var.

Sol menüden Maintenance seçeneğine gidin, New Maintenance butonuna tıklayın.

Title: Planlı Veritabanı Bakımı
Description: PostgreSQL versiyonu güncelleniyor. 
Bu süreçte uygulamaya erişim kısıtlı olabilir.

Timezone: Europe/Istanbul
Start Date/Time: 2024-01-15 02:00
End Date/Time: 2024-01-15 04:00

İlgili monitörleri de bakım penceresine ekleyin. Bu sayede bakım süresince o monitörler “down” olsa bile alarm üretmiyor ve durum sayfasında sarı renkte “bakımda” olarak görünüyor.

Tekrarlayan bakım pencereleri için Cron modunu kullanabilirsiniz:

Cron Expression: 0 2 * * 0

Bu her pazar gece 02:00’de başlayan bir bakım penceresi tanımlar. Haftalık yedekleme işlemi gibi düzenli operasyonlar için kullanışlı.

Bildirim Entegrasyonu

Durum sayfası müşterilere yönelik ama sizin de bir şeyler bozulduğunda haberdar olmanız lazım. Uptime Kuma’nın bildirim sistemi oldukça geniş.

Settings > Notifications altından yeni bildirim kanalları ekleyebilirsiniz.

Telegram bildirimi için:

Notification Type: Telegram
Bot Token: 1234567890:ABCdefGHIjklMNOpqrsTUVwxyz
Chat ID: -1001234567890

Chat ID için gruba bir mesaj atıp https://api.telegram.org/botTOKEN/getUpdates adresine giderek chat_id’yi bulabilirsiniz. Grubun başındaki eksi işaretini (-100…) unutmayın.

Slack için webhook URL’ini aldıktan sonra:

Notification Type: Slack
Webhook URL: https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX
Channel: #ops-alerts
Username: Uptime Kuma

Email bildirimi için SMTP ayarları (örnek olarak Gmail):

Notification Type: Email (SMTP)
SMTP Host: smtp.gmail.com
SMTP Port: 587
SMTP Username: [email protected]
SMTP Password: uygulama-sifresi
To Email: [email protected]

Gmail’de “less secure apps” artık çalışmıyor. Bunun yerine Google hesabında App Password oluşturmanız gerekiyor. Veya daha iyisi, şirket SMTP sunucunuzu kullanın.

Birden fazla bildirim kanalı ekledikten sonra, her monitörün ayarlarında bu kanalları seçebilirsiniz. Ben kritik servisler için hem Telegram hem de email kullanıyorum. Telegram anında geliyor, email ise kayıt tutma amacıyla.

Durum Sayfasını Herkese Açık Yapma vs. Şifre Koruma

Bazı durumlarda durum sayfasını müşterilerinizle paylaşmak yerine sadece ekip içinde kullanmak isteyebilirsiniz. Uptime Kuma’da bunu iki farklı şekilde halledebilirsiniz.

Durum sayfası ayarlarında Password Protection seçeneğini aktive edin:

Enable Password: ✓
Password: guclu-bir-sifre

Bu ayarla sayfaya girmek için şifre gerekiyor. Müşteriye private bir durum sayfası sunmak için kullanışlı.

Eğer sadece dahili kullanım içinse ve VPN arkasında olmasını istiyorsanız, nginx tarafında IP kısıtlaması daha güvenli bir yaklaşım:

location / {
    # Sadece ofis IP'si ve VPN range'i
    allow 192.168.1.0/24;
    allow 10.8.0.0/24;
    deny all;
    
    proxy_pass http://localhost:3001;
    # ... diğer proxy ayarları
}

API ile Otomatik Monitör Yönetimi

Birçok servisi olan büyük altyapılarda tek tek eklemek zaman alıcı olabiliyor. Uptime Kuma’nın REST API’si var ve bunu kullanarak monitörleri otomatize edebilirsiniz.

Önce API key alın: Settings > API Keys > Add API Key

Mevcut monitörleri listelemek için:

curl -s 
  -H "Authorization: Bearer API-KEY-BURAYA" 
  http://localhost:3001/api/v1/monitor 
  | python3 -m json.tool

Yeni monitör eklemek için:

curl -s -X POST 
  -H "Authorization: Bearer API-KEY-BURAYA" 
  -H "Content-Type: application/json" 
  -d '{
    "type": "http",
    "name": "Yeni Servis",
    "url": "https://yeni-servis.sirket.com/health",
    "interval": 60,
    "retryInterval": 20,
    "maxretries": 3
  }' 
  http://localhost:3001/api/v1/monitor

Bu API’yi kullanarak bir shell script yazıp, yeni deployment yapıldığında otomatik olarak monitör ekleyebilirsiniz. CI/CD pipeline’a entegre etmek için de aynı yaklaşım geçerli.

Bir Bash script örneği, birden fazla servisi toplu eklemek için:

#!/bin/bash

API_KEY="your-api-key"
BASE_URL="http://localhost:3001/api/v1"

declare -A SERVICES
SERVICES["Ana Web"]="https://www.sirket.com"
SERVICES["API Gateway"]="https://api.sirket.com/health"
SERVICES["Admin Panel"]="https://admin.sirket.com"
SERVICES["Dokumantasyon"]="https://docs.sirket.com"

for name in "${!SERVICES[@]}"; do
    url="${SERVICES[$name]}"
    echo "Ekleniyor: $name -> $url"
    
    response=$(curl -s -o /dev/null -w "%{http_code}" -X POST 
        -H "Authorization: Bearer $API_KEY" 
        -H "Content-Type: application/json" 
        -d "{
            "type": "http",
            "name": "$name",
            "url": "$url",
            "interval": 60,
            "retryInterval": 20,
            "maxretries": 3,
            "notificationIDList": {}
        }" 
        "$BASE_URL/monitor")
    
    if [ "$response" = "200" ] || [ "$response" = "201" ]; then
        echo "  OK: $name eklendi"
    else
        echo "  HATA: $name eklenemedi (HTTP $response)"
    fi
    
    sleep 1
done

echo "Tamamlandi."

Uptime Kuma’yı Yedekleme

Tüm bu konfigürasyonu kaybetmemek için düzenli yedek almak şart. Veriler /app/data dizininde SQLite olarak saklanıyor.

#!/bin/bash

BACKUP_DIR="/opt/backups/uptime-kuma"
DATE=$(date +%Y%m%d_%H%M%S)

mkdir -p "$BACKUP_DIR"

# Container'ı durdurmadan önce WAL checkpoint al
docker exec uptime-kuma sqlite3 /app/data/kuma.db ".checkpoint FULL"

# Veriyi yedekle
docker cp uptime-kuma:/app/data "$BACKUP_DIR/data_$DATE"

# 30 günden eski yedekleri temizle
find "$BACKUP_DIR" -type d -name "data_*" -mtime +30 -exec rm -rf {} +

echo "Yedek tamamlandi: $BACKUP_DIR/data_$DATE"

Bu scripti crontab’a ekleyin:

# Her gece 03:00'da yedek al
0 3 * * * /opt/scripts/backup-uptime-kuma.sh >> /var/log/uptime-kuma-backup.log 2>&1

Gerçek Dünya Senaryosu: E-Ticaret Altyapısı

Geçen yıl bir e-ticaret projesi için kurduğum yapıyı somut örnek olarak paylaşayım.

Toplam 14 monitör vardı, 5 grupta toplanmıştı:

  • Müşteri Hizmetleri: Ana site, mobil API, arama servisi
  • Ödeme Altyapısı: Ödeme gateway, 3D Secure endpoint
  • İçerik: CDN sağlık kontrolü, görsel servisi
  • Altyapı: Load balancer, SSL sertifika süresi
  • Dahili: Sipariş işleme worker’ları, stok sync servisi

Müşteriye gösterilen sayfada sadece ilk 3 grup vardı. Son 2 grup “Dahili” olarak işaretlendi ve yalnızca ops ekibi görüyordu ama aynı durum sayfasının farklı bir bölümünde. Aslında bunun için ayrı iki status page oluşturduk: biri status.sirket.com adresiyle herkese açık, diğeri ops-status.sirket.com adresiyle VPN arkasında.

Ödeme altyapısı için heartbeat interval’i 30 saniyeye indirdik, diğerleri 60 saniyede kaldı. Retries değerini ise ödeme servisi için 2’ye indirdik: orada sorun varsa hızlı alarm almak istiyoruz.

Black Friday döneminde Grafana dashboard’u ile birlikte kullandık. Uptime Kuma availability takibi yapıyor, Grafana ise latency trendlerini gösteriyordu. İkisi birbirini güzel tamamladı.

Sonuç

Uptime Kuma’nın durum sayfası özelliği, üçüncü parti SaaS araçlara (Statuspage, Better Uptime gibi) kıyasla hem maliyet hem de veri gizliliği açısından ciddi avantaj sunuyor. Ayda belki 50-100 dolar ödenecek ücretin karşılığında bu açık kaynak araç çoğu senaryoyu karşılıyor.

Kurumsal bir ortamda durum sayfasının teknik bir zorunluluk olduğunu, müşteri güvenini yönetmek açısından ise stratejik bir araç olduğunu zamanla öğrendim. Bir kesinti anında müşterinin “ne oluyor?” diye araması ile durum sayfasına bakıp “bakıyorlar, 18:30’da düzelecekmiş” demesi arasındaki fark, hem destek yükü hem de algı açısından büyük.

Reverse proxy kurulumu, özel domain, CSS özelleştirmesi ve API entegrasyonu ile bir araya geldiğinde gerçekten production-ready bir monitoring altyapısı ortaya çıkıyor. Üzerine düzenli yedekleme de eklenince gece 2’de gelen telefon araçları da azalmaya başlıyor. En azından benim için öyle oldu.

Bir yanıt yazın

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