Home / Linux, Systems, and Infrastructure / Memahami Unit …

Memahami Unit Systemd: Service dan Timer untuk Mengelola Layanan

Di balik perintah systemctl start yang tampak sederhana, systemd mengelola setiap layanan sebagai sebuah unit: berkas teks yang menentukan cara proses dijalankan, kapan mulai, dan bagaimana sistem memulihkannya bila gagal. Banyak pengguna Linux menyalin unit dari tutorial tanpa memahami isinya, lalu bingung ketika layanan tidak ikut menyala saat boot. Artikel ini membedah struktur unit systemd dengan contoh yang telah diuji pada Ubuntu 26.04.1 LTS (systemd 259), serta cara validasi yang tidak mengubah sistem sama sekali.

Ringkasan

  • Unit systemd adalah berkas teks tiga bagian: [Unit], tipe unit, dan [Install].
  • Type=oneshot untuk tugas sekali jalan; Type=exec untuk proses jangka panjang.
  • systemctl enable membuat symlink; tanpa enable, unit tidak ikut boot.
  • Setiap perubahan unit wajib diikuti systemctl daemon-reload.
  • Timer OnCalendar= menjadwalkan unit lain tanpa perlu cron.

Apa Itu Unit Systemd?

Systemd adalah sistem init modern yang dipakai hampir semua distro besar, dan situs resminya mendokumentasikan desainnya di systemd.io. Segala sesuatu yang dikelola systemd direpresentasikan sebagai unit: berkas INI berisi instruksi untuk menjalankan, menghentikan, dan mengkategorikan sebuah elemen sistem. Jenis unit yang umum terlihat dalam tabel berikut.

Jenis unitEkstensiGunanya
service.serviceMenjalankan dan mengawasi sebuah proses atau daemon
timer.timerMenjadwalkan unit lain dengan kalender atau interval
socket.socketMendengarkan port dan menunda aktivasi hingga ada koneksi
mount / automount.mount, .automountMengelola titik mount berkas sistem
path.pathMemicu unit saat sebuah berkas berubah
slice.sliceMengelompokkan unit untuk pembagian sumber daya (cgroup)
target.targetGrup logis unit, misalnya multi-user.target

Unit dicari dari direktori dengan urutan prioritas tertentu, sebagaimana dijelaskan di dokumentasi systemd.unit. Direktori admin selalu menang atas direktori vendor:

PrioritasDirektoriAsal
Tertinggi/etc/systemd/systemBuatan administrator
Menengah/run/systemd/systemHasil runtime (transien)
Rendah/usr/lib/systemd/systemDisertakan oleh paket distribusi

Bila nama berkas sama di dua direktori, versi yang lebih tinggi menang. Fragment drop-in *.d/*.conf dapat menambah atau menimpa kunci tanpa menyentuh berkas utama, trik yang rapi untuk kustomisasi kecil.

Anatomi Berkas Unit

Sebuah unit modern terdiri dari tiga bagian: [Unit] untuk metadata dan dependensi, bagian tipe sesuai akhiran berkas, serta [Install] untuk kebijakan saat enable.

Bagian [Unit]: Metadata dan Dependensi

Bagian [Unit] paling sering memuat tiga macam kunci: deskripsi, dokumentasi, dan relasi antarunit.

KunciArti
Description=Kalimat yang tampil di systemctl status
Documentation=Lokasi dokumentasi (man page atau URL)
After= / Before=Mengatur urutan mulai, tanpa memuat unit lain
Wants=Memuat unit lain secara lunak; kegagalannya tidak fatal
Requires=Memuat unit lain secara keras; kegagalannya ikut menggagalkan
Condition...=Menolak memulai bila syarat tidak terpenuhi

Poin yang tak pernah berhenti membingungkan: After= hanya menyusun antrean, ia tidak menarik unit yang disebut masuk ke dalam sesi boot. Agar unit lain ikut dimuat, gunakan Wants= atau Requires=. Requires= bersifat keras, sementara man page menyarankan Wants= bila tujuan Anda hanyalah “sebaiknya ada, bukan wajib”.

Bagian [Service]: Bagaimana Proses Dijalankan

Untuk unit .service, kunci terpenting adalah Type=, sebab ia menentukan kapan systemd menganggap unit sudah “aktif”. Nilai yang umum dijelaskan oleh dokumentasi systemd.service.

TypeKapan dianggap aktifCocok untuk
simpleBegitu proses bercabangDefault bila Type= tidak ditulis
execBegitu proses berhasil dieksekusiProses jangka panjang yang disarankan
forkingProses induk keluar, anak menjadi utamaDaemon gaya lama (daemonize)
oneshotSemua perintah selesaiTugas sekali jalan, misalnya backup
notifyProses mengirim READY=1Program yang digabung dengan systemd
dbusNama bus tersediaLayanan yang memakai D-Bus

Type=oneshot perlu ditemani RemainAfterExit=yes; tanpa itu, unit yang sudah selesai berjalan langsung berstatus inactive (dead) meski berhasil, dan orang mengiranya gagal. Aturan ExecStart= juga khas: argumen pertama wajib berkas absolut, tanpa interpretasi shell, tanda &&, ~, maupun ekspansi variabel. Awali dengan - bila kegagalan keluarannya boleh diabaikan.

Sistem tempat artikel ini ditulis memakai berkas cron.service bawaan Ubuntu sebagai contoh nyata yang sah:

ini
# /usr/lib/systemd/system/cron.service
[Unit]
Description=Regular background program processing daemon
After=remote-fs.target nss-user-lookup.target

[Service]
EnvironmentFile=-/etc/default/cron
ExecStart=/usr/sbin/cron -f -P $EXTRA_OPTS
Restart=on-failure

[Install]
WantedBy=multi-user.target

Dua hal menarik di sana: systemd menjalankan cron dengan -f agar tetap di depan, sehingga Type= standar cocok; Restart=on-failure meminta systemd menghidupkan lagi proses bila berhenti abnormal. Contoh buatan yang menyertai artikel ini, demo-long.service, menjalankan sleeper dengan Type=exec dan RestartSec=5s, dan tersedia di bawah untuk direnungkan.

ini
[Unit]
Description=Layanan yang berjalan terus menerus
After=network.target

[Service]
Type=exec
ExecStart=/usr/bin/sleep infinity
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target

Bagian [Install]: Kapan Unit Ikut Boot

Bagian ini baru berlaku saat systemctl enable dijalankan: systemd membaca WantedBy= dan membuat symlink berkas unit ke direktori <target>.wants/. Dengan begitu, unit dimuat setiap kali target itu tercapai, misalnya multi-user.target saat sistem menyala penuh.

Konsekuensi yang sering salah duga: systemctl start menghidupkan unit hanya untuk sesi ini, sedangkan systemctl enable menautkannya ke boot. Keduanya bisa digabung dengan systemctl enable --now bila ingin sekaligus.

Perintah yang Sering Dipakai

Tabel berikut merangkum operasi systemctl yang paling harian.

PerintahFungsi
systemctl start/stop/restart <unit>Mengubah status saat ini
systemctl enable/disable <unit>Menautkan / melepas unit dari boot
systemctl mask/unmask <unit>Melarang unit dijalankan oleh apa pun
systemctl daemon-reloadMembaca ulang unit setelah berkas diubah
systemctl status <unit>Ringkasan status, PID, dan log terakhir
systemctl cat <unit>Menampilkan isi unit beserta override
systemctl is-enabled <unit>Memeriksa status enable
systemctl list-units / list-unit-filesMendaftar unit aktif / semua unit

Sebagian besar perintah di atas butuh hak root kecuali untuk unit --user. Bila merasa baru saja mengubah berkas unit dan tidak ada efeknya, jalankan daemon-reload dulu, penyebab nomor satu unit tidak mengenali perubahan.

Timer: Menjadwalkan tanpa Cron

Unit .timer menambahkan penjadwalan berbasis kalender atau interval langsung dari systemd, mengikuti aturan pada dokumentasi systemd.timer. Secara bawaan, foo.timer membangunkan foo.service; untuk unit lain gunakan Unit=.

KunciMenjadwalkan berdasarkan
OnCalendar=Ekspresi kalender, misal *-*-* 02:00:00 setiap pukul 02.00
OnBootSec=Detik sejak sistem dinyalakan
OnUnitActiveSec=Detik sejak unit terakhir kali aktif
Persistent=trueMenjalankan event yang terlewat (hanya untuk OnCalendar)

Timer Ubuntu untuk anacron, yang ikut dipakai menulis artikel ini, menunjukkan kombinasi kalender yang elegan. OnCalendar=*-*-* 07..23:30 membangunkan anacron paling cepat setiap jam mulai 07.30 hingga 23.30, dan RandomizedDelaySec=5m membuat jadwalnya tidak serempak dengan host lain. Nilai AccuracySec= default adalah satu menit, dan Persistent=true memastikan event yang terlewat ketika mesin mati tetap dikejar begitu mesin hidup.

Pasangan timer buatan yang tervalidasi pada artikel ini terlihat seperti ini.

ini
# demo.timer -> membangunkan demo.service
[Unit]
Description=Jadwal ulang demo setiap hari pukul 02:00

[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true

[Install]
WantedBy=timers.target

Jangan lupa systemctl enable --now demo.timer dan periksa dengan systemctl list-timers, yang menampilkan waktu berikutnya sekaligus waktu terakhir: misalnya dpkg-db-backup.timer pada mesin ini akan terbangun Jumat 00.00 untuk dpkg-db-backup.service.

Validasi tanpa Mengubah Sistem

Dua perintah berikut aman dijalankan kapan saja dan tidak menyentuh state sistem: systemd-analyze verify memeriksa sintaks dan kewajaran berkas unit, dan systemctl cat menampilkan unit yang sedang berlaku. Ketiga contoh unit untuk artikel ini (dua service dan satu timer) diuji dengan:

bash
systemd-analyze verify /tmp/contoh/demo.service /tmp/contoh/demo.timer /tmp/contoh/demo-long.service

Perintah itu selesai tanpa keluaran dan berstatus nol, artinya ketiganya sah. Bila ada yang cacat, systemd menyebut masalah persis per baris. Untuk menelusuri perilaku unit yang sudah berjalan, systemctl status <unit> memadukan status, PID, dan potongan log, sementara journalctl -u <unit> menampilkan log lengkap unit itu.

Kesalahan Umum

Sebagian besar “misteri” systemd di lapangan berasal dari pola berikut.

  • Lupa daemon-reload setelah mengubah berkas unit.
  • ExecStart= memakai path relatif atau operator shell, padahal harus path absolut.
  • Type=oneshot tanpa RemainAfterExit=yes, sehingga unit berstatus dead padahal selesai.
  • WantedBy= dicantumkan tapi systemctl enable tidak dijalankan, jadi unit tidak ikut boot.
  • Mengira start bertahan setelah reboot; padahal yang bertahan hanya enable.

Penutup

Unit systemd tidaklah serumit penampakannya: tiga bagian, sekumpulan kunci kecil, dan dua perintah yang mengikatnya ke boot. Pahami dulu Type=, After= lawan Wants=, serta kebiasaan daemon-reload, dan sebagian besar layanan yang “tidak mau hidup” akan bisa dijelaskan dalam beberapa menit. Timer menjadikan penjadwalan tanpa cron menjadi lebih mudah dibaca, dan systemd-analyze verify memberi jaringan pengaman sebelum unit benar-benar dipicu.