, , , , , , , , , , , , , , , ,

Raspberry Pi 5 ile Kendi Ev Sunucumu Nasıl Kurdum? Docker, Portainer, Pi-hole, n8n ve Kullandığım Tüm Servisler

Raspberry Pi 5 ile Kendi Ev Sunucumu Nasıl Kurdum? Docker, Portainer, Pi-hole, n8n ve Kullandığım Tüm Servisler

Uzun zamandır yalnızca hazır servisleri kullanan biri olmak yerine, kendi altyapısını kuran, yöneten ve gerektiğinde geliştiren biri olmak istiyordum. Bu düşünceyle başladığım Raspberry Pi projesi, zaman içerisinde basit bir ev sunucusundan çok daha kapsamlı bir sisteme dönüştü.

Bugün Raspberry Pi 5 üzerinde çalışan sistemim; ağ trafiğini filtreleyen, Docker container’larını yöneten, internet servislerini izleyen, otomasyonlar çalıştıran, web sitelerindeki değişiklikleri takip eden, sistem sağlığını ölçen ve kritik durumlarda Telegram üzerinden bana bildirim gönderen bütünleşik bir altyapı hâline geldi.

Bu yazıda kullandığım donanımdan klasör yapısına, Docker ve Portainer kurulumundan geliştirdiğim özel Telegram botuna kadar Raspberry Pi üzerinde gerçekleştirdiğim çalışmaları ayrıntılı şekilde anlatacağım.

Bu proje benim için yalnızca birkaç Docker container’ı çalıştırmak anlamına gelmiyor. Aynı zamanda Linux, ağ yönetimi, güvenlik, otomasyon, DNS, reverse proxy, log yönetimi, sistem izleme ve uygulama geliştirme konularında edindiğim bilgileri gerçek bir sistem üzerinde uyguladığım kişisel bir laboratuvar niteliği taşıyor.

Neden Raspberry Pi 5?

Ev sunucusu kurmak için eski bir bilgisayar, mini PC, NAS cihazı veya bulut sunucu kullanılabilir. Benim Raspberry Pi 5 tercih etmemin temel nedenleri düşük enerji tüketimi, sessiz çalışması, kompakt yapısı ve Linux tabanlı sistemlerle oldukça uyumlu olmasıydı.

Sistemimde şu donanımları kullanıyorum:

  • Raspberry Pi 5
  • 8 GB RAM
  • 120 GB USB SSD
  • Ethernet bağlantısı
  • Raspberry Pi OS
  • Docker ve Docker Compose
  • Portainer yönetim paneli

MicroSD kartlar yoğun yazma işlemleri altında zamanla yıpranabildiği için Docker verilerini ve kalıcı servis dosyalarını USB SSD üzerinde tutmayı tercih ettim. Bu karar, sistemin hem daha hızlı hem de daha güvenilir çalışmasına katkı sağladı.

Özellikle veri tabanı kullanan container’lar, log dosyaları ve sürekli güncellenen yapılandırma dosyaları düşünüldüğünde SSD kullanımı benim için önemli bir gereksinimdi.

Klasör Yapısını Baştan Planlamak

Docker sistemlerinde en sık karşılaşılan sorunlardan biri, container sayısı arttıkça klasörlerin ve volume verilerinin kontrolsüz şekilde dağılmasıdır.

Ben bu nedenle tüm Docker projelerini aşağıdaki ana dizin altında toplamayı tercih ettim:

/srv/docker

Her servis için ayrı bir klasör oluşturdum:

/srv/docker/
├── portainer/
├── homepage/
├── pihole/
├── n8n/
├── netdata/
├── changedetection/
├── cloudflared/
├── code-server/
├── speedtest-tracker/
└── pi-assistant-loruv/

Bu yapı sayesinde hangi servisin hangi dosyaları kullandığını, volume verilerinin nerede tutulduğunu ve bir servisin nasıl yedekleneceğini kolayca görebiliyorum.

Her container için mümkün olduğunca ayrı bir compose.yml veya docker-compose.yml dosyası kullanıyorum. Şifre, API anahtarı ve Telegram bot tokenı gibi hassas bilgileri ise doğrudan Compose dosyasına yazmak yerine .env dosyalarında veya Portainer Environment Variables bölümünde saklıyorum.

Docker ve Docker Compose Kullanımı

Docker, bu sistemin temelini oluşturuyor. Servisleri doğrudan işletim sistemine kurmak yerine container olarak çalıştırmak bana önemli avantajlar sağladı.

Her servis kendi bağımlılıklarıyla izole biçimde çalışıyor. Bir uygulamanın güncellenmesi veya kaldırılması diğer servisleri doğrudan etkilemiyor. Ayrıca Compose dosyaları sayesinde tüm yapılandırmayı kod olarak saklayabiliyorum.

Sık kullandığım temel Docker komutlarından bazıları şunlar:

sudo docker ps
sudo docker ps -a
sudo docker compose up -d
sudo docker compose restart
sudo docker compose down
sudo docker compose logs --tail=100

Çalışan container’ları ve kullandıkları portları görmek için şu komutlardan da yararlanıyorum:

sudo docker ps --format "table {{.Names}}\t{{.Ports}}"

Bu komut, özellikle yeni bir servis kurarken port çakışmalarını önlemek açısından oldukça faydalı oluyor.

Container’ların kullandığı kaynakları canlı olarak görmek için:

sudo docker stats

komutunu kullanıyorum.

Bu sayede CPU, RAM, ağ ve disk kullanımlarını terminal üzerinden anlık olarak takip edebiliyorum.

Portainer ile Merkezi Container Yönetimi

Docker komut satırını kullanabilsem de günlük yönetim için Portainer kurdum.

Portainer sayesinde:

  • Çalışan ve duran container’ları görebiliyorum.
  • Container başlatma, durdurma ve yeniden başlatma işlemlerini yapabiliyorum.
  • Logları web panelinden inceleyebiliyorum.
  • Volume ve network yapılarını yönetebiliyorum.
  • Docker Compose tabanlı stack’ler oluşturabiliyorum.
  • Ortam değişkenlerini panel üzerinden tanımlayabiliyorum.
  • Container kaynak kullanımını kontrol edebiliyorum.

Portainer benim için terminalin yerini tamamen alan bir araç değil. Kritik işlemlerde ve hata ayıklamada hâlâ SSH ve Docker CLI kullanıyorum. Ancak günlük kontrollerde ve hızlı müdahalelerde büyük kolaylık sağlıyor.

Projelerimi mümkün olduğunca stack mantığıyla yönetiyorum. Örneğin GitHub üzerinde tuttuğum bir projenin Compose dosyasını Portainer’a bağlayarak dağıtım yapabiliyorum.

Bu yaklaşım, sistemi yalnızca çalışan bir sunucu olmaktan çıkarıp tekrarlanabilir ve yönetilebilir bir altyapıya dönüştürüyor.

SSD Dostu Log Yönetimi

Raspberry Pi üzerinde SSD kullanıyor olsam da gereksiz log üretiminin diski zamanla doldurmasını veya yoğun yazma işlemlerine neden olmasını istemiyorum.

Bu nedenle Docker Compose dosyalarında log sınırlandırması kullanıyorum:

logging:
  driver: json-file
  options:
    max-size: "10m"
    max-file: "3"

Bu yapılandırmayla her log dosyası en fazla 10 MB oluyor ve en fazla üç eski log dosyası tutuluyor.

Böylece hatalı çalışan bir container’ın sürekli log üreterek diski doldurmasının önüne geçiyorum.

Ayrıca container’larda uygun restart politikaları kullanıyorum:

restart: unless-stopped

Bu ayar sayesinde Raspberry Pi yeniden başladığında servisler otomatik olarak çalışıyor. Ancak benim özellikle durdurduğum bir container kendiliğinden tekrar başlamıyor.

Pi-hole ile Ağ Genelinde Reklam ve Zararlı Alan Adı Engelleme

Raspberry Pi üzerinde kullandığım en önemli servislerden biri Pi-hole oldu.

Pi-hole, ağ seviyesinde DNS filtrelemesi yapıyor. Telefon, bilgisayar, televizyon ve diğer cihazlarda tek tek reklam engelleyici kurmak yerine, ağdaki DNS sorgularını Pi-hole üzerinden geçiriyorum.

Pi-hole sayesinde:

  • Reklam alan adlarını engelleyebiliyorum.
  • Takip ve analiz servislerini sınırlandırabiliyorum.
  • Zararlı alan adı listeleri ekleyebiliyorum.
  • Hangi cihazın hangi alan adına sorgu gönderdiğini görebiliyorum.
  • Yerel DNS kayıtları oluşturabiliyorum.
  • Ağ trafiği hakkında istatistik elde edebiliyorum.

Pi-hole kullanırken yalnızca mümkün olan en fazla listeyi eklemeye çalışmıyorum. Çok fazla ve kontrolsüz liste kullanmak bazı uygulamaların veya web sitelerinin çalışmasını bozabilir.

Bu nedenle listeleri dikkatli seçiyor, hatalı engellenen adresleri whitelist üzerinden kontrol ediyor ve sorgu kayıtlarını düzenli olarak inceliyorum.

Bu süreç bana DNS çalışma mantığı, alan adı çözümleme, filtreleme listeleri ve ağ tabanlı güvenlik konularında önemli bir pratik kazandırdı.

Homepage ile Tüm Servisleri Tek Panelde Toplamak

Container sayısı arttıkça her servisin adresini ve portunu hatırlamak zorlaşabiliyor.

Bu sorunu çözmek için Homepage adlı dashboard uygulamasını kurdum.

Homepage üzerinde kullandığım servisleri kategoriler hâlinde gösteriyorum. Böylece Portainer, Pi-hole, Netdata, n8n, ChangeDetection.io ve diğer panellere tek bir ana ekran üzerinden erişebiliyorum.

Dashboard yalnızca bağlantıların bulunduğu basit bir sayfa değil. Uygun API entegrasyonları kullanıldığında bazı servislerin durumlarını ve istatistiklerini de gösterebiliyor.

Homepage yapılandırmasını kişisel kullanım alışkanlıklarıma göre özelleştirdim:

  • Servisleri kategorilere ayırdım.
  • Arka plan ve görünüm ayarlarını düzenledim.
  • Karanlık ve aydınlık tema kullanımını değerlendirdim.
  • Yerel ağ adreslerini tek panel altında topladım.
  • Gereksiz görsel bileşenleri azaltarak sade bir yapı oluşturdum.

Bu panel sayesinde ev sunucusu daha düzenli ve profesyonel bir yönetim arayüzüne kavuştu.

Netdata ile Sistem Kaynaklarını İzlemek

Bir sunucunun yalnızca çalışıyor olması yeterli değil. CPU, RAM, disk, sıcaklık ve ağ kullanımının da düzenli olarak takip edilmesi gerekiyor.

Bu amaçla Netdata kullanıyorum.

Netdata üzerinden şu bilgileri izleyebiliyorum:

  • CPU kullanımı
  • RAM ve swap kullanımı
  • Disk doluluk oranı
  • Disk okuma ve yazma işlemleri
  • Ağ trafiği
  • Sistem yükü
  • Çalışan süreçler
  • Docker container kaynak tüketimleri
  • Raspberry Pi sıcaklık değerleri

Özellikle yeni bir container kurduktan sonra sistem üzerindeki etkisini Netdata ve docker stats üzerinden kontrol ediyorum.

Bir servis boşta çalışırken bile gereğinden fazla CPU veya RAM tüketiyorsa yapılandırmasını yeniden değerlendiriyorum. Böylece Raspberry Pi’nin uzun süre stabil ve düşük yük altında çalışmasını hedefliyorum.

What’s Up Docker ile Güncelleme Takibi

Docker container’larının yeni sürümlerini takip etmek için What’s Up Docker, kısaca WUD kullanıyorum.

WUD, çalışan image sürümlerini kontrol ederek daha yeni bir sürüm bulunduğunda bana bilgi verebiliyor.

Ben güncellemeleri doğrudan ve kontrolsüz biçimde otomatik yüklemek yerine bildirim almayı tercih ediyorum. Bunun temel nedeni, her yeni sürümün mevcut yapılandırmayla tamamen uyumlu olacağının garanti edilememesi.

Güncelleme bildirimi aldıktan sonra:

  1. Image sürüm notlarını inceliyorum.
  2. Önemli değişiklikleri kontrol ediyorum.
  3. Gerekliyse yedek alıyorum.
  4. Container image’ını güncelliyorum.
  5. Log ve servis kontrollerini gerçekleştiriyorum.

Bu yaklaşım, sistemi güncel tutarken aynı zamanda beklenmedik kesinti riskini azaltıyor.

n8n ile Otomasyon Merkezi Oluşturmak

Raspberry Pi sistemimde en çok geliştirme yaptığım alanlardan biri n8n oldu.

n8n, farklı servisler arasında otomasyon iş akışları oluşturmamı sağlayan düşük kodlu bir platform. Ancak yalnızca hazır node’ları birbirine bağlamakla kalmayıp gerektiğinde JavaScript kodu, HTTP istekleri, API bağlantıları, koşullar ve veri dönüşümleri de kullanabiliyorum.

n8n üzerinde geliştirdiğim veya üzerinde çalıştığım otomasyonlardan bazıları şunlar:

  • RSS kaynaklarından içerik çekmek
  • Aynı içeriğin tekrar paylaşılmasını önlemek
  • Yapay zekâ ile özgün blog yazıları oluşturmak
  • WordPress’e otomatik taslak göndermek
  • Başarılı işlemlerden sonra Telegram bildirimi göndermek
  • Rastgele bekleme süreleri kullanmak
  • Belirli gün ve saatlerde iş akışları çalıştırmak
  • Sistem ve servis durumlarını kontrol etmek
  • API tabanlı veri çekmek
  • Koşullara göre farklı işlemler uygulamak

Örneğin bir RSS kaynağından alınan içeriğin doğrudan yayımlanması yerine önce daha önce işlenip işlenmediğini kontrol ediyorum. İçerik yeniyse yapay zekâ destekli düzenleme aşamasına gönderiliyor, ardından WordPress üzerinde taslak olarak oluşturuluyor.

İşlem tamamlandığında Telegram botu üzerinden yazı başlığını ve işlemin başarılı olduğunu belirten bir bildirim alabiliyorum.

Bu sistemde yalnızca otomasyonun çalışmasına değil, aynı işlemin yanlışlıkla tekrar çalışmamasına, hata durumlarının yönetilmesine ve verilerin kontrolsüz şekilde birikmemesine de dikkat ediyorum.

ChangeDetection.io ile Web Sitelerindeki Değişiklikleri İzlemek

Belirli bir web sayfasında yeni bir duyuru, sınav sonucu, alan adı veya içerik yayımlandığında bunu sürekli manuel olarak kontrol etmek verimli bir yöntem değil.

Bu nedenle ChangeDetection.io kurdum.

Bu servis belirlediğim sayfaları periyodik olarak kontrol ediyor ve içerikte değişiklik tespit ettiğinde bildirim gönderebiliyor.

Kullanım senaryolarım arasında şunlar bulunuyor:

  • Sonuç ve duyuru sayfalarını izlemek
  • Bir listeden yeni eklenen kayıtları tespit etmek
  • Silinen veya eklenen alan adlarını görmek
  • Belirli bir sayfadaki metin değişikliklerini takip etmek
  • Telegram üzerinden değişiklik bildirimi almak

Dinamik ve JavaScript ile oluşturulan sayfalarda klasik HTTP istekleri her zaman yeterli olmayabiliyor. Bu tür sayfalar için tarayıcı tabanlı görüntüleme ve Playwright desteğini değerlendirdim.

Ayrıca sistem kaynaklarını korumak için aynı anda çalıştırılan tarayıcı sayısını, kontrol sıklığını ve geçmişte tutulacak değişiklik sayısını sınırlandırdım.

Bu yaklaşım, ChangeDetection.io’nun faydalı olmasını sağlarken Raspberry Pi üzerinde gereksiz kaynak tüketmesini engelliyor.

Speedtest Tracker ile İnternet Performansını Ölçmek

İnternet bağlantısının anlık olarak hızlı görünmesi, her zaman stabil olduğu anlamına gelmiyor.

Speedtest Tracker ile belirli aralıklarla internet hız testi gerçekleştirerek geçmiş sonuçları kayıt altında tutabiliyorum.

Bu servis sayesinde:

  • İndirme hızını
  • Yükleme hızını
  • Ping değerini
  • Zaman içerisindeki performans değişimini
  • İnternet servis sağlayıcısındaki olası dalgalanmaları

takip edebiliyorum.

Özellikle internet bağlantısında belirli saatlerde yaşanan düşüşleri tespit etmek veya servis sağlayıcıyla iletişim kurarken ölçülebilir veriler sunmak açısından faydalı oluyor.

Cloudflare Tunnel ile Güvenli Uzak Erişim

Yerel ağdaki bir servisi internet üzerinden erişilebilir hâle getirmek için doğrudan modem portu açmak her zaman en güvenli yöntem değil.

Bu nedenle bazı servisler için Cloudflare Tunnel kullanmayı tercih ettim.

Cloudflare Tunnel sayesinde doğrudan public IP adresimi veya modem portlarımı açmadan, belirli servisleri kendi alan adlarım üzerinden yayınlayabiliyorum.

Bu yapı bana şu avantajları sağlıyor:

  • Modemde port yönlendirme ihtiyacının azalması
  • Cloudflare altyapısı üzerinden HTTPS kullanımı
  • Gerçek IP adresinin doğrudan açığa çıkmaması
  • Alt alan adlarıyla düzenli servis adresleri oluşturulması
  • Bazı erişim politikalarının merkezi olarak yönetilebilmesi

Elbette bir servisin HTTPS üzerinden yayınlanması, tek başına tamamen güvenli olduğu anlamına gelmiyor. Uygulama parolaları, erişim politikaları, güncellemeler ve yetkilendirme ayarları ayrıca ele alınmalı.

Bu nedenle yönetim panellerini internete açarken mümkün olduğunca sınırlı erişim, güçlü parola ve ek kimlik doğrulama yöntemleri kullanmaya dikkat ediyorum.

Code-Server ile Tarayıcı Üzerinden Kod Geliştirmek

Kendi PHP, Python, JavaScript ve yapılandırma dosyalarımı sunucu üzerinde düzenleyebilmek için Code-Server kurulumunu da sistemime dahil ettim.

Code-Server, Visual Studio Code benzeri bir geliştirme ortamını tarayıcı üzerinden kullanmayı sağlıyor.

Bunun avantajları şunlar:

  • Proje dosyalarına farklı cihazlardan erişebilmek
  • Kodları doğrudan sunucu ortamında çalıştırabilmek
  • SSH üzerinden sürekli dosya düzenleme ihtiyacını azaltmak
  • Terminal ve editörü aynı panelde kullanabilmek
  • Docker projelerini sunucu üzerinde geliştirebilmek

Ancak Code-Server gibi güçlü bir aracı internete doğrudan ve korumasız şekilde açmamak gerekiyor. Bu nedenle erişim güvenliği, parola, HTTPS ve mümkünse özel ağ kullanımı kritik önem taşıyor.

Samba ile Yerel Ağ Dosya Paylaşımı

Docker servislerinin yanında Raspberry Pi’yi yerel ağ dosya sunucusu olarak da kullanıyorum.

Samba sayesinde Windows ve macOS cihazlardan Raspberry Pi üzerindeki paylaşımlı klasörlere erişebiliyorum.

Paylaşımlı klasörleri SSD üzerinde tutarak bilgisayarlar arasında dosya aktarımı yapabiliyor ve bazı dosyaları merkezi bir alanda saklayabiliyorum.

Bu yapı basit bir NAS sistemi kadar gelişmiş olmasa da kişisel kullanım ve yerel ağ içerisinde dosya paylaşımı için oldukça işlevsel.

Samba yapılandırmasında kullanıcı izinleri, klasör sahipliği ve yazma yetkileri doğru şekilde ayarlanmadığında erişim problemleri yaşanabiliyor. Bu süreç sayesinde Linux dosya izinleri, kullanıcı grupları ve ağ paylaşımı konularında da önemli deneyim kazandım.

Kendi Geliştirdiğim Pi-Assistant-Loruv Projesi

Hazır container’ların yanında sistemi kendi ihtiyaçlarıma göre kontrol edebilmek için Pi-Assistant-Loruv adını verdiğim bir proje geliştirdim.

Bu proje Raspberry Pi ve Docker sistemini Telegram botu üzerinden kontrol etmeyi amaçlıyor.

Projenin gerçekleştirdiği başlıca işlemler şunlar:

  • Raspberry Pi açıldığında Telegram bildirimi gönderme
  • CPU sıcaklığını gösterme
  • RAM kullanımını gösterme
  • Disk kullanımını gösterme
  • İnternet bağlantısını kontrol etme
  • Public IP değişikliklerini bildirme
  • Docker container’larını listeleme
  • Container başlatma ve durdurma
  • Sistem durumunu Telegram üzerinden sorgulama
  • Kritik değerlerde uyarı gönderme
  • Container durduğunda veya yeniden başladığında bildirim verme

Bot üzerinde kullandığım komutlardan bazıları sistem durumu, Docker listesi ve yeniden başlatma gibi işlevler sunuyor.

Proje Docker Compose ile çalışıyor ve yapılandırma bilgilerini .env dosyasından alıyor.

Örnek proje dizini:

/srv/docker/pi-assistant-loruv

Temel yönetim komutları:

cd /srv/docker/pi-assistant-loruv
sudo docker compose restart

Kod değişikliğinden sonra yeniden oluşturmak için:

sudo docker compose up -d --build

Projeyi kapatmak için:

sudo docker compose down

Kalıcı verilerin yanlışlıkla silinmemesi için ne yaptığımı bilmediğim sürece down -v kullanmıyorum. Çünkü -v parametresi bağlı volume verilerini de kaldırabilir.

Projede Docker socket bağlantısı kullanıldığı için güvenlik konusunu özellikle dikkate aldım. Container’a yalnızca gerçekten ihtiyaç duyduğu dosyaları bağlıyor, no-new-privileges gibi güvenlik seçeneklerinden yararlanıyor ve Telegram komutlarını yetkili kullanıcı kimliğiyle sınırlandırıyorum.

Bu proje, hazır bir yazılım kurmanın ötesine geçerek Python, Telegram Bot API, Docker SDK, Linux sistem bilgileri ve hata yönetimi konularını tek bir uygulamada birleştirmemi sağladı.

Telegram’ı Merkezi Bildirim Kanalı Olarak Kullanmak

Sistemde farklı servislerin her biri için ayrı bir bildirim uygulaması kullanmak yerine Telegram’ı merkezi kanal hâline getirdim.

Telegram üzerinden şu bildirimleri alabiliyorum:

  • Container güncelleme uyarıları
  • Web sayfası değişiklikleri
  • n8n otomasyon sonuçları
  • WordPress taslak oluşturma bilgileri
  • Sistem sıcaklık uyarıları
  • İnternet bağlantısı sorunları
  • Container durma veya yeniden başlama olayları
  • Raspberry Pi açılış bildirimi

Telegram Bot API’nin basit HTTP istekleriyle çalışabilmesi, farklı uygulamalara kolayca entegre edilmesini sağlıyor.

Ancak bot tokenlarının loglarda veya herkese açık GitHub depolarında görünmemesi gerekiyor. Bu nedenle tokenları .envdosyalarında tutuyor ve Git tarafından takip edilmesini engelliyorum.

Güvenlik Konusunda Uyguladığım Temel Yaklaşım

Ev sunucusu küçük bir sistem olsa bile güvenlik açısından dikkatsiz davranmak doğru değil.

Benim uyguladığım temel güvenlik yaklaşımı şu prensiplere dayanıyor:

  • Gereksiz portları internete açmamak
  • Yönetim panellerini yalnızca yerel ağ veya güvenli tünel üzerinden kullanmak
  • Güçlü ve benzersiz parolalar belirlemek
  • Hassas bilgileri Compose dosyasına yazmamak
  • .env dosyalarını GitHub’a göndermemek
  • Container image’larını kontrollü şekilde güncellemek
  • Gereksiz yetkiler vermemek
  • Volume bağlantılarını mümkün olduğunca read-only yapmak
  • Logları düzenli kontrol etmek
  • Docker socket erişimini sınırlamak
  • Servisleri varsayılan parolalarla kullanmamak
  • Düzenli yedek almak

Docker socket, bir container’a ana Docker sistemi üzerinde ciddi kontrol imkânı verebildiği için yalnızca gerekli uygulamalarda kullanıyorum.

Aynı şekilde privileged: true seçeneğini de zorunlu olmadığı sürece tercih etmiyorum.

Performans ve Kaynak Kullanımını Dengede Tutmak

Raspberry Pi 5 güçlü bir cihaz olsa da sınırsız kaynağa sahip değil.

Bu nedenle bir servisi kurmadan önce kendime şu soruları soruyorum:

  • Bu servise gerçekten ihtiyacım var mı?
  • Boşta ne kadar RAM tüketiyor?
  • Sürekli CPU kullanıyor mu?
  • Çok fazla log üretiyor mu?
  • Disk üzerinde ne kadar veri biriktiriyor?
  • Aynı işlevi mevcut bir servis sağlayabilir mi?
  • Kontrol aralığını daha uzun tutabilir miyim?

Örneğin web sayfalarını tarayıcı motoruyla kontrol eden servisler, basit HTTP isteklerine göre daha fazla kaynak tüketiyor. Bu nedenle Playwright gibi özellikleri yalnızca gerçekten gerekli sayfalarda kullanıyorum.

Benzer şekilde geçmiş kayıt sayısını, kontrol sıklığını ve eş zamanlı işlem sayısını sınırlandırıyorum.

Amaç mümkün olan en fazla container’ı çalıştırmak değil; ihtiyaç duyduğum servisleri uzun süre kararlı, güvenli ve düşük kaynak tüketimiyle çalıştırmak.

Yedekleme ve Güncelleme Yaklaşımım

Bir Docker container’ını yeniden oluşturmak genellikle kolaydır. Asıl önemli olan container’ın kullandığı kalıcı verilerdir.

Bu nedenle yedekleme yaparken özellikle şu alanlara odaklanıyorum:

  • Compose dosyaları
  • .env dosyaları
  • Uygulama yapılandırmaları
  • Veri tabanları
  • Docker volume verileri
  • n8n workflow’ları
  • Pi-hole ayarları
  • Homepage yapılandırmaları
  • Özel geliştirdiğim proje dosyaları

GitHub üzerinde yalnızca paylaşılması güvenli olan kodları ve örnek yapılandırmaları tutuyorum. Token, parola ve özel anahtar gibi verileri repository içerisine eklemiyorum.

Güncelleme öncesinde özellikle veri tabanı kullanan uygulamalarda yedek almak, sürüm notlarını okumak ve geri dönüş planı oluşturmak gerekiyor.

Bu Proje Bana Neler Kazandırdı?

Raspberry Pi ev sunucusu projesi sayesinde yalnızca Docker kullanmayı öğrenmedim.

Pratik olarak çalıştığım başlıca konular şunlar oldu:

  • Linux sistem yönetimi
  • SSH kullanımı
  • Docker ve Docker Compose
  • Container network yapısı
  • Port ve servis yönetimi
  • Persistent volume kullanımı
  • DNS ve Pi-hole yönetimi
  • Telegram Bot API
  • REST API entegrasyonları
  • Webhook mantığı
  • n8n otomasyonları
  • RSS işleme
  • WordPress API bağlantıları
  • Cloudflare Tunnel
  • HTTPS ve erişim güvenliği
  • Sistem izleme
  • Log analizi
  • Kaynak optimizasyonu
  • Python tabanlı bot geliştirme
  • Git ve GitHub kullanımı
  • Hata ayıklama ve servis sürekliliği

En önemlisi ise çalışan bir sistemi yalnızca kurmakla yetinmeyip neden çalıştığını, hangi durumda bozulabileceğini ve nasıl daha güvenli hâle getirilebileceğini araştırmayı öğrendim.

Gelecekte Sisteme Eklemeyi Planladığım Geliştirmeler

Ev sunucusu projesi tamamlanan ve bir daha dokunulmayan bir çalışma değil. İhtiyaçlar değiştikçe sistem de gelişmeye devam ediyor.

İlerleyen dönemde üzerinde çalışmak istediğim konular arasında şunlar bulunuyor:

  • Daha kapsamlı otomatik yedekleme sistemi
  • Merkezi log toplama
  • Container sağlık kontrollerinin geliştirilmesi
  • Telegram bot komutlarının genişletilmesi
  • Yetkilendirme yapısının güçlendirilmesi
  • Otomatik ancak kontrollü kurtarma senaryoları
  • Daha ayrıntılı internet kesintisi analizi
  • Servisler için özel durum sayfası
  • Docker Compose dosyalarının standartlaştırılması
  • Kritik servisler için yedek Raspberry Pi veya sunucu planı
  • Kişisel projeler için otomatik dağıtım sistemi

Sonuç

Raspberry Pi 5 ile başladığım bu çalışma, zaman içerisinde kişisel bir ev sunucusu, otomasyon merkezi, ağ güvenliği aracı ve geliştirme ortamına dönüştü.

Docker ve Portainer sayesinde servisleri düzenli biçimde yönetiyor, Pi-hole ile ağ trafiğini filtreliyor, Netdata ile sistem kaynaklarını izliyor, Homepage ile tüm servisleri tek ekranda topluyor, n8n ile otomasyonlar geliştiriyor ve ChangeDetection.io ile web sayfalarındaki değişiklikleri takip ediyorum.

Cloudflare Tunnel uzak erişim altyapısını sağlarken, Telegram botları sistemin bildirim ve kontrol katmanını oluşturuyor. Kendi geliştirdiğim Pi-Assistant-Loruv projesi ise Raspberry Pi ve Docker sistemini doğrudan Telegram üzerinden yönetebilmemi sağlıyor.

Bu projenin benim için en değerli tarafı, teorik bilgileri gerçek bir sistem üzerinde uygulama fırsatı sunması oldu. Her yeni servis, karşılaştığım her hata ve geliştirdiğim her çözüm; Linux, Docker, ağ yönetimi, otomasyon ve yazılım geliştirme konularındaki tecrübemi daha ileri taşıdı.

Bugün sistemim yalnızca evde çalışan küçük bir Raspberry Pi değil. Kendi ihtiyaçlarıma göre geliştirdiğim, izlediğim, güvenliğini sağladığım ve sürekli iyileştirdiğim kişisel bir teknoloji laboratuvarı.




How I Built My Own Home Server with a Raspberry Pi 5: Docker, Portainer, Pi-hole, n8n and More

For a long time, I wanted to move beyond simply using ready-made online services. I wanted to build, manage and improve my own infrastructure.

What started as a small Raspberry Pi project gradually became a complete home server environment. My current system can manage Docker containers, filter network traffic, monitor system resources, run automation workflows, detect changes on websites and send important notifications through Telegram.

In this article, I will explain how I built my Raspberry Pi 5 home server, which services I use, how I organize my Docker environment and what I learned throughout the process.

For me, this project is not simply about running as many containers as possible. It is a practical technology laboratory where I apply my knowledge of Linux, Docker, networking, DNS, system monitoring, security, automation, APIs and software development.

Why I Chose the Raspberry Pi 5

A home server can be built with an old computer, a mini PC, a NAS device or a cloud server. I selected the Raspberry Pi 5 because of its low power consumption, silent operation, compact size and excellent compatibility with Linux-based systems.

My current setup includes:

  • Raspberry Pi 5
  • 8 GB RAM
  • 120 GB USB SSD
  • Ethernet connectivity
  • Raspberry Pi OS
  • Docker and Docker Compose
  • Portainer

Instead of relying on a microSD card for container data, I use an external USB SSD. Docker services can generate frequent write operations through databases, configuration files and logs. An SSD therefore provides better performance and reliability for long-term use.

Planning the Directory Structure

One of the most common problems in a growing Docker environment is an unorganized directory structure.

To prevent this, I store my Docker projects under a single main directory:

/srv/docker

Each service has its own directory:

/srv/docker/
├── portainer/
├── homepage/
├── pihole/
├── n8n/
├── netdata/
├── changedetection/
├── cloudflared/
├── code-server/
├── speedtest-tracker/
└── pi-assistant-loruv/

This structure makes it easier to understand which files belong to each service, where persistent data is stored and what needs to be backed up.

I normally use a separate compose.yml or docker-compose.yml file for each service. Sensitive information such as passwords, API keys and Telegram bot tokens is stored in .env files or Portainer environment variables rather than being written directly into Compose files.

Docker and Docker Compose

Docker is the foundation of the entire system.

Instead of installing every application directly on the operating system, I run services in isolated containers. Each service has its own dependencies and can be updated, restarted or removed without directly affecting the others.

Docker Compose also allows me to define infrastructure as configuration.

Some of the commands I frequently use are:

sudo docker ps
sudo docker ps -a
sudo docker compose up -d
sudo docker compose restart
sudo docker compose down
sudo docker compose logs --tail=100

To list container names and exposed ports:

sudo docker ps --format "table {{.Names}}\t{{.Ports}}"

This is particularly useful before deploying a new service because it helps prevent port conflicts.

To monitor live resource usage:

sudo docker stats

This command displays CPU, memory, network and disk activity for active containers.

Managing Containers with Portainer

Although I am comfortable using Docker through SSH and the command line, I installed Portainer for daily container management.

Portainer allows me to:

  • View running and stopped containers
  • Start, stop and restart services
  • Inspect container logs
  • Manage networks and volumes
  • Create Docker Compose stacks
  • Configure environment variables
  • Review container status and resource usage

Portainer does not completely replace the command line. I still prefer SSH and Docker CLI for troubleshooting and advanced operations.

However, Portainer provides a fast and convenient interface for routine checks and immediate interventions.

I also use stack-based deployments whenever possible. A project stored on GitHub can be connected to Portainer and deployed through its Compose configuration.

This makes the environment more reproducible and easier to maintain.

SSD-Friendly Log Management

Even though my system uses an SSD, I do not want unlimited logs to consume storage or create unnecessary write operations.

For that reason, I configure Docker log rotation:

logging:
  driver: json-file
  options:
    max-size: "10m"
    max-file: "3"

With this configuration, each log file is limited to 10 MB and only three files are retained.

This prevents a misconfigured or failing container from filling the entire disk with repetitive log messages.

I also use suitable restart policies:

restart: unless-stopped

This allows services to start automatically after the Raspberry Pi reboots, while keeping manually stopped containers inactive.

Network-Wide Filtering with Pi-hole

Pi-hole is one of the most useful services in my home server environment.

It provides DNS-level filtering for devices on my local network. Instead of installing a separate blocker on every computer, phone or smart device, I route DNS requests through Pi-hole.

With Pi-hole, I can:

  • Block advertising domains
  • Reduce tracking requests
  • Add malicious domain lists
  • Review DNS queries
  • Identify which device requested a domain
  • Create local DNS records
  • Analyze network-level statistics

My goal is not to add the largest possible number of blocklists. Uncontrolled lists can break websites, mobile applications and legitimate services.

I therefore select lists carefully, review blocked queries and use the whitelist when necessary.

Managing Pi-hole has also improved my practical understanding of DNS resolution, domain filtering and network security.

Creating a Central Dashboard with Homepage

As the number of containers increased, remembering every local address and port became inconvenient.

I solved this problem by installing Homepage.

Homepage provides a single dashboard for my services. From one screen, I can access Portainer, Pi-hole, Netdata, n8n, ChangeDetection.io and other internal applications.

I customized the dashboard according to my own workflow:

  • Grouped services by category
  • Adjusted the background and visual layout
  • Evaluated light and dark themes
  • Added local service addresses
  • Removed unnecessary visual components
  • Created a clean and simple interface

Where supported, Homepage can also connect to service APIs and display useful status information.

This dashboard transformed a collection of separate applications into a more organized and professional home server interface.

Monitoring System Resources with Netdata

A server should not only remain online. Its CPU, memory, storage, temperature and network usage should also be monitored.

I use Netdata for detailed system monitoring.

It allows me to review:

  • CPU usage
  • RAM and swap usage
  • Disk capacity
  • Disk read and write operations
  • Network traffic
  • System load
  • Running processes
  • Docker container resource consumption
  • Raspberry Pi temperature

Whenever I install a new container, I monitor its effect through Netdata and docker stats.

If a service consumes excessive CPU or memory while idle, I review its configuration, polling interval and resource requirements.

My objective is to keep the Raspberry Pi stable and efficient over long periods of operation.

Tracking Container Updates with What’s Up Docker

I use What’s Up Docker, also known as WUD, to check for newer container image versions.

WUD compares deployed images with available releases and can send notifications when an update is detected.

I do not automatically install every new release without review. A new image may introduce breaking changes or require configuration updates.

My update process normally includes:

  1. Reviewing release notes
  2. Checking important configuration changes
  3. Creating a backup when required
  4. Pulling the new image
  5. Recreating the container
  6. Checking logs and service functionality

This approach allows me to keep the system updated while reducing the risk of unexpected downtime.

Building an Automation Center with n8n

n8n is one of the most powerful components of my Raspberry Pi environment.

It is a low-code workflow automation platform that can connect APIs, web services, databases and messaging platforms. When built-in nodes are not enough, I can also use JavaScript, HTTP requests, conditions and custom data transformations.

Some of the workflows I have created or developed include:

  • Reading content from RSS feeds
  • Preventing duplicate content processing
  • Generating original blog drafts with artificial intelligence
  • Sending drafts to WordPress
  • Delivering Telegram notifications after successful operations
  • Adding randomized delays
  • Running workflows on selected days and times
  • Checking system and service status
  • Retrieving data through APIs
  • Applying conditional logic

For example, an RSS item is not immediately published. The workflow first checks whether the content has already been processed.

If the item is new, it can be sent to an AI-powered content stage, converted into an original article and created as a draft in WordPress.

After a successful operation, the workflow sends a Telegram message containing the article title and publication status.

I also pay attention to data retention, error handling and duplicate prevention. Automation is useful only when it operates reliably and does not repeatedly process the same input.

Monitoring Website Changes with ChangeDetection.io

Manually checking a webpage for announcements, exam results, new records or updated content is inefficient.

I use ChangeDetection.io to monitor selected pages at regular intervals.

The service can detect content changes and send notifications when something new appears.

My use cases include:

  • Monitoring announcement and result pages
  • Detecting newly added items in a list
  • Tracking removed or added domain names
  • Watching specific text sections
  • Sending changes through Telegram

Some websites generate their content dynamically with JavaScript. A basic HTTP request may not capture those pages correctly.

For these cases, I evaluated browser-based checks and Playwright support.

Because browser automation consumes more resources, I limit concurrent browser sessions, check intervals and stored history. I use heavier browser-based monitoring only when a simple request is not sufficient.

Measuring Internet Performance with Speedtest Tracker

A connection may appear fast during a manual test but still experience regular drops or instability.

Speedtest Tracker allows me to run scheduled connection tests and retain historical results.

I can monitor:

  • Download speed
  • Upload speed
  • Ping
  • Performance changes over time
  • Possible service provider fluctuations

Historical data is particularly useful for identifying patterns at specific times of day or providing measurable information when contacting the internet service provider.

Secure Remote Access with Cloudflare Tunnel

Exposing a local service to the internet by opening router ports is not always the safest option.

For selected services, I use Cloudflare Tunnel.

Cloudflare Tunnel allows me to publish an internal service through my own domain without directly exposing my public IP address or opening inbound router ports.

This provides several advantages:

  • Reduced need for port forwarding
  • HTTPS through Cloudflare infrastructure
  • Protection of the origin IP address
  • Clean service addresses through subdomains
  • Centralized access policy options

HTTPS alone does not make an application completely secure. Strong authentication, restricted access, software updates and proper authorization are still required.

I therefore avoid exposing administrative panels unnecessarily and prefer local network, tunnel-based or private network access.

Browser-Based Development with Code-Server

I also added Code-Server to my environment so I can edit and run PHP, Python, JavaScript and configuration files directly on the server.

Code-Server provides a Visual Studio Code-like development environment through a web browser.

Its benefits include:

  • Accessing projects from different devices
  • Running code directly in the server environment
  • Reducing the need to edit every file through SSH
  • Using an integrated terminal and editor
  • Developing Docker projects where they are deployed

Because Code-Server provides powerful access to the system, it should never be exposed publicly without proper protection.

Authentication, HTTPS and restricted network access are essential.

Local File Sharing with Samba

In addition to Docker services, I use the Raspberry Pi as a local network file server.

Samba allows Windows and macOS devices to access shared folders stored on the Raspberry Pi.

By keeping these directories on the SSD, I can transfer files between computers and maintain a central storage area for selected data.

Although this is not a complete enterprise NAS solution, it is practical for personal file sharing inside the local network.

Configuring Samba also gave me practical experience with Linux permissions, ownership, user groups and network shares.

Developing My Own Pi-Assistant-Loruv Project

In addition to installing existing applications, I developed a custom project called Pi-Assistant-Loruv.

The purpose of this project is to monitor and control my Raspberry Pi and Docker environment through a Telegram bot.

Its main functions include:

  • Sending a Telegram message when the Raspberry Pi starts
  • Reporting CPU temperature
  • Reporting RAM usage
  • Reporting disk usage
  • Checking internet connectivity
  • Detecting public IP address changes
  • Listing Docker containers
  • Starting and stopping containers
  • Providing system status through Telegram commands
  • Sending warnings for critical values
  • Reporting container stops and restarts

The project runs through Docker Compose and reads its configuration from a .env file.

The project directory is:

/srv/docker/pi-assistant-loruv

To restart it:

cd /srv/docker/pi-assistant-loruv
sudo docker compose restart

After changing the source code:

sudo docker compose up -d --build

To stop the project:

sudo docker compose down

I avoid using down -v unless I intentionally want to delete associated volume data. The -v option can remove persistent information.

Because the project interacts with the Docker socket, security is especially important. I mount only the required paths, use options such as no-new-privileges and restrict Telegram commands to authorized user IDs.

This project allowed me to combine Python, the Telegram Bot API, Docker management, Linux system information and error handling in a single application.

Using Telegram as the Central Notification Channel

Instead of using a separate notification application for every service, I use Telegram as the central notification channel.

Telegram can deliver:

  • Container update alerts
  • Website change notifications
  • n8n workflow results
  • WordPress draft notifications
  • Temperature warnings
  • Internet connectivity alerts
  • Container stop and restart events
  • Raspberry Pi startup messages

The Telegram Bot API is simple to integrate because it can be used through standard HTTP requests.

However, bot tokens must never appear in public logs or GitHub repositories. I keep tokens in environment files and exclude them from version control.

My Security Approach

A home server may be small, but it still requires a serious security approach.

My basic security principles include:

  • Avoid exposing unnecessary ports
  • Keep management panels on the local network or behind secure access
  • Use strong and unique passwords
  • Store sensitive values outside Compose files
  • Exclude .env files from Git repositories
  • Update container images carefully
  • Avoid unnecessary privileges
  • Mount volumes as read-only where possible
  • Review logs regularly
  • Limit Docker socket access
  • Replace default passwords
  • Maintain backups

Access to the Docker socket can provide extensive control over the host environment. I therefore enable it only for applications that genuinely require it.

I also avoid using privileged: true unless there is no safer alternative.

Balancing Performance and Resource Usage

The Raspberry Pi 5 is a capable device, but its resources are not unlimited.

Before deploying a new service, I consider several questions:

  • Do I really need this application?
  • How much memory does it consume while idle?
  • Does it continuously use CPU?
  • Does it generate excessive logs?
  • How much data will it store?
  • Can an existing service already perform the same task?
  • Can I increase its polling interval?

Browser-based website monitoring, for example, consumes significantly more resources than simple HTTP requests.

I therefore use Playwright-style browser checks only for websites that actually require them.

I also limit history retention, monitoring frequency and concurrent operations.

The objective is not to run the highest possible number of containers. The objective is to operate the services I need in a stable, secure and efficient way.

Backup and Update Strategy

Recreating a Docker container is usually easy. Persistent application data is the valuable part.

My backup strategy focuses on:

  • Compose files
  • .env files
  • Application configurations
  • Databases
  • Docker volume data
  • n8n workflows
  • Pi-hole settings
  • Homepage configuration
  • Custom project source code

I store only safe code and example configurations on GitHub. Passwords, tokens and private keys are never committed to public repositories.

Before updating applications that use databases or complex configurations, I create backups, review release notes and consider a rollback plan.

What I Learned from This Project

The Raspberry Pi home server project taught me much more than how to start a Docker container.

The main areas in which I gained practical experience include:

  • Linux system administration
  • SSH
  • Docker and Docker Compose
  • Container networking
  • Port and service management
  • Persistent volumes
  • DNS and Pi-hole
  • Telegram Bot API
  • REST API integrations
  • Webhooks
  • n8n automation
  • RSS processing
  • WordPress API integrations
  • Cloudflare Tunnel
  • HTTPS and access security
  • System monitoring
  • Log analysis
  • Resource optimization
  • Python bot development
  • Git and GitHub
  • Troubleshooting and service continuity

Most importantly, I learned not to stop after making a service work.

I try to understand why it works, what could cause it to fail, how it can be monitored and how it can be secured.

Future Improvements

A home server is not a project that is completed once and never changed again. It continues to evolve as requirements change.

Some of the improvements I plan to explore include:

  • A more comprehensive automated backup system
  • Centralized log collection
  • Improved container health checks
  • Additional Telegram bot commands
  • Stronger authorization controls
  • Controlled automatic recovery scenarios
  • More detailed internet outage analysis
  • A dedicated internal status page
  • Standardized Compose templates
  • A backup Raspberry Pi or secondary server plan
  • Automated deployment for personal projects

Conclusion

What began as a Raspberry Pi 5 experiment gradually became a personal home server, automation center, network filtering system and development environment.

Docker and Portainer allow me to manage services in an organized way. Pi-hole filters network traffic, Netdata monitors system resources, Homepage provides a central dashboard, n8n runs automation workflows and ChangeDetection.io watches web pages for updates.

Cloudflare Tunnel provides secure remote connectivity, while Telegram acts as the notification and control layer. My custom Pi-Assistant-Loruv project allows me to monitor and manage the Raspberry Pi and Docker containers directly through Telegram.

The most valuable part of this project has been the opportunity to apply technical knowledge to a real and continuously operating system.

Every service I deployed, every error I investigated and every solution I developed improved my experience in Linux, Docker, networking, automation and software development.

Today, the device running in my home is not simply a small Raspberry Pi. It is a personal technology laboratory that I designed, secured, monitored and continue to improve.

Bir yanıt yazın

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



    Şimdi Ara +90 551 000 17 59