Modern bir Linux sunucusunda arka planda çalışan hemen her şey (web sunucusu, veritabanı, SSH, zamanlanmış görevler) systemd tarafından yönetilir. Nginx'i yeniden başlattığınızda, sunucu açılışında MySQL'in otomatik ayağa kalkmasını sağladığınızda ya da bir servisin neden çöktüğünü loglardan araştırdığınızda aslında systemd ile konuşuyorsunuz. Bu yüzden bir sistem yöneticisinin systemd ve onun kontrol aracı systemctl ile rahatça çalışabilmesi şarttır.
Bu rehberde systemd'nin ne olduğunu, günlük hayatta en çok kullanacağınız systemctl komutlarını, journalctl ile log okumayı ve en önemlisi kendi uygulamanızı bir servise dönüştüren unit dosyasını nasıl yazacağınızı uygulamalı örneklerle ele alıyoruz. Temel komut bilginiz eksikse önce Linux temel komutları yazımıza göz atmanızı öneririz.
systemd Nedir ve Init Sisteminin Rolü#
Linux çekirdeği önyükleme sırasında ilk kullanıcı-alanı sürecini başlatır ve bu sürecin PID (Process ID) değeri her zaman 1'dir. İşte bu 1 numaralı süreç "init sistemi"dir; diğer tüm süreçlerin atasıdır. Görevi, sistem açılışında gerekli servisleri doğru sırayla ayağa kaldırmak, çalışırken onları izlemek ve kapanışta düzgünce durdurmaktır.
systemd, günümüzde Ubuntu, Debian, Rocky Linux, AlmaLinux ve CentOS gibi büyük dağıtımların tamamında standart olan init sistemidir. Eski SysV init'ten farkı, servisleri paralel başlatabilmesi, bağımlılıkları otomatik çözmesi, servis çöktüğünde otomatik yeniden başlatabilmesi ve merkezi bir log altyapısına (journald) sahip olmasıdır.
systemd'nin temel yapı taşı "unit"tir. Her yönetilebilir kaynak bir unit'tir ve tipine göre farklı uzantı alır:
| Unit tipi | Uzantı | Ne işe yarar |
|---|---|---|
| Service | .service | Arka plan servisleri (nginx, mysql, kendi uygulamanız) |
| Socket | .socket | Ağ/soket dinleme, servisi talep gelince başlatma |
| Timer | .timer | cron benzeri zamanlanmış görevler |
| Mount | .mount | Dosya sistemi bağlama noktaları |
| Target | .target | Birden fazla unit'i gruplayan hedefler (ör. çok kullanıcılı mod) |
Bu rehberin ağırlığı en çok karşılaşacağınız .service unit'lerinde olacak.
Temel systemctl Komutları#
systemctl, systemd'yi yönetmek için kullandığınız ana komuttur. Bir servisin çalışıp çalışmadığını kontrol etmekten onu kalıcı olarak etkinleştirmeye kadar her şeyi buradan yaparsınız. Aşağıda en sık kullanılan komutları örneklerle görüyoruz:
# Bir servisi başlat
sudo systemctl start nginx
# Bir servisi durdur
sudo systemctl stop nginx
# Yeniden başlat (durdur + başlat)
sudo systemctl restart nginx
# Yapılandırmayı kesinti olmadan yeniden yükle (mümkünse)
sudo systemctl reload nginx
# Servisin anlık durumunu gör
sudo systemctl status nginx
restart ile reload arasındaki fark önemlidir. restart süreci tamamen kapatıp yeniden açar; kısa bir kesinti oluşur ve mevcut bağlantılar düşer. reload ise servise yapılandırma dosyasını yeniden okumasını söyler ama süreci öldürmez; nginx gibi bunu destekleyen servislerde canlı trafiği kesmeden ayar değişikliği uygulamak için idealdir.
Bir servisin sistem açılışında otomatik başlamasını istiyorsanız enable, istemiyorsanız disable kullanırsınız. Bu, servisin o an çalışıp çalışmadığından bağımsız bir ayardır:
# Açılışta otomatik başlat
sudo systemctl enable nginx
# Hem şimdi başlat hem açılışa ekle (tek komutta)
sudo systemctl enable --now nginx
# Açılıştan çıkar
sudo systemctl disable nginx
# Bir servisin açılışta etkin olup olmadığını sor
systemctl is-enabled nginx
Sistemdeki servislere toplu bakmak isterseniz şu komutlar işinizi görür:
# Yüklü ve çalışan tüm servisleri listele
systemctl list-units --type=service
# Sadece başarısız (failed) durumdaki unit'leri göster
systemctl --failed
Bir Servisin Durumunu Okuma#
systemctl status çıktısı ilk bakışta yoğun görünür ama her satırı bir şey anlatır. Örnek bir çıktıyı inceleyelim:
$ sudo systemctl status nginx
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; preset: enabled)
Active: active (running) since Thu 2026-07-09 08:14:22 UTC; 3h 21min ago
Main PID: 812 (nginx)
Tasks: 3 (limit: 4915)
Memory: 12.4M
CPU: 240ms
CGroup: /system.slice/nginx.service
├─812 nginx: master process /usr/sbin/nginx
└─813 nginx: worker process
Bakmanız gereken en kritik satır Active: satırıdır. Burada birkaç farklı durum görebilirsiniz:
- active (running): Servis çalışıyor ve sürekli bir süreç barındırıyor (web sunucusu gibi).
- active (exited): Görevini yaptı ve düzgünce sonlandı (tek seferlik başlangıç betikleri gibi). Bu bir hata değildir.
- inactive (dead): Servis çalışmıyor; durdurulmuş.
- failed: Servis başlamayı denedi ama çöktü. Bu satır kırmızıysa hemen loglara bakmanız gerekir.
Loaded: satırındaki enabled/disabled bilgisi açılışta otomatik başlayıp başlamadığını söyler. Main PID süreç kimliğidir. Çıktının en altındaki birkaç satır ise o servise ait en güncel log kayıtlarıdır; hızlı bir teşhis için genelde yeterlidir.
journalctl ile Log İnceleme#
systemd, tüm servislerin çıktılarını merkezi bir günlük olan journald'da toplar. Bu logları okumak için journalctl kullanırsınız. Bir servis çöktüğünde ilk başvuracağınız araç budur.
# Belirli bir servisin loglarını göster (-u = unit)
journalctl -u nginx
# Logları canlı takip et (tail -f gibi) — hata ayıklarken vazgeçilmez
journalctl -u nginx -f
# Sadece son 100 satırı göster
journalctl -u nginx -n 100
# En yeni kayıtlar en üstte olacak şekilde ters sırala
journalctl -u nginx -r
Zaman bazlı filtreleme, bir olayın ne zaman olduğunu bildiğinizde çok değerlidir:
# Son 1 saatteki kayıtlar
journalctl -u nginx --since "1 hour ago"
# Belirli bir tarih aralığı
journalctl -u nginx --since "2026-07-09 08:00" --until "2026-07-09 09:00"
# Sadece hata seviyesi ve üstü (öncelik filtresi)
journalctl -u nginx -p err
# Bu açılıştan bu yana (donanım/boot sorunları için)
journalctl -b
journald varsayılan olarak logları diskte tutmayabilir; kalıcı log istiyorsanız /etc/systemd/journald.conf içinde Storage=persistent ayarlayıp sudo systemctl restart systemd-journald çalıştırın. Diskin taşmaması için journalctl --vacuum-size=500M gibi bir komutla eski logları sınırlayabilirsiniz. Zamanlanmış görevlerinizi cron yerine systemd ile yönetiyorsanız log takibi de bu tek merkezden yapılır; klasik cron kullanıyorsanız cron görevleri rehberimiz ile karşılaştırmanızı öneririz.
Kendi Unit (.service) Dosyanızı Yazma#
systemd'nin en güçlü yanı, kendi uygulamanızı sadece birkaç satırla düzgün yönetilen bir servise dönüştürebilmenizdir. Diyelim ki /opt/uygulama altında server.js adında bir Node.js uygulamanız var ve bunun sunucu açılışında otomatik başlamasını, çökerse yeniden ayağa kalkmasını istiyorsunuz.
Önce /etc/systemd/system/ altına bir unit dosyası oluşturun:
sudo nano /etc/systemd/system/uygulama.service
İçeriği şöyle olabilir:
[Unit]
Description=Cloutr Ornek Node Uygulamasi
After=network.target
[Service]
Type=simple
User=www-data
WorkingDirectory=/opt/uygulama
ExecStart=/usr/bin/node /opt/uygulama/server.js
Restart=on-failure
RestartSec=5
Environment=NODE_ENV=production
[Install]
WantedBy=multi-user.target
Her bölümün anlamına bakalım:
- [Unit] → After=network.target: Servisin ağ hazır olduktan sonra başlamasını sağlar. Veritabanına bağlanan uygulamalar için
After=mysql.servicegibi bağımlılıklar da eklenebilir. - [Service] → Type=simple: systemd, ExecStart komutunu başlatır ve o sürecin ana süreç olduğunu varsayar. En yaygın tiptir. Uygulama kendini arka plana atıp (fork edip) çıkıyorsa
Type=forkingkullanılır. - User=www-data: Servisi root yerine yetkisiz bir kullanıcıyla çalıştırmak güvenlik açısından önemlidir; olası bir açık tüm sistemi değil sadece o kullanıcıyı etkiler.
- Restart=on-failure ve RestartSec=5: Uygulama hatayla çökerse systemd onu 5 saniye sonra otomatik yeniden başlatır. Bu, tek başına küçük bir "watchdog" gibi çalışır.
- [Install] → WantedBy=multi-user.target:
enableettiğinizde servisin normal çok kullanıcılı sunucu modunda açılışa bağlanmasını belirtir.
Dosyayı yazdıktan sonra systemd'ye yeni unit'i tanıtmanız gerekir:
# Unit dosyalarını yeniden oku
sudo systemctl daemon-reload
# Servisi başlat ve açılışa ekle
sudo systemctl enable --now uygulama
# Çalıştığını doğrula
sudo systemctl status uygulama
Artık journalctl -u uygulama -f ile uygulamanızın çıktısını canlı izleyebilir, sudo systemctl restart uygulama ile yeni sürümü devreye alabilirsiniz. Unit dosyasında bir değişiklik yaptığınızda her zaman daemon-reload çalıştırmayı unutmayın; aksi halde systemd eski tanımı kullanmaya devam eder.
Servis Bağımlılıkları ve Başlangıç Sırası#
Gerçek sunucularda servisler birbirinden bağımsız değildir; bir web uygulaması veritabanına, veritabanı da ağa ihtiyaç duyar. systemd bu ilişkileri unit dosyasındaki [Unit] bölümünde tanımlamanıza izin verir. En sık kullanılan dört yönergeyi bilmek, çoğu başlangıç sırası sorununu çözmenize yeter:
- After= ve Before=: Yalnızca sıralama belirler, bağımlılık kurmaz.
After=mysql.service, servisinizin MySQL başladıktan sonra başlatılmasını sağlar; ama MySQL çökerse sizinki yine de başlar. - Requires=: Güçlü bağımlılık.
Requires=mysql.serviceyazarsanız, MySQL başlatılamazsa servisiniz de başlatılmaz. GenellikleAfter=ile birlikte kullanılır. - Wants=: Yumuşak bağımlılık. Belirtilen servisi başlatmaya çalışır ama o başlamasa bile sizinki çalışmaya devam eder. Çoğu senaryoda
Requires'tan daha güvenlidir.
Örneğin bir uygulama hem ağa hem de veritabanına ihtiyaç duyuyorsa unit dosyasının başı şöyle olabilir:
[Unit]
Description=Veritabanina bagimli uygulama
After=network.target mysql.service
Wants=mysql.service
Bu yapı, "önce ağ ve veritabanı gelsin, sonra ben başlayayım; ama veritabanı sorunluysa yine de denemekten vazgeçme" der. Bağımlılıkları doğru kurmak, sunucu yeniden başladığında servislerin yanlış sırada ayağa kalkıp birbirini bekleyerek zaman aşımına uğramasını önler. Bir servisin hangi diğer unit'lere bağlı olduğunu systemctl list-dependencies servis komutuyla ağaç halinde görebilirsiniz.
systemd Timer ile cron Alternatifi#
systemd, zamanlanmış görevler için de cron'a modern bir alternatif sunar: timer unit'leri. Bir timer, kendisiyle aynı adı taşıyan bir servisi belirli aralıklarla tetikler. Avantajı; loglarının journalctl'de olması, kaçırılan görevleri telafi edebilmesi (Persistent=true) ve bağımlılık yönetiminin daha güçlü olmasıdır.
Örneğin her gün gece yarısı bir yedekleme betiği çalıştırmak isteyelim. Önce görevi yapan /etc/systemd/system/yedek.service dosyasını oluşturun:
[Unit]
Description=Gunluk yedekleme gorevi
[Service]
Type=oneshot
ExecStart=/usr/local/bin/yedek.sh
Sonra onu tetikleyen /etc/systemd/system/yedek.timer dosyasını yazın:
[Unit]
Description=Gunluk yedeklemeyi her gece calistir
[Timer]
OnCalendar=*-*-* 00:00:00
Persistent=true
[Install]
WantedBy=timers.target
Timer'ı etkinleştirin ve aktif zamanlayıcıları listeleyin:
sudo systemctl daemon-reload
sudo systemctl enable --now yedek.timer
# Tüm timer'ları ve bir sonraki çalışma zamanlarını gör
systemctl list-timers
Persistent=true sayesinde, sunucu görev saatinde kapalı olsaydı bile açıldığında kaçırılan çalıştırmayı telafi eder; klasik cron bunu yapmaz. Yine de basit tekil görevler için cron çoğu zaman daha kısa ve tanıdıktır; ekibinizin alışkanlığına göre seçim yapabilirsiniz.
Yaygın Sorunlar ve Çözümleri#
Servis yönetiminde en sık karşılaşılan durumlardan biri failed haline düşen bir servistir. systemctl status servis çıktısı kırmızı "failed" gösteriyorsa, mutlaka journalctl -u servis -n 50 ile son logları okuyun; hatanın gerçek nedeni neredeyse her zaman oradadır (yanlış dosya yolu, port çakışması, izin hatası gibi). Sorunu çözdükten sonra sudo systemctl reset-failed servis ile başarısızlık işaretini temizleyip yeniden başlatabilirsiniz.
Bir servisi tamamen devre dışı bırakmak, hatta yanlışlıkla bile başlatılamaz hale getirmek isterseniz mask kullanılır. Bu, disable'dan daha güçlüdür; servisi /dev/null'a bağlar ve manuel start denemelerini bile reddeder:
# Servisi tamamen kilitle (başlatılamaz hale getir)
sudo systemctl mask apache2
# Kilidi kaldır
sudo systemctl unmask apache2
Bu özellikle iki farklı web sunucusunun (ör. Apache ve nginx) aynı 80 portunu istemesi gibi çakışmalarda işe yarar; kullanmadığınızı mask ederek kazara başlamasını engellersiniz. Port çakışması, izin sorunları ve otomatik başlatma gibi konular sunucu güvenliğinin de bir parçasıdır; genel bir çerçeve için sunucu güvenliği temelleri yazımızı inceleyebilirsiniz.
Sıkça Sorulan Sorular#
systemctl enable ile start arasındaki fark nedir?#
start bir servisi o an, hemen başlatır ama sunucu yeniden başladığında servis otomatik açılmaz. enable ise servisi açılış listesine ekler; yani bir sonraki yeniden başlatmada otomatik ayağa kalkmasını sağlar ama o anki çalışma durumunu değiştirmez. İkisini birden istiyorsanız systemctl enable --now servis komutu her ikisini tek seferde yapar.
Bir servisin loglarını nasıl görürüm?#
systemd ile yönetilen servislerin logları journald'da toplanır ve journalctl -u servisadi komutuyla okunur. Canlı takip için -f, son N satır için -n, zaman filtresi için --since bayraklarını kullanabilirsiniz. Örneğin journalctl -u nginx -f nginx loglarını gerçek zamanlı gösterir; hata ayıklarken bu komutu bir terminalde açık tutmak çok pratiktir.
Kendi uygulamamı neden systemd servisi yapmalıyım?#
Uygulamanızı systemd servisi yaptığınızda sunucu açılışında otomatik başlar, çökerse Restart=on-failure ile kendini onarır ve tüm çıktısı merkezi loga düşer. Uygulamayı nohup veya ekran (screen) içinde manuel çalıştırmaya kıyasla çok daha dayanıklı ve yönetilebilir bir yapı elde edersiniz. Ayrıca güncelleme, durdurma ve izleme işlemleri standart systemctl komutlarıyla tek tipleşir.
daemon-reload komutunu ne zaman çalıştırmalıyım?#
/etc/systemd/system/ altındaki bir unit dosyasını her oluşturduğunuzda veya düzenlediğinizde sudo systemctl daemon-reload çalıştırmalısınız. Bu komut systemd'nin unit tanımlarını yeniden okumasını sağlar; çalıştırmazsanız systemd eski tanımla çalışmaya devam eder ve değişikliğiniz etkisiz kalır. Sadece servisi restart etmek yeterli değildir çünkü tanım henüz belleğe yüklenmemiştir.
Type=simple ve Type=forking arasındaki fark nedir?#
Type=simple, ExecStart ile başlattığınız komutun ön planda çalışan ana süreç olduğunu varsayar; Node, Python veya Go uygulamaları gibi kendini arka plana atmayan programlar için doğru seçimdir. Type=forking ise programın başlayıp bir alt süreç oluşturduktan sonra ana sürecin sonlandığı geleneksel Unix daemon'ları için kullanılır. Yanlış tip seçerseniz systemd servisin durumunu yanlış algılar; emin değilseniz modern uygulamalarda simple ile başlamak genelde doğrudur.
Servis "failed" durumuna düştü, ne yapmalıyım?#
Önce journalctl -u servisadi -n 50 ile son log kayıtlarını okuyun; gerçek hata (yanlış yol, port çakışması, izin sorunu) neredeyse her zaman orada yazar. Sorunu giderdikten sonra sudo systemctl reset-failed servisadi ile başarısızlık işaretini temizleyip sudo systemctl start servisadi ile yeniden başlatın. Hata tekrarlıyorsa unit dosyasındaki ExecStart, User ve WorkingDirectory satırlarını dikkatle kontrol edin.
Kapanış#
systemd ve systemctl, bir Linux sunucusunu profesyonelce yönetmenin temel taşıdır. Servisleri başlatmak, açılışa bağlamak, logları journalctl ile takip etmek ve kendi uygulamanızı dayanıklı bir servise dönüştürmek; bir kez alıştığınızda günlük işlerinizi çok hızlandıran becerilerdir.
Kendi unit dosyalarınızı yazıp uygulamalarınızı yönetmek için tam kök (root) erişimine sahip bir sunucuya ihtiyacınız var. Clou.TR'nin VDS sunucuları ve sanal sunucu çözümleri size bu esnekliği sunar; kurulum ve yapılandırma yükünü bize bırakmak isterseniz sunucu yönetimi hizmetimiz ile systemd servislerinizi biz sizin adınıza kurup izleyelim. Uygun bir başlangıç için tüm sunucu paketlerimizi inceleyebilirsiniz.