Aplikasi web butuh database, database butuh penyimpanan, dan semuanya butuh jaringan — tidak ada service yang benar-benar hidup sendirian. Pada init klasik urutan ini diatur dengan angka pada nama script; systemd menggantinya dengan deklarasi dependensi langsung di unit file. Kita sudah melihat sepenggal Requires=dbus.socket di Chapter systemd Units ; sekarang saatnya membedahnya penuh. Kuncinya satu: systemd memisahkan dua pertanyaan yang berbeda — apa yang ikut dinyalakan dan siapa yang menyala lebih dulu — dan keduanya punya directive masing-masing.

Dua Pertanyaan Berbeda: Menarik dan Mengurutkan #

Directive dependensi terbagi dua keluarga. Keluarga requirement menjawab: bila unit A dinyalakan, unit mana yang ikut ditarik? Keluarga ordering menjawab: bila A dan B sama-sama dinyalakan, mana yang lebih dulu? Keduanya independen — directive requirement tidak mengatur urutan, directive ordering tidak menarik apa pun.

Wants dan Requires: Relasi Lunak dan Keras #

Dua directive requirement yang paling sering dipakai, dengan konsekuensi gagal yang berbeda:

DirectiveBila target ikut ditarik dan gagalBila target dihentikan eksplisit
Wants=unit pengingat tetap berjalanunit pengingat tetap berjalan
Requires=unit pengingat ikut gagal startunit pengingat ikut dihentikan

Wants= adalah hubungan longgar: “coba nyalakan itu, tapi tidak apa-apa bila gagal”. Requires= adalah hubungan keras: “tanpa itu, saya menolak hidup”. Praktik umum: Wants untuk dependensi yang tidak fatal — misalnya sinkronisasi waktu — dan Requires untuk yang wajib. Mari kita lihat keduanya dalam satu unit:

bash
cat > webapp.service << 'EOF'
[Unit]
Description=Aplikasi web yang butuh jaringan
Wants=network-online.target
Requires=network.target
After=network.target network-online.target

[Service]
ExecStart=/usr/bin/python3 -m http.server 8080

[Install]
WantedBy=multi-user.target
EOF
systemd-analyze verify webapp.service && echo "sintaks unit valid"

Output yang Dihasilkan:

text
sintaks unit valid

Mari kita telaah blok di atas:

  1. Baris 3-4 (Wants= dan Requires=): saat webapp.service dinyalakan, kedua target jaringan ikut ditarik. Bila network-online.target gagal, webapp tetap jalan; bila network.target gagal, webapp ikut gagal — aplikasi web tanpa jaringan memang tidak masuk akal.
  2. Baris 5 (After=): hanya mengurutkan — webapp menunggu kedua target selesai dinyalakan lebih dulu. Baris ini tidak menarik apa pun; tugas menarik sudah dipegang baris 3-4.
  3. Baris 11 (WantedBy=multi-user.target): kebalikan dari kedua directive di atas — bukan webapp yang menarik, melainkan webapp yang menawarkan diri ditarik oleh target saat boot.

After dan Before: Urutan, Bukan Dependensi #

Poin baris 5 layak ditegaskan terpisah karena inilah salah kaprah paling umum pemula systemd:

Unit bawaan sistem adalah contoh terbaik pola “pasangan Wants + After” — misalnya service manajemen login:

bash
grep -E '^(Wants|After)=' /lib/systemd/system/systemd-logind.service

Output yang Dihasilkan:

text
Wants=user.slice [email protected]
After=nss-user-lookup.target user.slice [email protected]
Wants=dbus.socket
After=dbus.socket

Empat baris itu adalah dua pasangan. Pasangan pertama menarik user.slice dan driver grafis, lalu After= berisi sama memastikan keduanya siap lebih dulu; pasangan kedua, Wants=dbus.socket plus After=dbus.socket, adalah pola idiomatik yang sering kita temui: nyalakan dependensinya, lalu tunggu sampai benar-benar siap.

BindsTo, PartOf, dan Conflicts #

Tiga directive lain melengkapi kasus khusus. BindsTo= versi paling keras dari Requires: unit ini ikut mati begitu targetnya berhenti karena alasan apa pun. PartOf= menularkan perubahan: target di-restart atau di-stop, unit yang menyatakan PartOf ikut — dipakai agar container ikut bangkit saat engine-nya di-restart. Conflicts= hubungan bermusuhan: unit ini dan targetnya tidak boleh aktif bersamaan. Rangkaian directive lengkapnya dengan contoh sintaks dirangkum di systemd.unit(5) .

Target: Kumpulan yang Menarik Anggotanya #

Semua relasi di atas bertemu pada satu jenis unit: target. Target tidak menjalankan proses apa pun — isinya murni deklarasi dependensi, titik temu tempat puluhan unit mengikat diri. Perhatikan isi multi-user.target, target utama mode teks pada server:

bash
grep -v '^#' /lib/systemd/system/multi-user.target | grep -v '^$'

Output yang Dihasilkan:

text
[Unit]
Description=Multi-User System
Documentation=man:systemd.special(7)
Requires=basic.target
Conflicts=rescue.service rescue.target
After=basic.target rescue.service rescue.target
AllowIsolate=yes

Mari kita baca isinya:

  1. Requires=basic.target + After=basic.target: pola Wants-plus-After yang sama, kini dipakai target sendiri — multi-user menarik fondasi sistem lalu menunggunya.
  2. Conflicts=rescue.service rescue.target: mode multi-user dan mode penyelamatan saling meniadakan — inilah yang menjalankan pergantian mode saat systemctl isolate dari Chapter systemctl .
  3. AllowIsolate=yes: izin agar target ini boleh dijadikan tujuan isolate — mematikan semua unit di luar rantainya.
  4. Tidak ada section [Service]: bukti bahwa target memang murni deklarasi — tidak ada proses yang dijalankan.

Anggota target datang dari dua arah: ditarik oleh Requires/Wants, atau menawarkan diri lewat WantedBy — mekanisme symlink .wants dari Chapter Managing Services .

Transaksi: Perubahan yang Atomik #

Saat kita menjalankan systemctl start webapp.service, systemd tidak bekerja satu-satu. systemd menyusun transaction: kumpulan job untuk semua unit yang ditarik, dicek siklus urutannya, lalu dieksekusi sebagai satu kesatuan. Bila ditemukan masalah — misalnya dua unit saling menunggu lewat After= yang berlawanan arah — perintah ditolak dengan pesan ordering cycle found dan tidak ada job yang berjalan. Desain atomik ini menjaga sistem tidak setengah jalan: lebih baik menolak perintah daripada membiarkan service menyala dengan dependensi yang tidak jelas.

Peta dependensi kita tinggal satu yang belum dijelajahi: target sebagai pengganti runlevel klasik — bedanya multi-user dan graphical, dan cara default target ditentukan saat boot. Itulah topik Chapter systemd Targets .