systemd Kullanarak Linux Hizmetini Önyükleme Sırasında Başlatma
Sunucunuz yeniden başlatıldığında kritik hizmetlerin otomatik olarak başlamasını sağlamak, herhangi bir Linux sistem yöneticisinin en temel sorumluluklarından biridir. VPS Hosting ortamında bir web uygulaması, bir veritabanı motoru veya özel bir daemon çalıştırıyor olsanız da, beklenmedik bir yeniden başlatma asla uzun süreli kapalı kalma anlamına gelmemelidir. Günümüzün çoğu Linux dağıtımını güçlendiren modern init sistemi olan systemd ile, hizmetlerinizin nasıl, ne zaman ve kim olarak başlayacağını tam olarak tanımlayabilirsiniz; tümü temiz, bildirimsel bir birim dosyası aracılığıyla.
Bu kapsamlı kılavuz sizi her adımda yürütür: systemd’nin ne olduğunu anlamak, üretime hazır bir hizmet birim dosyası oluşturmak, izinleri doğrulamak, yürütülebilir dosyanızı test etmek ve hizmet yaşam döngüsünü yönetmek. Sonunda, özel uygulamanız her yeniden başlatmada otomatik olarak çalışacaktır.
systemd Nedir ve Neden Önemlidir?
systemd, Ubuntu, Debian, CentOS, Rocky Linux, AlmaLinux ve Fedora dahil olmak üzere çoğu büyük Linux dağıtımında SysVinit ve Upstart gibi eski alternatiflerin yerini alan bir init sistemi ve hizmet yöneticisidir. Önyüklemede sıralı bir kabuk betikleri zinciri yürütmek yerine, systemd hizmet başlatmayı paralelleştirir, bağımlılık sıralamasını çözer ve sistem işlemlerinin tüm yaşam döngüsünü tek, birleşik bir arayüzden yönetir.
Sunucu ortamları için systemd’nin temel avantajları
| Özellik | Fayda |
|---|---|
| Paralel hizmet başlatma | Çok hizmetli sunucularda daha hızlı önyükleme süreleri |
| Bağımlılık yönetimi | Hizmetler yalnızca ön koşulları hazır olduktan sonra başlar |
| Otomatik yeniden başlatma ilkeleri | Çöken hizmetler manuel müdahale olmadan kurtulur |
| journald aracılığıyla merkezi günlüğe kaydetme | Tüm hizmet çıktısı sorgulanabilir bir günlükte yakalanır |
| Cgroup tabanlı kaynak kontrolü | CPU ve bellek sınırları hizmet başına uygulanır |
| Soket ve cihaz aktivasyonu | Hizmetler koşulsuz olarak değil, talep üzerine başlar |
Dedicated Servers veya VPS örneklerinde uygulamaları yönetenler için, bu yetenekler doğrudan daha yüksek çalışma süresi ve yük altında daha öngörülebilir davranış anlamına gelir.
systemd Birim Dosyalarını Anlama
systemd’nin yönettiği her şey, bölümlere ayrılmış düz metin bir yapılandırma dosyası olan bir birim dosyası ile temsil edilir. Bir hizmet birim dosyası systemd’ye şunları söyler:
- Ne hizmet olduğu (meta veri, açıklama, bağımlılıklar)
- Nasıl çalıştırılacağı (yürütülebilir yol, çalışma dizini, kullanıcı bağlamı)
- Ne zaman başlayacağı (önyükleme hedefi, diğer birimler ile sıralama)
- Ne yapılacağı başarısız olursa (yeniden başlatma ilkesi, yeniden başlatma gecikmesi)
Sistem genelinde hizmetler için birim dosyaları /etc/systemd/system/ içinde bulunur. Buraya yerleştirilen dosyalar /lib/systemd/system/ içindeki satıcı tarafından sağlanan birimlere göre öncelik alır ve paket yükseltmeleri arasında kalıcı olur.
Adım Adım: systemd Hizmet Birimi Oluşturma
Aşağıdaki izlenecek yol, myapp adlı hayali bir uygulamayı kullanır. myapp, myuser ve /usr/bin/myapp öğesinin her örneğini kendi ortamınız için uygun değerlerle değiştirin.
Adım 1: Çalışma Dizinini Hazırlayın
Birim dosyasını yazmadan önce, uygulamanızın nereye çalışacağına karar verin. Adanmış bir çalışma dizini yapılandırma dosyalarını, günlükleri ve çalışma zamanı verilerini düzenli tutar ve izin yönetimini basit hale getirir.
Dizin zaten mevcut değilse oluşturun:
sudo mkdir -p /opt/myapp> Neden /opt/ yerine /etc/systemd/?
> /etc/systemd/ ağacı systemd’nin kendi yapılandırması için ayrılmıştır. Uygulama verilerini buraya yerleştirmek standart dışıdır ve kafa karışıklığına neden olabilir. Dosya Sistemi Hiyerarşisi Standardı kategorisine en uygun olan /opt/myapp, /srv/myapp veya /var/lib/myapp kullanın.
Sahipliği hizmeti çalıştıracak kullanıcıya atayın:
sudo useradd --system --no-create-home --shell /usr/sbin/nologin myuser
sudo chown -R myuser:myuser /opt/myappAdanmış bir sistem hesabı kullanmak (giriş kabuğu yok, ev dizini yok) bir güvenlik en iyi uygulamasıdır. Uygulama hiç bir zaman tehlikeye girerse hasar alanını sınırlar.
Sonucu doğrulayın:
ls -ld /opt/myapp
# Expected output: drwxr-xr-x 2 myuser myuser 4096 Jan 1 00:00 /opt/myappAdım 2: Hizmet Birim Dosyası Oluşturun
Tercih ettiğiniz düzenleyici ile yeni bir birim dosyası açın:
sudo nano /etc/systemd/system/myapp.serviceAşağıdaki içeriği yapıştırın, değerleri uygulamanızla eşleşecek şekilde ayarlayın:
[Unit]
Description=My Custom Application
Documentation=https://example.com/docs
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/usr/bin/myapp --config /opt/myapp/myapp.conf
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5s
User=myuser
Group=myuser
WorkingDirectory=/opt/myapp
StandardOutput=journal
StandardError=journal
SyslogIdentifier=myapp
# Security hardening
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
[Install]
WantedBy=multi-user.targetDosyayı Ctrl+O ile kaydedin, ardından Ctrl+X ile çıkın.
Adım 3: Her Yönergeyi Anlama
[Unit] Bölümü
| Yönerge | Amaç |
|---|---|
Description | systemctl status çıktısında gösterilen insan tarafından okunabilir ad |
Documentation | Hizmet için URL veya man sayfası referansı |
After | Hizmetin listelenen birim etkin olduktan *sonra* başlamasını sağlar |
Wants | Yumuşak bağımlılık — systemd listelenen birimi başlatmaya *çalışacak* ancak kullanılamıyorsa başarısız olmayacak |
> network-online.target vs network.target: network-online.target (Wants=network-online.target ile birlikte) önyüklemede uzak bir veritabanına veya harici bir API’ye bağlanan bir uygulama gibi, tamamen yapılandırılmış bir ağ arayüzüne gerçekten ihtiyaç duyan hizmetler için kullanın. network.target yalnızca ağ alt sisteminin *başlatıldığını*, arayüzlerin hazır olduğunu ve adreslerin atandığını garanti etmez.
[Service] Bölümü
| Yönerge | Amaç |
|---|---|
Type=simple | ExecStart tarafından başlatılan işlem ana işlemdir (çoğu uygulama için varsayılan) |
ExecStart | İkili dosyaya ve herhangi bir argümana tam yol. Her zaman mutlak yollar kullanın. |
ExecReload | Tam yeniden başlatma olmadan yapılandırmayı yeniden yüklemek için komut (isteğe bağlı ancak önerilir) |
Restart=on-failure | Hizmet sıfır olmayan bir kodla çıktığında veya bir sinyal tarafından öldürüldüğünde yeniden başlatın. Temiz çıkışlarda da yeniden başlatmalar istiyorsanız always kullanın. |
RestartSec | Yeniden başlatma denemesinden önce beklenecek saniye |
User / Group | Kök yerine bu kullanıcı/grup olarak işlemi çalıştırın |
WorkingDirectory | ExecStart yürütmeden önce geçerli dizini ayarlayın |
StandardOutput / StandardError | Stdout/stderr’i systemd günlüğüne yönlendirin |
SyslogIdentifier | Bu hizmet için günlük girdilerini filtrelemek için kullanılan etiket |
NoNewPrivileges | İşlemin setuid ikili dosyaları aracılığıyla ek ayrıcalıklar kazanmasını engeller |
ProtectSystem=strict | /usr, /boot ve /etc hizmet için salt okunur olarak bağlar |
ProtectHome | /home, /root ve /run/user erişilemez hale getirir |
PrivateTmp | Hizmete kendi özel /tmp ad alanı verir |
[Install] Bölümü
| Yönerge | Amaç |
|---|---|
WantedBy=multi-user.target | Sistem standart çok kullanıcılı (grafik olmayan) runlevel’e ulaştığında hizmeti etkinleştirir. Bu neredeyse tüm sunucu daemon’ları için doğru hedefidir. |
Adım 4: Dosya ve Dizin İzinlerini Doğrulayın
systemd’yi yeniden yüklemeden önce, hizmet kullanıcısının gerçekten ihtiyaç duyduğu her şeye erişebildiğini doğrulayın:
# Check working directory ownership and permissions
ls -ld /opt/myapp
# Confirm the executable exists and is executable
ls -l /usr/bin/myapp
# Verify the config file is readable by myuser
sudo -u myuser cat /opt/myapp/myapp.confBu kontrollerin herhangi biri başarısız olursa, devam etmeden önce izinleri düzeltin:
# Make the binary executable
sudo chmod +x /usr/bin/myapp
# Grant read access to the config file
sudo chmod 640 /opt/myapp/myapp.conf
sudo chown myuser:myuser /opt/myapp/myapp.confAdım 5: Yürütülebilir Dosyayı Manuel Olarak Test Edin
Kontrolü systemd’ye vermeden *önce* uygulamanızın doğru çalıştığını her zaman doğrulayın. Bu, uygulama hatalarını systemd yapılandırma sorunlarından ayırır:
sudo -u myuser /usr/bin/myapp --config /opt/myapp/myapp.confUygulama hatasız başlarsa, durdurmak için Ctrl+C tuşuna basın ve devam edin. Başarısız olursa, uygulamanın kendisini sorun giderin — tüm bağımlılıkların yüklendiğini, ortam değişkenlerinin ayarlandığını ve gerekli portların kullanılabilir olduğunu kontrol edin.
Adım 6: systemd’yi Yeniden Yükleyin ve Hizmeti Etkinleştirin
Birim dosyasını kaydettikten sonra, systemd’ye yapılandırmasını yeniden okumasını söyleyin:
sudo systemctl daemon-reloadHizmeti her sonraki önyüklemede otomatik olarak başlayacak şekilde etkinleştirin:
sudo systemctl enable myapp.serviceBu komut uygun .wants dizininde bir sembolik bağlantı oluşturur, birim dosyanızı multi-user.target önyükleme dizisine bağlar. Şuna benzer bir çıktı görmelisiniz:
Created symlink /etc/systemd/system/multi-user.target.wants/myapp.service → /etc/systemd/system/myapp.service.Yeniden başlatmadan hizmeti hemen başlatın:
sudo systemctl start myapp.serviceAdım 7: Hizmetin Çalıştığını Doğrulayın
Hizmetin geçerli durumunu kontrol edin:
sudo systemctl status myapp.serviceSağlıklı bir hizmet şuna benzer bir çıktı üretir:
● myapp.service - My Custom Application
Loaded: loaded (/etc/systemd/system/myapp.service; enabled; vendor preset: disabled)
Active: active (running) since Wed 2025-01-01 12:00:00 UTC; 5s ago
Main PID: 12345 (myapp)
Tasks: 4 (limit: 4915)
Memory: 12.3M
CPU: 45ms
CGroup: /system.slice/myapp.service
└─12345 /usr/bin/myapp --config /opt/myapp/myapp.confDoğrulanacak temel alanlar:
Loaded— birim dosyasının başarıyla ayrıştırıldığını doğrular ve önyükleme içinenabledveyadisabledolup olmadığını gösterirActive: active (running)— hizmet şu anda çalışıyorMain PID— uygulamanızın işlem kimliği
Adım 8: journalctl ile Günlükleri İzleyin
systemd tüm hizmet çıktısını günlüğe, yapılandırılmış, sorgulanabilir bir günlük deposuna yönlendirir. Bunu incelemek için journalctl kullanın:
# View all logs for myapp (most recent last)
journalctl -u myapp.service
# Follow live log output (like tail -f)
journalctl -u myapp.service -f
# Show only logs since the last boot
journalctl -u myapp.service -b
# Show the last 50 lines
journalctl -u myapp.service -n 50
# Show logs since a specific time
journalctl -u myapp.service --since "2025-01-01 12:00:00"Hizmetiniz başlamazsa, günlük neredeyse her zaman neden başarısız olduğunu açıklayan tam hata mesajını içerir. Herhangi bir değişiklik yapmadan önce burası ilk bakılacak yerdir.
Adım 9: Önyükleme Davranışını Test Edin
Hizmetin önyükleme dizisini manuel olarak incelemeden yeniden başlatmayı hayatta kalıp kalmadığını doğrulamak için bunu simüle edebilirsiniz:
# Reboot the server (only if safe to do so)
sudo rebootSunucu çevrimiçi olduktan sonra, hizmet durumunu tekrar kontrol edin:
sudo systemctl status myapp.serviceactive (running) gösteriyorsa, hizmetiniz otomatik başlatma için doğru şekilde yapılandırılmıştır.
Hizmet Yaşam Döngüsünü Yönetme
Hizmetiniz çalışmaya başladıktan sonra, aşağıdaki komutları düzenli olarak kullanacaksınız:
Yaygın systemctl Komutları
# Start the service
sudo systemctl start myapp.service
# Stop the service gracefully
sudo systemctl stop myapp.service
# Restart the service (stop + start)
sudo systemctl restart myapp.service
# Reload configuration without restarting (if ExecReload is defined)
sudo systemctl reload myapp.service
# Enable automatic startup at boot
sudo systemctl enable myapp.service
# Disable automatic startup at boot
sudo systemctl disable myapp.service
# Check whether the service is enabled
sudo systemctl is-enabled myapp.service
# Check whether the service is currently active
sudo systemctl is-active myapp.service
# View the full unit file as systemd interprets it
sudo systemctl cat myapp.service
# Edit the unit file and reload in one step
sudo systemctl edit --full myapp.serviceYaygın Sorunları Giderme
Hizmet başlamazsa: “Böyle bir dosya veya dizin yok”
Bu genellikle ExecStart mevcut olmayan bir ikiliye işaret ettiği veya WorkingDirectory mevcut olmadığı anlamına gelir. Her iki yolu da doğrulayın:
which myapp
ls -l /opt/myappHizmet başlar ancak hemen çıkar
Uygulamanın kendi hata çıktısı için günlüğü kontrol edin:
journalctl -u myapp.service -n 100 --no-pagerAyrıca Type=simple uygulamanız için doğru olduğunu doğrulayın. İkili dosyanız kendisini arka plana çatallandırırsa, bunun yerine Type=forking kullanın.
“İzin reddedildi” hataları
Hizmet kullanıcısı gerekli bir dosya veya dizine erişemez. ls -l kullanarak izinleri denetleyin ve sudo -u myuser erişimi etkileşimli olarak test edin.
Port zaten kullanımda
Başka bir işlem uygulamanızın ihtiyaç duyduğu porta bağlı. Bunu şu şekilde tanımlayın:
sudo ss -tlnp | grep :<port>Hizmet bir döngüde yeniden başlar
###PP
on All Hosting Services
