systemd adalah program pertama yang jalan saat server Linux menyala (Ubuntu, Debian, Fedora, dan hampir semua distro modern), dan dia yang mengurus program lain yang harus selalu hidup, yang disebut service. Mirip satpam gedung yang memegang daftar tugas: nyalakan lift tiap pagi, kalau lift mati nyalakan lagi, dan catat semua kejadian di buku log. Daftar tugas untuk satu service itu namanya unit file.
🧪 Tebakan cepat: kamu mengganti
Restart=nojadiRestart=on-failuredi unit file, menyimpannya, lalu app-mu crash. Apakah systemd menyalakannya lagi? Tebak dulu, jawabannya ada di bagian "daemon-reload: systemd membaca ulang unit file".
Unit file: aturan untuk satu service
Unit file ditulis dalam format INI: nama section di dalam kurung siku, lalu baris-baris key=value. Ini unit file app Node di Lab:
# /etc/systemd/system/myapp.service
[Unit]
Description=My App
After=network.target
[Service]
User=deploy
WorkingDirectory=/srv/myapp
ExecStart=/usr/bin/node server.js
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
[Unit]: keterangan dan hubungan dengan unit lain.After=network.targetcuma mengatur urutan: start setelah jaringan siap.Requires=lebih keras: unit yang disebut ikut dinyalakan, dan kalau unit itu dimatikan, service ini ikut mati. Biasanya ditulis berpasangan,Requires=plusAfter=.[Service]: cara menjalankannya.User=deploysupaya gak jalan sebagai root,ExecStart=perintahnya dengan path lengkap,Restart=danRestartSec=5untuk restart otomatis lima detik setelah berhenti.[Install]: dipakai olehsystemctl enable.WantedBy=multi-user.targetartinya "nyalakan saat server boot seperti biasa".
systemctl: menyalakan, mematikan, mengecek
sudo systemctl start myapp # nyalakan sekarang
sudo systemctl stop myapp # matikan
sudo systemctl restart myapp # matikan lalu nyalakan, misalnya setelah deploy kode baru
sudo systemctl enable myapp # ikut nyala setiap server boot
sudo systemctl disable myapp # gak ikut nyala saat boot lagi
systemctl status myapp # keadaan sekarang dan log terakhirnya
start, stop, dan restart gak mencetak apa-apa kalau berhasil. enable mencetak symlink yang dibuatnya:
$ sudo systemctl enable myapp
Created symlink /etc/systemd/system/multi-user.target.wants/myapp.service → /etc/systemd/system/myapp.service.
$ sudo systemctl start myapp
$ systemctl status myapp
● myapp.service - My App
Loaded: loaded (/etc/systemd/system/myapp.service; enabled; preset: enabled)
Active: active (running) since Thu 2026-10-08 14:37:06 WIB; 3s ago
Main PID: 4821 (node)
Tasks: 7 (limit: 2274)
Memory: 38.2M (peak: 38.6M)
CPU: 412ms
CGroup: /system.slice/myapp.service
└─4821 /usr/bin/node server.js
Oct 08 14:37:06 web-1 systemd[1]: Started myapp.service - My App.
Oct 08 14:37:06 web-1 node[4821]: Server jalan di port 3000
start= nyalakan sekarang.enable= nyalakan setiap boot. Dua hal berbeda;sudo systemctl enable --now myappmelakukan dua-duanya.- Baris
Active:paling penting:active (running),inactive (dead), ataufailed. Titik di depan ikut berubah:●jalan,○mati,×gagal.
Restart=: apa yang terjadi kalau app berhenti
Restart= |
Keluar normal (exit 0) | Crash atau exit selain 0 | Dimatikan dengan systemctl stop |
|---|---|---|---|
no (bawaan) |
gak restart | gak restart | gak restart |
on-failure |
gak restart | restart | gak restart |
always |
restart | restart | gak restart |
on-success |
restart | gak restart | gak restart |
systemctl stop gak pernah memicu restart, termasuk dengan always: systemd tahu kamu yang mematikannya. Untuk server HTTP, on-failure paling umum: crash dibangkitkan lagi, keluar normal dibiarkan. Ini log saat app crash dengan Restart=on-failure dan RestartSec=5:
Oct 08 14:38:10 web-1 node[4821]: Database gagal tersambung, keluar dengan exit code 1
Oct 08 14:38:10 web-1 systemd[1]: myapp.service: Main process exited, code=exited, status=1/FAILURE
Oct 08 14:38:10 web-1 systemd[1]: myapp.service: Failed with result 'exit-code'.
Oct 08 14:38:15 web-1 systemd[1]: myapp.service: Scheduled restart job, restart counter is at 1.
Oct 08 14:38:15 web-1 systemd[1]: Started myapp.service - My App.
daemon-reload: systemd membaca ulang unit file
systemd membaca unit file sekali, lalu memakai salinan yang sudah dimuat itu. Mengedit file-nya saja belum mengubah apa-apa. Jadi kalau kamu mengganti Restart=no jadi Restart=on-failure lalu app crash, systemd masih memakai Restart=no, dan app-nya tetap mati. Itu jawaban tebakannya. Setiap habis mengedit, jalankan:
sudo systemctl daemon-reload
Kalau lupa, systemctl mengingatkanmu:
Warning: The unit file, source configuration file or drop-ins of myapp.service changed on disk. Run 'systemctl daemon-reload' to reload units.
journalctl: membaca log service
Semua yang dicetak service ke stdout dan stderr dikumpulkan systemd di journal, jadi kamu gak perlu file log sendiri:
journalctl -u myapp # semua log myapp
journalctl -u myapp -f # ikuti log secara live, seperti tail -f
journalctl -u myapp -n 50 # 50 baris terakhir
journalctl -u myapp -b # sejak boot terakhir
Di latihan: membaca unit file dengan JavaScript
parseUnitFile membaca unit file baris per baris: baris [Unit] membuka section Unit, dan baris key=value masuk ke section yang sedang terbuka. Pecah di tanda = yang pertama saja:
const line = "ExecStart=/usr/bin/node server.js";
const eq = line.indexOf("=");
console.log(line.slice(0, eq)); // ExecStart
console.log(line.slice(eq + 1)); // /usr/bin/node server.js
indexOf("=")mencari tanda=pertama.split("=")akan memotong juga value sepertiEnvironment=NODE_ENV=production.describeRestartPolicymemetakan policy ke deskripsi:on-failurejadiRestart jika exit gagal,alwaysjadiSelalu restart,on-successjadiRestart jika exit sukses, dan yang lain jadiPolicy tidak dikenal.
⚠️ Jebakan yang sering ketemu
- Lupa
daemon-reload. Unit file yang diedit gak berlaku sampai systemd membacanya ulang. Perhatikan peringatanchanged on disk. - Mengira
startsama denganenable. Service yang cuma di-startgak ikut nyala setelah reboot. ExecStarttanpa path lengkap. systemd gak membacaPATHmilikmu, jadi Node yang dipasang lewat nvm di folder home gak ketemu. Cek path-nya denganwhich node, lalu tulis lengkap.- Lupa
User=. Tanpa itu service jalan sebagai root, jadi celah keamanan di app-mu langsung jadi akses root.
TL;DR: systemd menjalankan dan menjaga service sesuai unit file: [Unit] (Description, After untuk urutan, Requires untuk ketergantungan keras), [Service] (User, ExecStart dengan path lengkap, Restart), [Install] (WantedBy untuk enable). systemctl start/stop/restart mengatur sekarang, enable mengatur saat boot, status menunjukkan keadaan dan log terakhir. Restart=on-failure membangkitkan app yang crash, always juga setelah keluar normal, dan systemctl stop gak pernah memicu restart. Setelah mengedit unit file, wajib sudo systemctl daemon-reload. Log live: journalctl -u myapp -f.