Layanan systemd yang tidak mau berjalan hampir tidak pernah misterius. Jalankan systemctl status <unit>, lalu baca 50 baris journal terakhir untuk unit itu dengan journalctl -u <unit> -n 50 --no-pager — dari keduanya, satu dari lima penyebab biasanya sudah disebutkan langsung: path yang salah, binary yang hilang, izin yang keliru, penolakan SELinux/AppArmor, atau galat sintaks unit file. Alasan kegagalannya ada di log; perbaikan-perbaikan di bawah hanyalah pencocokan pola terhadap log itu.
Bagaimana melihat kenapa layanan systemd gagal?
Status dulu, journal kemudian:
systemctl status myapp.service
journalctl -u myapp.service -n 50 --no-pager status memberi Anda kondisi (inactive (dead), failed (exit-code), activating (auto-restart)) dan beberapa baris log terakhir. Journal memberi Anda keseluruhan cerita: stdout, stderr, dan keluhan systemd sendiri tentang unit itu.
Jika unit pernah gagal sebelumnya dan Anda ingin rekaman run itu, tambahkan -b untuk boot saat ini atau --since today:
journalctl -u myapp.service -b --no-pager Untuk perangkat lengkapnya — boot, prioritas, mengikuti output secara live — lihat memo journalctl. Memori ototnya sama.
Satu pasang lagi yang layak diketahui:
systemctl list-units --failed
systemctl reset-failed myapp.service Yang pertama mendaftar setiap unit merah di mesin. Yang kedua membersihkan status failed setelah Anda memperbaikinya — kosmetik, tetapi mencegah halaman status berteriak serigala.
Apa saja penyebab yang paling umum?
Setelah log menyebutkan gejalanya, penyebabnya hampir selalu salah satu dari lima ini:
| Kata log | Penyebab yang mungkin | Perbaikan |
|---|---|---|
status=203/EXEC | Path ExecStart= salah atau interpreter hilang | Path absolut, chmod +x, periksa shebang |
status=203/EXEC pada skrip | Skrip berakhiran baris CRLF atau shebang salah | dos2unix script.sh, perbaiki baris pertama |
status=1/FAILURE, tanpa log aplikasi | Working directory atau env var hilang | Set WorkingDirectory=, tambah Environment= |
Permission denied | Pengguna tak bisa membaca file atau bind port | Perbaiki kepemilikan; port di bawah 1024 butuh AmbientCapabilities=CAP_NET_BIND_SERVICE atau root |
Unit is masked | Seseorang menjalankan systemctl mask | systemctl unmask myapp.service |
| Edit unit file “tidak berefek” | Daemon tidak di-reload | systemctl daemon-reload |
Keluarga 203/EXEC layak disebut khusus karena dialah yang memakan sore Anda. Systemd tidak memakai shell Anda untuk menjalankan ExecStart=. Artinya:
# Salah — tanpa shell, ~ tidak pernah mengembang, tanpa pencarian PATH
ExecStart=~/app/run.sh
# Benar
ExecStart=/opt/app/run.sh Dan skripnya sendiri harus executable dan diawali shebang sungguhan (#!/bin/bash atau #!/usr/bin/env bash). Skrip yang jalan mulus dari terminal Anda tetapi gagal dengan 203 di bawah systemd hampir selalu salah satu dari: tidak executable, akhiran baris CRLF, shebang yang menunjuk ke tempat tak ada, atau path relatif.
Kenapa bisa jalan saat dijalankan manual tetapi tidak saat boot?
Ini bug urutan klasik. Jika log menunjukkan kegagalan tepat setelah boot tetapi unitnya jalan mulus saat Anda menjalankan systemctl start dengan tangan, layanan Anda kalah balapan — ia mengincar jaringan, disk yang di-mount, atau database sebelum hal itu ada.
Perbaikannya adalah mendeklarasikan dependensi alih-alih berharap:
[Unit]
After=network-online.target postgresql.service
Wants=network-online.target
[Service]
ExecStartPre=/usr/bin/test -f /opt/app/config.toml After= mengurutkan start; Wants= membuat systemd benar-benar menaikkan dependensinya. network-online.target hanya bekerja jika service network-wait diaktifkan di distro Anda, jadi periksa systemctl is-enabled NetworkManager-wait-online.service (atau padanan systemd-networkd). Gerbang ExecStartPre= adalah cara yang murah dan jujur untuk gagal dengan lantang beserta pesan yang terbaca, bukan stack trace.
Varian keduanya: service jalan saat boot tetapi langsung mati. Cari hal-hal yang dimiliki lingkungan interaktif Anda tetapi tidak dimiliki boot — perbedaan PATH, virtualenv, HOME. Set yang Anda butuhkan secara eksplisit:
[Service]
Environment="PATH=/opt/app/venv/bin:/usr/bin"
User=appuser
WorkingDirectory=/opt/app Kenapa layanan saya tidak mencatat log ke journal?
Jika journalctl -u tidak menampilkan apa pun, periksa tiga hal secara berurutan:
StandardOutput=danStandardError=di unit — keduanya harusjournal(default) ataujournal+console. Bisa jadi seseorang menyetelnya kenull.- Aplikasi menulis ke file, bukan ke stdout. Systemd hanya menangkap stdout/stderr; penulis log-file melewati journal sepenuhnya. Arahkan aplikasinya ke stdout, atau bacalah filenya.
- Batas penyimpanan membuang baris lama:
journalctl --disk-usage, danSystemMaxUse=di/etc/systemd/journald.confjika journal sedang tersedak.
Untuk debug proses start-nya sendiri, tak ada yang mengalahkan menjatuhkan shell ke dalam konteks boot:
[Service]
ExecStart=/bin/bash -c 'exec /opt/app/bin/server 2>&1' Atau, untuk misteri yang sesungguhnya, jalankan perintah ExecStart= persisnya sebagai pengguna unit tersebut di dalam shell — sebagian besar perbedaan lingkungan muncul dalam sepuluh detik pertama.
Bagaimana membuatnya restart otomatis setelah crash?
Kebijakan defaultnya Restart=no: service yang crash tetap mati, dan Anda mengetahuinya dari seorang pengguna. Perbaiki per service:
[Service]
Restart=on-failure
RestartSec=5 | Setelan | Restart saat |
|---|---|
no (default) | Tidak pernah |
on-failure | Exit non-nol, signal, timeout |
always | Exit apa pun, bahkan yang bersih |
on-watchdog | Hanya timeout watchdog |
Padukan Restart=on-failure dengan penjaga laju start agar loop crash tidak menghantam mesin: StartLimitIntervalSec= dan StartLimitBurst= di bagian [Unit]. Lima kegagalan dalam enam puluh detik seharusnya memanggil manusia, bukan memutar CPU.
Jika Anda merangkai ini sebagai job terjadwal alih-alih daemon, timbang dulu cron vs timer systemd — timer memberi Anda logging journal dan pengurutan dependensi secara gratis, dan justru itulah yang terus dicari-cari artikel ini.
Checklist 60 detik
systemctl status <unit>— baca kondisi dan baris-baris terakhir.journalctl -u <unit> -n 50 --no-pager— temukan error yang sebenarnya.203/EXEC? Perbaiki path, shebang, izin.Permission denied? Perbaiki pengguna dan kepemilikan file.- Gagal hanya saat boot? Tambahkan
After=/Wants=network-online.targetdan gerbangExecStartPre=. - Mengubah unit file?
systemctl daemon-reload && systemctl restart <unit>. - Tambahkan
Restart=on-failureagar crash berikutnya mengumumkan dirinya alih-alih bersembunyi.
Sebagian besar momen “systemd itu rumit” berujung pada satu hal: errornya dari awal memang ada di journal. Bacalah sebelum mengedit unit file, bukan sesudahnya.
— mrsaynothing
Get the next one by email
One email per post. No spam, no algorithms.
what is this?Kuantisasi GGUF: Level Mana yang Harus Anda Pakai?
Suka tulisannya? Saya membangun seperti ini untuk hidup. pekerjakan saya