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.
