Ubuntu’da Betik Otomatik Yüklemeyi Etkinleştirme: Üretime Hazır Üç Yöntem
Ubuntu’da betik otomatik yüklemeyi etkinleştirmek, işletim sistemini herhangi bir manuel müdahale olmaksızın sistem başlangıcında bir veya daha fazla kabuk betiğini ya da hizmeti otomatik olarak çalıştıracak şekilde yapılandırmak anlamına gelir. Bu, üç temel mekanizma aracılığıyla sağlanır: eski SysVinit tabanlı /etc/init.d/ dizini, /etc/rc.local uyumluluk katmanı ve modern systemd servis birimi çerçevesi — sonuncusu, Ubuntu 15.04’ten itibaren tüm Ubuntu sürümlerinde yetkili ve önerilen yaklaşımdır.
Bir VPS Hosting ortamında iş yükü çalıştıran sistem yöneticileri için başlangıç otomasyonu bir kolaylık değil, bir güvenilirlik gereksinimidir. Yanlış yapılandırılmış veya eksik bir otomatik başlatma girişi, kritik daemon’ların, izleme ajanlarının, yedekleme betiklerinin veya özel ağ yapılandırmalarının yeniden başlatma sonrasında sessizce başlatılamamasına ve sonradan teşhis edilmesi güç servis kesintilerine yol açar.
Ubuntu Sunucularında Başlangıç Betiği Otomasyonunun Önemi
Her üretim Ubuntu sunucusu zamanla operasyonel betikler biriktirir: veritabanı ön ısıtma rutinleri, günlük döndürme tetikleyicileri, VPN tünel başlatıcıları, güvenlik duvarı kural yükleyicileri ve uygulama sağlık kontrolleri. Yapılandırılmış bir otomatik yükleme mekanizması olmadan bu betikler tamamen manuel çalıştırmaya bağımlıdır — bir çekirdek güncellemesi veya acil yeniden başlatma sonrasında atlanacak tek bir adım, kesintiye dönüşebilir.
Ubuntu’nun başlangıç otomasyon ekosistemi önemli ölçüde gelişmiştir:
- SysVinit (Ubuntu 15.04 öncesi): Sıralı, yavaş, betik tabanlı. Her hizmet bir sonrakini engelliyordu.
- Upstart (Ubuntu 6.10–15.04): Olay güdümlü, daha hızlı, ancak artık kullanımdan kaldırılmış.
- systemd (Ubuntu 15.04+): Paralel servis aktivasyonu, bağımlılık grafikleri, soket aktivasyonu, cgroup tabanlı kaynak kontrolü ve
journaldaracılığıyla yapılandırılmış günlükleme.
Hangi katmanla çalıştığınızı ve nedenini anlamak, test ortamında çalışan ancak üretimde sessizce bozulan bir çözüm dağıtmanızı önler.
Yöntem 1: /etc/init.d/ Dizinini Kullanma (SysVinit / LSB Betikleri)
Nasıl Çalışır
/etc/init.d/ dizini, Linux Standard Base (LSB) init betikleri için geleneksel konumdur. Bu dizindeki her betik, standartlaştırılmış komutlara yanıt veren bir kabuk betiğidir: start, stop, restart, status ve isteğe bağlı olarak reload. update-rc.d yardımcı programı, /etc/rcN.d/ çalışma seviyesi dizinlerinde sembolik bağlantılar oluşturarak betiğin önyükleme ve kapatma sırasında ne zaman ve hangi sırayla çalışacağını belirler.
systemd çalıştıran modern Ubuntu sistemlerinde bu betikler, LSB init betiklerini geçici systemd birimlerine otomatik olarak dönüştüren systemd-sysv-generator adlı bir uyumluluk katmanı aracılığıyla hâlâ desteklenmektedir. Bu, /etc/init.d/ betiklerinizin çalışmaya devam edeceği, ancak doğrudan SysVinit tarafından değil systemd tarafından sarmalanarak çalıştırılacağı anlamına gelir.
Adım Adım Uygulama
Adım 1: Betiğinizi oluşturun
Betiğinizi yazın ve LSB başlık kuralına uyduğundan emin olun. Minimal, üretime hazır bir örnek:
#!/bin/bash
### BEGIN INIT INFO
# Provides: examplescript
# Required-Start: $remote_fs $syslog $network
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Example autoload script
# Description: Runs a custom initialization task at boot
### END INIT INFO
case "$1" in
start)
echo "Starting examplescript..."
/usr/local/bin/examplescript.sh &
;;
stop)
echo "Stopping examplescript..."
pkill -f examplescript.sh
;;
restart)
$0 stop
$0 start
;;
status)
pgrep -f examplescript.sh > /dev/null && echo "Running" || echo "Stopped"
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
exit 1
;;
esac
exit 0Adım 2: Betiği /etc/init.d/ konumuna yerleştirin
sudo cp examplescript /etc/init.d/examplescriptAdım 3: Çalıştırılabilir yapın
sudo chmod +x /etc/init.d/examplescriptAdım 4: Çalışma seviyesi sistemiyle kaydedin
sudo update-rc.d examplescript defaultsdefaults argümanı, betiği 2, 3, 4 ve 5 çalışma seviyelerinde başlatmak ve 0, 1 ve 6 çalışma seviyelerinde durdurmak üzere kaydeder — çoğu sunucu daemon’u için standart davranış budur.
Adım 5: Kaydı doğrulayın
ls -la /etc/rc2.d/ | grep examplescript/etc/init.d/examplescript konumuna işaret eden S01examplescript gibi bir sembolik bağlantı görmelisiniz.
Kritik Tuzak
Bu yöntemde en yaygın hata, LSB başlık bloğunun atlanmasıdır. Başlık bloğu olmadan update-rc.d bağımlılık sıralamasını belirleyemez ve systemd-sysv-generator ağ kullanılabilirliği veya dosya sistemi bağlantılarına göre yanlış bir çalışma sırası atayabilir. Required-Start bağımlılıklarını her zaman açıkça tanımlayın.
Betiği silmeden otomatik başlatmadan kaldırmak için:
sudo update-rc.d examplescript disableTamamen kaldırmak için:
sudo update-rc.d examplescript removeYöntem 2: /etc/rc.local Kullanımı (Uyumluluk Katmanı)
Nasıl Çalışır
/etc/rc.local, tüm standart çok kullanıcılı çalışma seviyesi hizmetleri başladıktan sonra bir kabuk betiğini bir kez çalıştıran eski bir mekanizmadır. Servis yönetimi, bağımlılık bildirimleri veya yeniden başlatma mantığı olmaksızın mümkün olan en basit otomatik başlatma yöntemidir. Ubuntu 18.04 ve sonrasında rc.local desteği, varsayılan olarak devre dışı olan ve açıkça etkinleştirilmesi gereken rc-local.service systemd birimi tarafından sağlanır.
Ne Zaman Kullanılır
/etc/rc.local‘i yalnızca şunlar için kullanın:
- Servis olarak yönetilmesi gerekmeyen tek seferlik başlatma komutları
- Bir systemd birimini resmileştirmeden önce hızlı prototipleme veya test
- Basit ortam değişkeni dışa aktarmaları veya çekirdek parametre ayarlamaları
Uzun süre çalışan daemon’lar için /etc/rc.local kullanmayın. Süreç denetimi olmaksızın engelleyici ve sıralı bir şekilde çalıştığından, rc.local içinde askıya alınan bir komut önyükleme sırasının tamamlanmasını geciktirebilir veya engelleyebilir.
Adım Adım Uygulama
Adım 1: /etc/rc.local dosyasının var olup olmadığını kontrol edin
ls -la /etc/rc.localYoksa oluşturun:
sudo bash -c 'cat > /etc/rc.local << EOF
#!/bin/bash
exit 0
EOF'
sudo chmod +x /etc/rc.localAdım 2: rc-local systemd birimini etkinleştirin (Ubuntu 18.04+)
sudo systemctl enable rc-local
sudo systemctl start rc-localAdım 3: exit 0 satırından önce komutunuzu ekleyin
sudo nano /etc/rc.localKomutunuzu exit 0 satırının üstüne ekleyin:
#!/bin/bash
/usr/local/bin/examplescript.sh >> /var/log/examplescript.log 2>&1 &
exit 0Sondaki &, uzun süre çalışan herhangi bir komut için zorunludur — işlemi arka plana çatallayarak rc.local‘ın engellenmesini önler.
Adım 4: Çalışmayı doğrulayın
sudo systemctl status rc-localKritik Tuzak
Ubuntu 20.04 ve 22.04’te rc-local.service, sabit kodlanmış 30 saniyelik bir zaman aşımına sahiptir. Betiğinizin tamamlanması 30 saniyeden uzun sürerse systemd, hizmeti başarısız olarak işaretler ve rc.local içindeki sonraki komutlar çalıştırılmaz. Çıktıyı yönlendirin ve uzun süre çalışan işlemleri açıkça arka plana alın.
Yöntem 3: systemd Servis Birimlerini Kullanma (Önerilen)
systemd’nin Üretim İçin Doğru Yaklaşım Olmasının Nedeni
systemd, SysVinit’in yalnızca bir yedeği değildir — bağımlılık çözümü, paralel başlatma, soket ve D-Bus aktivasyonu, talep üzerine servis oluşturma, otomatik yeniden başlatma ile süreç denetimi, cgroup tabanlı kaynak yalıtımı ve journald aracılığıyla yapılandırılmış günlük toplama sağlayan eksiksiz bir sistem ve oturum yöneticisidir. Bir Dedicated Server veya üretim VPS üzerinde çalışan herhangi bir iş yükü için systemd birimleri, otomatik yüklenen betikleri yönetmek için tek uygun mekanizmadır.
systemd Birim Dosyasının Anatomisi
Bir .service birim dosyası üç zorunlu bölüme ayrılır:
[Unit]: Meta veriler, insan tarafından okunabilir açıklama ve bağımlılık bildirimleri (After=,Requires=,Wants=).[Service]: Çalıştırma parametreleri — çalıştırılacak ikili dosya veya betik, servis türü, yeniden başlatma politikası, ortam değişkenleri ve güvenlik korumalı alan seçenekleri.[Install]: Bu birimi hangi systemd hedefinin etkinleştireceğini tanımlar (WantedBy=multi-user.target, sunucu daemon’ları için standarttır).
Adım Adım Uygulama
Adım 1: Betiğinizi hazırlayın
Betiğinizin çalıştırılabilir olduğundan ve kararlı bir konumda bulunduğundan emin olun:
sudo cp examplescript.sh /usr/local/bin/examplescript.sh
sudo chmod +x /usr/local/bin/examplescript.shAdım 2: Birim dosyasını oluşturun
sudo nano /etc/systemd/system/examplescript.serviceGüvenlik sertleştirmeli üretime hazır bir birim dosyası:
[Unit]
Description=Example Autoload Script
Documentation=https://your-internal-wiki/examplescript
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/usr/local/bin/examplescript.sh
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5s
StandardOutput=journal
StandardError=journal
SyslogIdentifier=examplescript
User=nobody
Group=nogroup
NoNewPrivileges=true
ProtectSystem=strict
PrivateTmp=true
[Install]
WantedBy=multi-user.targetAdım 3: systemd daemon’unu yeniden yükleyin
Herhangi bir birim dosyası oluşturulduktan veya değiştirildikten sonra daemon’un yapılandırma dizinini yeniden yüklemeniz gerekir:
sudo systemctl daemon-reloadAdım 4: Otomatik başlatma için servisi etkinleştirin
sudo systemctl enable examplescript.serviceBu, /etc/systemd/system/multi-user.target.wants/ içinde birim dosyanıza işaret eden bir sembolik bağlantı oluşturur.
Adım 5: Servisi hemen başlatın
sudo systemctl start examplescript.serviceAdım 6: Durumu ve günlükleri doğrulayın
sudo systemctl status examplescript.service
sudo journalctl -u examplescript.service -fsystemd Servis Türlerini Anlamak
[Service] bölümündeki Type= yönergesi, en yanlış anlaşılan parametrelerden biridir. Yanlış tür seçmek, systemd’nin servis hazırlığını yanlış raporlamasına ve bağımlılık hatalarına yol açar.
| Tür | Davranış | Kullanım Durumu |
|---|---|---|
simple | ExecStart tarafından başlatılan süreç ana süreçtir. systemd bunu hemen hazır kabul eder. | Çatallanmayan betikler ve basit daemon’lar |
forking | Süreç çatallanır ve üst süreç çıkar. systemd, alt süreci PID dosyası aracılığıyla izler. | Geleneksel Unix daemon’ları (örn. PidFile ile Apache) |
oneshot | Süreç tamamlanana kadar çalışır ve çıkar. systemd, bağımlı birimleri başlatmadan önce bekler. | Tek seferlik başlatma görevleri, kurulum betikleri |
notify | Süreç hazırlığını sd_notify() aracılığıyla bildirir. | Yerel systemd entegrasyonuna sahip daemon’lar |
idle | Tüm aktif işler dağıtılana kadar çalışma ertelenir. | Düşük öncelikli arka plan görevleri |
Önyüklemede bir kez çalışıp çıkan bir betik için, betik tamamlandıktan sonra birimi “aktif” durumda tutmak amacıyla RemainAfterExit=yes ile birlikte Type=oneshot kullanın.
Gelişmiş: After= ve Wants= ile Bağımlılık Sıralaması
Yaygın bir üretim hatası, ağ bağlantısı gerektiren bir betiğin ağ yığını tam olarak başlatılmadan önce başlamasıdır. Ağa bağımlı betikler için doğru bağımlılık zinciri şöyledir:
After=network-online.target
Wants=network-online.targetBu durum, yalnızca ağ arayüzlerinin yapılandırıldığını garanti eden — gerçekten çevrimiçi ve erişilebilir olduklarını değil — After=network.target‘dan farklıdır. network-online.target bağımlılığı, bağlantıyı doğrulamak için systemd-networkd-wait-online.service veya eşdeğerini gerektirir.
Karşılaştırma: Üç Yöntemin Özeti
| Özellik | /etc/init.d/ | /etc/rc.local | systemd Birimi |
|---|---|---|---|
| Üretim için önerilen | Hayır | Hayır | Evet |
| Paralel başlatma desteği | Hayır | Hayır | Evet |
| Süreç denetimi / otomatik yeniden başlatma | Hayır | Hayır | Evet |
| Bağımlılık yönetimi | Sınırlı (LSB başlıkları) | Yok | Tam |
| Yapılandırılmış günlükleme | Hayır | Hayır | Evet (journald) |
| Güvenlik korumalı alanı | Hayır | Hayır | Evet |
| Karmaşıklık | Düşük | Çok düşük | Orta |
| Ubuntu 22.04+ desteği | Uyumluluk katmanı aracılığıyla | rc-local.service aracılığıyla | Yerel olarak |
| Uzun süre çalışan daemon’lar için uygun | Kısmen | Hayır | Evet |
| Tek seferlik başlatma görevleri için uygun | Evet | Evet | Evet (oneshot) |
Yaygın Hatalar ve Bunlardan Kaçınma Yolları
Betikleri gereksiz yere root olarak çalıştırmak. systemd birim dosyalarındaki User= ve Group= yönergeleri ayrıcalıkları düşürmenize olanak tanır. Yalnızca /var/log/myapp/ konumuna yazmaya ihtiyaç duyan bir betik root gerektirmez — özel bir sistem kullanıcısı oluşturun ve dizin sahipliğini buna göre atayın.
rc.local içinde çıktıyı yönlendirmemek. Çıktı yönlendirmesi olmadan, rc.local komutlarından gelen echo veya hata çıktısı sistem konsoluna gider ve kaybolur. Her zaman >> /var/log/yourscript.log 2>&1 ekleyin.
Mutlak yolları tutarsız kullanmak. systemd servisleri, kullanıcının PATH değişkeni olmayan minimal bir ortamda çalışır. /usr/bin/python3 veya /bin/bash gibi yorumlayıcılar dahil olmak üzere ExecStart içinde başvurulan her ikili dosya için her zaman mutlak yollar kullanın.
Birim dosyalarını düzenledikten sonra daemon-reload çalıştırmayı unutmak. systemd, birim dosyası içeriklerini önbelleğe alır. Bir .service dosyasını düzenler ve sudo systemctl daemon-reload çalıştırmazsanız systemd eski yapılandırmayı kullanmaya devam eder.
Özel betikler için birim dosyalarını /lib/systemd/system/ konumuna yerleştirmek. /lib/systemd/system/ dizini paket yöneticisi tarafından yönetilir. Özel birim dosyaları, öncelik taşıyan ve paket yükseltmelerinden etkilenmeyen /etc/systemd/system/ konumuna ait olmalıdır.
Pratik Karar Matrisi: Hangi Yöntemi Kullanmalı
Belirli senaryonuz için uygun yöntemi seçmek üzere bu çerçeveyi kullanın:
- Hata durumunda yeniden başlatılması gereken uzun süre çalışan daemon —
Restart=on-failureile systemd birimi - Diğer servisler başlamadan önce tamamlanması gereken tek seferlik kurulum betiği —
Type=oneshotveBefore=bağımlılıklarıyla systemd birimi - Ağın tamamen çevrimiçi olmasını gerektiren betik —
After=network-online.targetile systemd birimi - Test veya prototipleme için hızlı tek satırlık komut —
/etc/rc.local(geçici olarak) - LSB init betiğiyle birlikte gelen eski uygulama —
update-rc.dile/etc/init.d/ - Üretimde çalışan her şey — her zaman systemd
Birden fazla Ubuntu sunucusunu yöneten yöneticiler için systemd birim yönetimini, .service dosyalarını tüm filonuzda etkisiz biçimde dağıtıp etkinleştirebilen Ansible gibi yapılandırma yönetimi araçlarıyla eşleştirmeyi düşünün. Bu yapılandırmaları uygulamak için tam root erişimine sahip yönetilen bir ortama ihtiyaç duyuyorsanız, VPS Hosting ile birlikte VPS Control Panel, systemd servislerini kısıtlama olmaksızın doğrudan yönetme esnekliği sağlar.
GPU sürücülerini, CUDA ortamlarını veya ML çıkarım sunucularını başlatmak için başlangıç betikleri gerektiren kaynak yoğun iş yükleri çalıştıran ekipler için GPU Hosting ortamları, systemd’nin After= bağımlılık zincirlerinden özellikle yararlanır; bu sayede uygulama servisleri donanım kaynaklarına bağlanmaya çalışmadan önce sürücülerin tam olarak yüklendiği garanti edilir.
Otomatik yüklenen betikleriniz bir kontrol paneli ortamına bağlı web sunucusu yapılandırmaları veya veritabanı başlatma rutinleriyle etkileşime giriyorsa, VPS with cPanel kurulumlarında ekstra dikkat gereklidir — cPanel kendi servis denetim katmanını yönetir ve özel systemd birimleri, cPanel’in servis yönetimi kancalarıyla çakışmayı önleyecek şekilde tanımlanmalıdır.
Teknik Temel Kontrol Listesi
Bir Ubuntu sunucusuna herhangi bir başlangıç betiği dağıtmadan önce aşağıdakileri doğrulayın:
- Birim dosyası konumu: Özel betikler
/lib/systemd/system/değil/etc/systemd/system/konumuna gider - Çalıştırılabilir bit:
ls -la /path/to/script.shile doğrulayın —xbiti ayarlanmış olmalıdır - Mutlak yollar:
ExecStartiçindeki her ikili dosya tam yol kullanır;$PATH‘a bağımlılık yoktur - Bağımlılık bildirimleri: Ağa bağımlı her betik için
After=network-online.target - Servis türü: Kalıcı daemon’lar için
Type=simple, çalışıp çıkan betikler içinType=oneshot - Ayrıcalık minimizasyonu:
User=,Group=,NoNewPrivileges=true,ProtectSystem=strict - Günlükleme yapılandırıldı:
journaldentegrasyonu içinStandardOutput=journalveStandardError=journal - daemon-reload çalıştırıldı: Birim dosyaları oluşturulduktan veya düzenlendikten sonra her zaman
sudo systemctl daemon-reloadçalıştırın - Enable ile start farkı:
enableotomatik başlatma sembolik bağlantısını oluşturur;starthemen çalıştırır — her ikisi de gereklidir journalctlile test edildi:sudo journalctl -u yourservice.service --since "5 minutes ago"ile başarılı çalışmayı doğrulayın
SSS
systemctl enable ile systemctl start arasındaki fark nedir?
systemctl enable, servisin bir sonraki önyüklemede otomatik olarak başlamasını sağlayan bir sembolik bağlantı oluşturur. systemctl start, servisi mevcut oturumda hemen başlatır. Yeni bir servisi ilk kez kurarken genellikle her iki komuta da ihtiyaç duyarsınız.
Betik mevcut olmasına rağmen systemd servisim neden “executable not found” hatasıyla başarısız oluyor?
Bu neredeyse her zaman ExecStart yolunun yanlış olduğu veya betiğin çalıştırılabilir bitinin eksik olduğu anlamına gelir. which yourscript ve ls -la /path/to/script ile doğrulayın. Ayrıca betiğinizin ilk satırının geçerli bir shebang (#!/bin/bash veya #!/usr/bin/env python3) olduğunu doğrulayın; systemd, ExecStart için varsayılan olarak bir kabuk çağırmaz.
Her önyüklemede değil, yalnızca bir kez başlangıçta betik çalıştırabilir miyim?
[Unit] bölümünde ConditionPathExists=!/var/run/myscript.done yönergesiyle birlikte Type=oneshot kullanın. Betik ilk çalışmada sentinel dosyasını oluşturur; sonraki önyüklemelerde koşul başarısız olduğundan çalışma atlanır.
/etc/rc.local Ubuntu 22.04’te hâlâ destekleniyor mu?
Evet, ancak varsayılan olarak devre dışıdır. sudo systemctl enable rc-local ile rc-local.service birimini manuel olarak etkinleştirmeniz ve dosyanın var olduğundan ve çalıştırılabilir olduğundan emin olmanız gerekir. Önerilen bir uygulama değil, uyumluluk tedbiri olarak desteklenmektedir.
Bir başlangıç betiğinin neden çalışmadığını nasıl kontrol edebilirim?
Son önyüklemeden bu yana o birime ait tüm günlük girişlerini görüntülemek için sudo journalctl -u yourservice.service -b çalıştırın. rc.local hataları için sudo systemctl status rc-local.service kontrol edin ve önyükleme sırası sırasında zaman damgalı girişler için /var/log/syslog inceleyin.
