Halo, Rekan ArtonLabs. systemd adalah bagian Linux yang kita pakai setiap hari tanpa benar-benar mempelajarinya, dan tulisan ini mencoba membayar utang itu.
Setiap aplikasi yang kami jalankan di server pada akhirnya menjadi unit systemd: Gunicorn, Django-Q, Ollama, bahkan skrip kecil yang harus selalu hidup. systemd adalah bagian Linux yang paling sering dipakai dan paling jarang dipelajari dengan benar. Tulisan ini membahas yang benar-benar Anda butuhkan: menulis unit, membaca log, mengatur restart, menyunting unit tanpa merusaknya, dan menjalankan tugas berkala tanpa cron.
Daftar Isi
- Anatomi Sebuah Unit
- Perintah Dasar systemctl
- Membaca Log dengan journalctl
- Restart Otomatis dan Batasnya
- Menyunting Unit dengan Drop-in
- Timer sebagai Pengganti Cron
- Pembatasan Keamanan di Unit
- Penutup
Anatomi Sebuah Unit
# /etc/systemd/system/pemantau.service
[Unit]
Description=Pemantau antrean
After=network-online.target postgresql.service
Wants=network-online.target
[Service]
Type=simple
User=webapp
WorkingDirectory=/home/webapp/pemantau
EnvironmentFile=/home/webapp/pemantau/.env
ExecStart=/home/webapp/pemantau/.venv/bin/python pemantau.py
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
Tiga bagian. [Unit] menjelaskan dan mengatur urutan: After menyatakan "mulai setelah", Wants menyatakan "usahakan yang itu juga hidup". [Service] menyatakan apa yang dijalankan, sebagai siapa, di mana. [Install] menentukan kapan unit ini diaktifkan saat boot; multi-user.target berarti boot normal tanpa tampilan grafis. Type=simple cocok untuk proses yang tetap di latar depan; kebanyakan aplikasi modern seperti itu.
Perintah Dasar systemctl
sudo systemctl daemon-reload # setelah mengubah berkas unit
sudo systemctl enable --now pemantau # aktifkan saat boot dan jalankan sekarang
sudo systemctl status pemantau
sudo systemctl restart pemantau
sudo systemctl stop pemantau
systemctl list-units --type=service --state=running
daemon-reload adalah langkah yang paling sering terlupa: mengubah berkas unit tidak berpengaruh sampai systemd diminta membacanya ulang. status menampilkan beberapa baris log terakhir, dan itu sering sudah cukup untuk tahu kenapa sesuatu gagal.
Membaca Log dengan journalctl
journalctl -u pemantau -f # ikuti langsung
journalctl -u pemantau --since "1 hour ago"
journalctl -u pemantau -p err --since today # hanya galat
journalctl -u pemantau -n 200 --no-pager
journalctl --disk-usage
Keluaran standar dan galat proses Anda masuk ke journal secara otomatis, jadi aplikasi tidak perlu menulis berkas log sendiri kalau tidak mau. Untuk membatasi ukuran journal, atur SystemMaxUse=500M di /etc/systemd/journald.conf; di VPS kecil, journal yang tidak dibatasi bisa diam-diam memakan gigabyte. Kalau aplikasi menulis berkas log sendiri seperti Gunicorn, tetap pakai logrotate, dan gunakan copytruncate agar berkas tidak dibuat ulang dengan pemilik yang salah.
Restart Otomatis dan Batasnya
Restart=on-failure menghidupkan ulang proses yang keluar dengan kode galat; Restart=always menghidupkan ulang apa pun alasannya, cocok untuk pekerja antrean. RestartSec memberi jeda sebelum mencoba lagi. Tetapi proses yang terus gagal akan mencapai batas: secara bawaan lima kali dalam sepuluh detik, setelah itu systemd menyerah dan unit berstatus failed. Untuk layanan yang bergantung pada jaringan atau database yang mungkin lambat siap saat boot, longgarkan batasnya:
[Unit]
StartLimitIntervalSec=300
StartLimitBurst=10
[Service]
Restart=always
RestartSec=10
Kalau unit sudah mencapai batas, systemctl reset-failed pemantau lalu start lagi. Tetapi tanyakan dulu kenapa ia gagal berulang; restart otomatis menyembunyikan masalah, bukan menyelesaikannya.
Menyunting Unit dengan Drop-in
Unit yang dibuat paket atau panel (misalnya unit Gunicorn yang ditulis VinzaPanel) bisa ditimpa saat pembaruan. Jangan sunting berkas aslinya; buat drop-in:
sudo systemctl edit pemantau
Perintah itu membuka editor untuk /etc/systemd/system/pemantau.service.d/override.conf. Untuk mengganti ExecStart, kosongkan dulu lalu tulis yang baru, karena ExecStart bersifat menambah:
[Service]
ExecStart=
ExecStart=/home/webapp/pemantau/.venv/bin/python pemantau.py --workers 1
Kami memakai pola ini untuk mengubah jumlah worker Gunicorn pada aplikasi yang unitnya ditulis ulang panel setiap deploy; drop-in-nya bertahan. Satu jebakan: tanda % di unit harus ditulis %%, karena % adalah awalan penanda khusus systemd.
Variabel Lingkungan dan Rahasia
EnvironmentFile= memuat berkas berisi baris KUNCI=nilai; nilai tidak melewati shell, jadi tidak perlu tanda kutip kecuali memang bagian dari nilainya. Berkas itu harus dimiliki root atau pengguna layanan dengan izin 600. Untuk beberapa nilai sederhana, Environment="PORT=8001" langsung di unit juga bisa. Yang harus dihindari: menulis sandi di ExecStart, karena baris itu terlihat di systemctl show dan di log. Kalau berkas lingkungan belum ada saat unit dijalankan, unit gagal dengan jelas; tambahkan tanda minus (EnvironmentFile=-/jalur/.env) kalau berkas itu opsional.
Timer sebagai Pengganti Cron
# backup.service
[Service]
Type=oneshot
User=webapp
ExecStart=/home/webapp/bin/backup.sh
# backup.timer
[Timer]
OnCalendar=*-*-* 02:30:00
Persistent=true
[Install]
WantedBy=timers.target
sudo systemctl enable --now backup.timer
systemctl list-timers
Keunggulannya atas cron: log masuk journal, Persistent=true menjalankan tugas yang terlewat saat mesin mati, dan list-timers menunjukkan kapan jalan berikutnya. Cron tetap baik untuk tugas sederhana; timer lebih baik kalau Anda ingin pemantauan dan isolasi yang sama dengan layanan lain.
Pembatasan Keamanan di Unit
Beberapa baris di [Service] membatasi apa yang bisa dilakukan proses kalau disusupi: NoNewPrivileges=true, PrivateTmp=true, ProtectSystem=strict dengan ReadWritePaths= untuk folder yang memang perlu ditulis, dan ProtectHome=read-only kalau aplikasi tidak di home. Jalankan systemd-analyze security pemantau untuk melihat skor dan sarannya. Tidak semua saran cocok untuk setiap aplikasi, tetapi tiga baris pertama jarang merugikan.
Unit Pengguna Tanpa Root
Pengguna biasa bisa punya unit sendiri di ~/.config/systemd/user/, dikelola dengan systemctl --user. Ini berguna untuk alat pribadi atau pengembangan. Satu jebakan: unit pengguna berhenti saat pengguna itu logout, kecuali Anda menyalakan lingering:
sudo loginctl enable-linger namapengguna
systemctl --user enable --now pemantau
journalctl --user -u pemantau -f
Mendiagnosis Unit yang Gagal
systemctl status pemantau -l # baris log lengkap, tidak dipotong
systemctl cat pemantau # unit yang benar-benar dipakai, termasuk drop-in
journalctl -u pemantau -b # semua log sejak boot terakhir
systemd-analyze verify /etc/systemd/system/pemantau.service
Urutan yang biasanya kami pakai: status -l untuk melihat kode keluar dan baris terakhir, cat untuk memastikan drop-in terbaca, lalu journalctl untuk konteks. Kode keluar 203 berarti ExecStart tidak bisa dijalankan (jalur salah atau tidak executable); 217 berarti pengguna di User= tidak ada; keduanya muncul berulang kali dalam pengalaman kami.
journalctl -u nama -n 100 tetap menjadi perintah pertama yang kami ketik.
Terima kasih sudah membaca sampai akhir, Rekan ArtonLabs. Perintah mana yang paling sering Anda ketik saat layanan bermasalah? Kami penasaran.