Cara Mengaktifkan Autoloading Skrip di Ubuntu: Tiga Metode Siap Produksi
Mengaktifkan autoloading skrip di Ubuntu berarti mengonfigurasi sistem operasi untuk secara otomatis menjalankan satu atau lebih skrip shell atau layanan saat sistem startup, tanpa intervensi manual apa pun. Hal ini dicapai melalui tiga mekanisme utama: direktori /etc/init.d/ berbasis SysVinit yang sudah lama ada, shim kompatibilitas /etc/rc.local, dan kerangka unit layanan systemd modern — yang terakhir merupakan pendekatan yang otoritatif dan direkomendasikan pada semua rilis Ubuntu mulai dari 15.04 ke atas.
Bagi administrator sistem yang menjalankan beban kerja di lingkungan VPS Hosting, otomatisasi startup bukan sekadar kemudahan — melainkan sebuah kebutuhan keandalan. Entri autostart yang salah dikonfigurasi atau tidak ada berarti daemon penting, agen pemantauan, skrip pencadangan, atau konfigurasi jaringan kustom gagal diluncurkan secara diam-diam setelah reboot, menyebabkan gangguan layanan yang sulit didiagnosis setelah kejadian.
Mengapa Otomatisasi Skrip Startup Penting di Server Ubuntu
Setiap server Ubuntu produksi mengakumulasi skrip operasional dari waktu ke waktu: rutinitas pre-warm database, pemicu rotasi log, inisialisasi tunnel VPN, pemuat aturan firewall, dan pemeriksaan kesehatan aplikasi. Tanpa mekanisme autoloading yang terstruktur, skrip-skrip ini sepenuhnya bergantung pada eksekusi manual — satu langkah yang terlewat setelah pembaruan kernel atau reboot darurat dapat berujung pada downtime.
Ekosistem otomatisasi startup Ubuntu telah berkembang secara signifikan:
- SysVinit (sebelum Ubuntu 15.04): Sekuensial, lambat, berbasis skrip. Setiap layanan memblokir layanan berikutnya.
- Upstart (Ubuntu 6.10–15.04): Berbasis event, lebih cepat, tetapi kini sudah tidak digunakan lagi.
- systemd (Ubuntu 15.04+): Aktivasi layanan paralel, grafik dependensi, aktivasi socket, kontrol sumber daya berbasis cgroup, dan logging terstruktur melalui
journald.
Memahami lapisan mana yang sedang Anda gunakan — dan alasannya — mencegah Anda menerapkan solusi yang berfungsi di lingkungan pengujian tetapi diam-diam rusak di produksi.
Metode 1: Menggunakan Direktori /etc/init.d/ (SysVinit / Skrip LSB)
Cara Kerjanya
Direktori /etc/init.d/ adalah tempat tradisional untuk skrip init Linux Standard Base (LSB). Setiap skrip dalam direktori ini adalah skrip shell yang merespons perintah standar: start, stop, restart, status, dan opsional reload. Utilitas update-rc.d membuat tautan simbolis di direktori runlevel /etc/rcN.d/, menentukan kapan dan dalam urutan apa skrip dijalankan selama urutan boot dan shutdown.
Pada sistem Ubuntu modern yang menjalankan systemd, skrip-skrip ini masih didukung melalui lapisan kompatibilitas yang disebut systemd-sysv-generator, yang secara otomatis mengonversi skrip init LSB menjadi unit systemd sementara. Ini berarti skrip /etc/init.d/ Anda masih akan berjalan, tetapi dibungkus oleh systemd daripada dieksekusi langsung oleh SysVinit.
Implementasi Langkah demi Langkah
Langkah 1: Buat skrip Anda
Tulis skrip Anda dan pastikan mengikuti konvensi header LSB. Contoh minimal yang aman untuk produksi:
#!/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 0Langkah 2: Tempatkan skrip di /etc/init.d/
sudo cp examplescript /etc/init.d/examplescriptLangkah 3: Jadikan dapat dieksekusi
sudo chmod +x /etc/init.d/examplescriptLangkah 4: Daftarkan ke sistem runlevel
sudo update-rc.d examplescript defaultsArgumen defaults mendaftarkan skrip untuk memulai di runlevel 2, 3, 4, dan 5, serta berhenti di runlevel 0, 1, dan 6 — perilaku standar untuk sebagian besar daemon server.
Langkah 5: Verifikasi pendaftaran
ls -la /etc/rc2.d/ | grep examplescriptAnda seharusnya melihat symlink seperti S01examplescript yang mengarah kembali ke /etc/init.d/examplescript.
Jebakan Kritis
Kesalahan paling umum dengan metode ini adalah menghilangkan blok header LSB. Tanpanya, update-rc.d tidak dapat menentukan urutan dependensi, dan systemd-sysv-generator mungkin menetapkan urutan eksekusi yang salah relatif terhadap ketersediaan jaringan atau mount filesystem. Selalu definisikan dependensi Required-Start secara eksplisit.
Untuk menghapus skrip dari autostart tanpa menghapusnya:
sudo update-rc.d examplescript disableUntuk menghapusnya sepenuhnya:
sudo update-rc.d examplescript removeMetode 2: Menggunakan /etc/rc.local (Shim Kompatibilitas)
Cara Kerjanya
/etc/rc.local adalah mekanisme lama yang menjalankan skrip shell sekali, setelah semua layanan runlevel multi-pengguna standar dimulai. Ini adalah metode autostart paling sederhana — tanpa manajemen layanan, tanpa deklarasi dependensi, tanpa logika restart. Pada Ubuntu 18.04 dan yang lebih baru, dukungan rc.local disediakan oleh unit systemd rc-local.service, yang dinonaktifkan secara default dan harus diaktifkan secara eksplisit.
Kapan Menggunakannya
Gunakan /etc/rc.local hanya untuk:
- Perintah inisialisasi sekali pakai yang tidak perlu dikelola sebagai layanan
- Pembuatan prototipe cepat atau pengujian sebelum memformalkan unit systemd
- Ekspor variabel lingkungan sederhana atau penyesuaian parameter kernel
Jangan gunakan /etc/rc.local untuk daemon yang berjalan lama. Karena berjalan secara blocking dan sekuensial tanpa pengawasan proses, perintah yang macet di rc.local akan menunda atau mencegah selesainya urutan boot.
Implementasi Langkah demi Langkah
Langkah 1: Periksa apakah /etc/rc.local ada
ls -la /etc/rc.localJika tidak ada, buat:
sudo bash -c 'cat > /etc/rc.local << EOF
#!/bin/bash
exit 0
EOF'
sudo chmod +x /etc/rc.localLangkah 2: Aktifkan unit systemd rc-local (Ubuntu 18.04+)
sudo systemctl enable rc-local
sudo systemctl start rc-localLangkah 3: Tambahkan perintah Anda sebelum exit 0
sudo nano /etc/rc.localSisipkan perintah Anda di atas baris exit 0:
#!/bin/bash
/usr/local/bin/examplescript.sh >> /var/log/examplescript.log 2>&1 &
exit 0& di akhir sangat penting untuk perintah yang berjalan lama — ini mem-fork proses ke latar belakang sehingga rc.local tidak memblokir.
Langkah 4: Verifikasi eksekusi
sudo systemctl status rc-localJebakan Kritis
Pada Ubuntu 20.04 dan 22.04, rc-local.service memiliki timeout hardcoded 30 detik. Jika skrip Anda membutuhkan waktu lebih dari 30 detik untuk selesai, systemd akan menandai layanan sebagai gagal dan perintah berikutnya di rc.local tidak akan dieksekusi. Arahkan output dan latar belakangkan proses yang berjalan lama secara eksplisit.
Metode 3: Menggunakan Unit Layanan systemd (Direkomendasikan)
Mengapa systemd Adalah Pendekatan yang Tepat untuk Produksi
systemd bukan sekadar pengganti SysVinit — ini adalah manajer sistem dan sesi lengkap yang menyediakan resolusi dependensi, startup paralel, aktivasi socket dan D-Bus, spawning layanan sesuai permintaan, pengawasan proses dengan restart otomatis, isolasi sumber daya berbasis cgroup, dan agregasi log terstruktur melalui journald. Untuk beban kerja apa pun yang berjalan di Dedicated Server atau VPS produksi, unit systemd adalah satu-satunya mekanisme yang tepat untuk mengelola skrip yang dimuat secara otomatis.
Anatomi File Unit systemd
File unit .service dibagi menjadi tiga bagian wajib:
[Unit]: Metadata, deskripsi yang dapat dibaca manusia, dan deklarasi dependensi (After=,Requires=,Wants=).[Service]: Parameter eksekusi — biner atau skrip yang akan dijalankan, tipe layanan, kebijakan restart, variabel lingkungan, dan opsi sandboxing keamanan.[Install]: Mendefinisikan target systemd mana yang mengaktifkan unit ini (WantedBy=multi-user.targetadalah standar untuk daemon server).
Implementasi Langkah demi Langkah
Langkah 1: Siapkan skrip Anda
Pastikan skrip Anda dapat dieksekusi dan berada di jalur yang stabil:
sudo cp examplescript.sh /usr/local/bin/examplescript.sh
sudo chmod +x /usr/local/bin/examplescript.shLangkah 2: Buat file unit
sudo nano /etc/systemd/system/examplescript.serviceFile unit tingkat produksi dengan penguatan keamanan:
[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.targetLangkah 3: Muat ulang daemon systemd
Setelah membuat atau memodifikasi file unit apa pun, Anda harus memuat ulang indeks konfigurasi daemon:
sudo systemctl daemon-reloadLangkah 4: Aktifkan layanan untuk autostart
sudo systemctl enable examplescript.serviceIni membuat symlink di /etc/systemd/system/multi-user.target.wants/ yang mengarah ke file unit Anda.
Langkah 5: Mulai layanan segera
sudo systemctl start examplescript.serviceLangkah 6: Verifikasi status dan log
sudo systemctl status examplescript.service
sudo journalctl -u examplescript.service -fMemahami Tipe Layanan systemd
Direktif Type= di bagian [Service] adalah salah satu parameter yang paling sering disalahpahami. Memilih tipe yang salah menyebabkan systemd salah melaporkan kesiapan layanan, yang mengakibatkan kegagalan dependensi.
| Tipe | Perilaku | Kasus Penggunaan |
|---|---|---|
simple | Proses yang dimulai oleh ExecStart adalah proses utama. Systemd menganggapnya siap segera. | Skrip dan daemon sederhana yang tidak melakukan fork |
forking | Proses melakukan fork dan induk keluar. Systemd melacak anak melalui file PID. | Daemon Unix tradisional (misalnya, Apache dengan PidFile) |
oneshot | Proses berjalan hingga selesai dan keluar. Systemd menunggu sebelum memulai unit dependen. | Tugas inisialisasi sekali pakai, skrip setup |
notify | Proses memberi sinyal kesiapan melalui sd_notify(). | Daemon dengan integrasi systemd native |
idle | Eksekusi ditunda hingga semua pekerjaan aktif didistribusikan. | Tugas latar belakang berprioritas rendah |
Untuk skrip yang berjalan sekali saat boot dan keluar, gunakan Type=oneshot dengan RemainAfterExit=yes untuk menjaga unit dalam keadaan “aktif” setelah skrip selesai.
Lanjutan: Pengurutan Dependensi dengan After= dan Wants=
Kegagalan produksi yang umum terjadi ketika skrip yang memerlukan konektivitas jaringan dimulai sebelum stack jaringan sepenuhnya diinisialisasi. Rantai dependensi yang benar untuk skrip yang bergantung pada jaringan adalah:
After=network-online.target
Wants=network-online.targetIni berbeda dari After=network.target, yang hanya menjamin bahwa antarmuka jaringan telah dikonfigurasi — bukan bahwa mereka benar-benar online dan dapat dijangkau. Dependensi network-online.target memerlukan systemd-networkd-wait-online.service atau yang setara untuk mengonfirmasi konektivitas.
Perbandingan: Ketiga Metode Sekilas
| Fitur | /etc/init.d/ | /etc/rc.local | Unit systemd |
|---|---|---|---|
| Direkomendasikan untuk produksi | Tidak | Tidak | Ya |
| Dukungan startup paralel | Tidak | Tidak | Ya |
| Pengawasan proses / restart otomatis | Tidak | Tidak | Ya |
| Manajemen dependensi | Terbatas (header LSB) | Tidak ada | Penuh |
| Logging terstruktur | Tidak | Tidak | Ya (journald) |
| Sandboxing keamanan | Tidak | Tidak | Ya |
| Kompleksitas | Rendah | Sangat rendah | Sedang |
| Didukung di Ubuntu 22.04+ | Melalui lapisan kompatibilitas | Melalui rc-local.service | Secara native |
| Cocok untuk daemon yang berjalan lama | Sebagian | Tidak | Ya |
| Cocok untuk tugas init sekali pakai | Ya | Ya | Ya (oneshot) |
Kesalahan Umum dan Cara Menghindarinya
Menjalankan skrip sebagai root tanpa perlu. Direktif User= dan Group= dalam file unit systemd memungkinkan Anda menurunkan hak istimewa. Skrip yang hanya perlu menulis ke /var/log/myapp/ tidak memerlukan root — buat pengguna sistem khusus dan tetapkan kepemilikan direktori sesuai.
Tidak mengalihkan output di rc.local. Tanpa pengalihan output, output echo atau error apa pun dari perintah rc.local pergi ke konsol sistem dan hilang. Selalu tambahkan >> /var/log/yourscript.log 2>&1.
Menggunakan jalur absolut secara tidak konsisten. Layanan systemd berjalan di lingkungan minimal tanpa PATH pengguna. Selalu gunakan jalur absolut untuk setiap biner yang direferensikan dalam ExecStart, termasuk interpreter seperti /usr/bin/python3 atau /bin/bash.
Melupakan daemon-reload setelah mengedit file unit. systemd menyimpan cache konten file unit. Jika Anda mengedit file .service dan tidak menjalankan sudo systemctl daemon-reload, systemd akan terus menggunakan konfigurasi lama.
Menempatkan file unit di /lib/systemd/system/ untuk skrip kustom. Direktori /lib/systemd/system/ dikelola oleh manajer paket. File unit kustom harus berada di /etc/systemd/system/, yang memiliki prioritas lebih tinggi dan bertahan setelah pembaruan paket.
Matriks Keputusan Praktis: Metode Mana yang Digunakan
Gunakan kerangka ini untuk memilih metode yang tepat untuk skenario spesifik Anda:
- Daemon yang berjalan lama yang harus restart saat gagal — unit systemd dengan
Restart=on-failure - Skrip setup sekali pakai yang harus selesai sebelum layanan lain dimulai — unit systemd dengan
Type=oneshotdan dependensiBefore= - Skrip yang memerlukan jaringan sepenuhnya online — unit systemd dengan
After=network-online.target - Perintah satu baris cepat untuk pengujian atau pembuatan prototipe —
/etc/rc.local(sementara) - Aplikasi lama yang dikirimkan dengan skrip init LSB —
/etc/init.d/denganupdate-rc.d - Apa pun yang berjalan di produksi — systemd, selalu
Bagi administrator yang mengelola beberapa server Ubuntu, pertimbangkan untuk memasangkan manajemen unit systemd dengan alat manajemen konfigurasi seperti Ansible, yang dapat menerapkan dan mengaktifkan file .service secara idempoten di seluruh armada Anda. Jika Anda memerlukan lingkungan terkelola dengan akses root penuh untuk mengimplementasikan konfigurasi ini, VPS Hosting dengan VPS Control Panel memberikan fleksibilitas untuk mengelola layanan systemd secara langsung tanpa batasan.
Untuk tim yang menjalankan beban kerja intensif sumber daya yang memerlukan skrip startup untuk menginisialisasi driver GPU, lingkungan CUDA, atau server inferensi ML, lingkungan GPU Hosting sangat diuntungkan dari rantai dependensi After= systemd, memastikan driver sepenuhnya dimuat sebelum layanan aplikasi mencoba mengikat ke sumber daya perangkat keras.
Jika skrip yang dimuat secara otomatis berinteraksi dengan konfigurasi server web atau rutinitas inisialisasi database yang terkait dengan lingkungan control panel, instalasi VPS dengan cPanel memerlukan perhatian ekstra — cPanel mengelola lapisan pengawasan layanannya sendiri, dan unit systemd kustom harus didefinisikan untuk menghindari konflik dengan hook manajemen layanan cPanel.
Daftar Periksa Poin Penting Teknis
Sebelum menerapkan skrip startup apa pun di server Ubuntu, verifikasi hal-hal berikut:
- Lokasi file unit: Skrip kustom masuk ke
/etc/systemd/system/, bukan/lib/systemd/system/ - Bit executable: Konfirmasi dengan
ls -la /path/to/script.sh— bitxharus disetel - Jalur absolut: Setiap biner dalam
ExecStartmenggunakan jalur penuh; tidak bergantung pada$PATH - Deklarasi dependensi:
After=network-online.targetuntuk skrip yang bergantung pada jaringan - Tipe layanan:
Type=simpleuntuk daemon persisten,Type=oneshotuntuk skrip yang berjalan dan keluar - Minimalisasi hak istimewa:
User=,Group=,NoNewPrivileges=true,ProtectSystem=strict - Logging dikonfigurasi:
StandardOutput=journaldanStandardError=journaluntuk integrasijournald - daemon-reload dieksekusi: Selalu jalankan
sudo systemctl daemon-reloadsetelah membuat atau mengedit file unit - Enable vs. start:
enablemembuat symlink autostart;startmenjalankannya segera — keduanya diperlukan - Diuji dengan
journalctl: Konfirmasi eksekusi yang berhasil dengansudo journalctl -u yourservice.service --since "5 minutes ago"
FAQ
Apa perbedaan antara systemctl enable dan systemctl start?
systemctl enable membuat tautan simbolis yang menyebabkan layanan dimulai secara otomatis saat boot berikutnya. systemctl start memulai layanan segera dalam sesi saat ini. Anda biasanya memerlukan kedua perintah saat menyiapkan layanan baru untuk pertama kalinya.
Mengapa layanan systemd saya gagal dengan “executable not found” meskipun skrip ada?
Ini hampir selalu berarti jalur ExecStart salah atau skrip tidak memiliki bit executable. Verifikasi dengan which yourscript dan ls -la /path/to/script. Juga konfirmasi bahwa baris pertama skrip Anda adalah shebang yang valid (#!/bin/bash atau #!/usr/bin/env python3), karena systemd tidak memanggil shell secara default untuk ExecStart.
Bisakah saya menjalankan skrip saat startup hanya sekali, bukan setiap boot?
Gunakan Type=oneshot dengan direktif ConditionPathExists=!/var/run/myscript.done di bagian [Unit]. Skrip membuat file sentinel saat pertama kali dijalankan; boot berikutnya melewati eksekusi karena kondisi gagal.
Apakah /etc/rc.local masih didukung di Ubuntu 22.04?
Ya, tetapi dinonaktifkan secara default. Anda harus mengaktifkan unit rc-local.service secara manual dengan sudo systemctl enable rc-local dan memastikan file ada dan dapat dieksekusi. Ini didukung sebagai langkah kompatibilitas, bukan praktik yang direkomendasikan.
Bagaimana cara memeriksa mengapa skrip startup gagal dijalankan?
Jalankan sudo journalctl -u yourservice.service -b untuk melihat semua entri log untuk unit tersebut sejak boot terakhir. Untuk kegagalan rc.local, periksa sudo systemctl status rc-local.service dan tinjau /var/log/syslog untuk entri yang dicap waktu selama urutan boot.
