SSD Nodes Learn
Panduan Matt ConnorOleh Matt Connor · Diperbarui 2026-07-24

Cara membuat program jadi systemd service

Pelajari cara membuat file .service agar program tetap berjalan otomatis saat boot, restart otomatis jika crash, dan cara mengatur timer serta log sistem.

Apa itu systemd service, dan mengapa Anda membutuhkannya

systemd service adalah file teks kecil yang menginstruksikan server cara menjalankan program: memulai program saat boot, memulai ulang jika crash, dan mengirimkan output ke log sistem. Hanya itu fungsinya. Program yang Anda jalankan secara manual dalam sesi SSH akan berhenti saat Anda logout atau server melakukan reboot. Program yang dibungkus dalam systemd service akan tetap berjalan, karena server yang mengelolanya, bukan shell Anda.

systemd adalah init system pada Ubuntu, Debian, Fedora, dan sebagian besar server Linux modern. systemd adalah proses pertama yang berjalan dan mengawasi semua proses lainnya. Saat Anda membuat file service, Anda menyerahkan program tersebut kepada pengawas tersebut. Panduan ini menunjukkan unit terkecil yang berfungsi, tiga bagian yang ada pada setiap unit, cara mengaktifkan dan membaca log, cara menjalankannya secara terjadwal dengan timer, dan cara membatasi hak akses agar program berjalan dengan hak istimewa seminimal mungkin.

Layanan terkecil yang berfungsi

File layanan berada di /etc/systemd/system/, berakhiran .service, dan hanya membutuhkan beberapa baris. Buatlah satu untuk program di /usr/local/bin/myapp:

sudo nano /etc/systemd/system/myapp.service
[Unit]
Description=My application

[Service]
ExecStart=/usr/local/bin/myapp

[Install]
WantedBy=multi-user.target

Itu adalah unit lengkap yang berfungsi. ExecStart adalah perintah untuk dijalankan. WantedBy=multi-user.target berarti jalankan layanan ini setelah server mencapai mode multi-user normal, yang membuatnya berjalan saat boot. Hal lainnya hanyalah penyempurnaan.

Tiga bagian, dan kegunaan masing-masing

Setiap file unit dibagi menjadi bagian-bagian di dalam kurung siku. Sebuah service menggunakan tiga bagian.

[Unit] mendeskripsikan service dan relasinya. Dua baris yang paling sering Anda gunakan:

[Unit]
Description=My application
After=network-online.target
Wants=network-online.target

Description adalah label manusia yang Anda lihat di systemctl status. After=network-online.target menginstruksikan systemd agar tidak menjalankan program Anda sampai jaringan aktif, hal ini penting untuk program apa pun yang menggunakan port atau melakukan koneksi keluar.

[Service] adalah cara program dijalankan. Di sinilah sebagian besar pengaturan Anda berada:

[Service]
ExecStart=/usr/local/bin/myapp --config /etc/myapp/config.toml
WorkingDirectory=/opt/myapp
User=myapp
Restart=on-failure
RestartSec=5
Environment=LOG_LEVEL=info

User=myapp menjalankan program sebagai akun tanpa hak akses istimewa alih-alih root, ini adalah baris paling penting untuk keamanan. Restart=on-failure dan RestartSec=5 memiliki bagian tersendiri di bawah, karena keduanya adalah alasan utama orang membuat service.

[Install] adalah apa yang terjadi saat Anda mengaktifkan service:

[Install]
WantedBy=multi-user.target

WantedBy=multi-user.target adalah apa yang menghubungkan service ke proses boot saat Anda menjalankan systemctl enable. Tanpa bagian [Install], service dapat dijalankan secara manual tetapi tidak akan berjalan otomatis setelah reboot.

Aktifkan dan pantau

Setelah menulis atau mengedit file unit, muat ulang systemd agar perubahan terbaca, lalu aktifkan dan jalankan layanan dalam satu langkah:

sudo systemctl daemon-reload
sudo systemctl enable --now myapp.service

daemon-reload adalah langkah yang sering terlewatkan: systemd menyimpan cache file unit, sehingga pengeditan tidak akan berpengaruh sampai Anda melakukan muat ulang. enable --now akan mengaktifkan layanan saat booting sekaligus menjalankannya segera. Periksa dengan cara:

sudo systemctl status myapp.service
* myapp.service - My application
     Loaded: loaded (/etc/systemd/system/myapp.service; enabled)
     Active: active (running) since Wed 2026-07-15 22:40:11 UTC; 3s ago
   Main PID: 4123 (myapp)

Active: active (running) dan enabled adalah hasil yang Anda inginkan. Untuk membaca output program, minta journal hanya untuk unit ini:

sudo journalctl -u myapp.service -f

-f akan menampilkan baris baru saat data masuk, seperti tail -f. Semua yang ditulis program ke standard output atau standard error akan masuk ke sini tanpa perlu pengaturan logging tambahan.

Restart saat gagal, alasan Anda berada di sini

Keuntungan utama dari sebuah service adalah systemd akan memulai ulang program Anda saat program tersebut berhenti. Dua baris berikut melakukannya:

[Service]
Restart=on-failure
RestartSec=5

Restart=on-failure memulai ulang program saat keluar dengan kode non-nol atau mati karena sinyal crash seperti SIGKILL atau SIGSEGV. Keluar secara bersih, atau dihentikan oleh SIGTERM, SIGINT, SIGHUP, atau SIGPIPE, tidak akan memicu restart. RestartSec=5 menunggu lima detik di antara setiap percobaan, sehingga program yang langsung crash tidak akan berjalan dalam loop yang terus-menerus. Konfirmasikan hal ini dengan menghentikan proses dan melihat systemd menjalankannya kembali. Gunakan SIGKILL: default SIGTERM dianggap sebagai penghentian bersih, sehingga on-failure tidak akan memulai ulang service tersebut:

sudo systemctl kill -s SIGKILL myapp.service
sudo systemctl status myapp.service

Dalam waktu lima detik, status akan menunjukkan Main PID dan active (running) baru lagi. Itulah fungsi utamanya, dan itulah alasan mengapa service lebih baik daripada membiarkan program berjalan di tmux atau screen.

Jalankan sebagai pengguna tanpa hak istimewa, dan perkuat keamanannya

Layanan yang berjalan sebagai root dapat melakukan apa pun pada server Anda jika program tersebut tereksploitasi. Jalankan layanan sebagai penggunanya sendiri, dan berikan beberapa direktif pada systemd untuk membatasinya. Pertama, buat akun sistem tanpa akses login dan tanpa direktori home:

sudo useradd --system --no-create-home --shell /usr/sbin/nologin myapp

Kemudian atur User=myapp dan tambahkan baris penguatan ke [Service]:

[Service]
User=myapp
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true

Setiap baris menghapus fungsi yang tidak diperlukan oleh program. NoNewPrivileges=true mencegah proses mendapatkan hak istimewa baru, bahkan melalui biner setuid. PrivateTmp=true memberikan /tmp privat yang tidak dapat dilihat oleh proses lain. ProtectSystem=strict membuat seluruh sistem berkas menjadi read-only kecuali beberapa jalur yang Anda tentukan dengan ReadWritePaths=. ProtectHome=true menyembunyikan /home sepenuhnya dari layanan tersebut. Ini adalah prinsip hak istimewa terendah (least-privilege) yang sama dengan menempatkan layanan di balik firewall: berikan hanya apa yang dibutuhkan. Jika Anda telah membaca panduan tentang menutup celah firewall IPv6 pada VPS, ini adalah bagian pada host dari konsep yang sama. Untuk layanan yang terhubung ke internet, pasangkan penguatan ini dengan Fail2ban di depan SSH dan firewall default-deny.

Daripada mengetik semua ini secara manual dan salah mengingat direktif, buatlah unit yang lengkap dan aman, lalu salin hasilnya:

Toolsystemd service and timer generator

Timers: pengganti cron modern

systemd timer menjalankan layanan berdasarkan jadwal, dan ini adalah pengganti modern untuk cron job. Sebuah timer terdiri dari dua file: .service yang melakukan pekerjaan, dan .timer yang menentukan waktu. Misalkan Anda ingin melakukan backup setiap hari pada jam 3 pagi. Layanan tersebut menjalankan tugas satu kali lalu berhenti:

# /etc/systemd/system/backup.service
[Unit]
Description=Nightly backup

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh

Type=oneshot memberi tahu systemd bahwa program berjalan, selesai, dan berhenti, alih-alih tetap berjalan di latar belakang. Timer menjadwalkannya:

# /etc/systemd/system/backup.timer
[Unit]
Description=Run the nightly backup

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

[Install]
WantedBy=timers.target

OnCalendar=*-*-* 03:00:00 berarti jam 3 pagi setiap hari. Uji ekspresi kalender apa pun dengan systemd-analyze calendar "*-*-* 03:00:00", yang mengonfirmasi apakah ekspresi tersebut dapat dibaca dan menampilkan waktu eksekusi berikutnya. Persistent=true menjalankan pekerjaan yang terlewat segera setelah server menyala jika server mati pada jam 3 pagi, hal yang tidak bisa dilakukan oleh cron. Perhatikan bahwa timer diaktifkan melalui timers.target, bukan multi-user.target. Aktifkan timernya, bukan layanannya:

sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer
systemctl list-timers

list-timers menampilkan setiap timer beserta waktu eksekusi berikutnya dan terakhir, sehingga Anda dapat melihat kapan pekerjaan Anda akan berjalan berikutnya. Generator di atas membuat pasangan .service dan .timer untuk Anda saat Anda mengaktifkan mode timer. Dibandingkan dengan baris cron, timer memberikan log asli di journal, direktif hardening yang sama dengan layanan apa pun, dan fitur penanganan eksekusi yang terlewat yang disediakan oleh Persistent=true. Cron masih memadai untuk pekerjaan sederhana; timer adalah alat yang lebih baik untuk pekerjaan yang kritikal.

FAQ

Apa perbedaan antara systemd service dan cron job?

Service menjaga program tetap berjalan: service dimulai saat boot, memulai ulang saat gagal, dan mencatat log ke journal. Cron job menjalankan perintah singkat sesuai jadwal lalu berhenti. Jika Anda memerlukan penjadwalan tetapi juga menginginkan log journal, hardening, dan fitur catch-up untuk jadwal yang terlewat, gunakan systemd timer. Systemd timer menggabungkan jadwal .timer dengan service oneshot dan menggantikan cron untuk sebagian besar tugas server.

Di mana saya harus meletakkan file systemd service saya?

Letakkan unit buatan Anda di /etc/systemd/system/ dengan nama yang diakhiri .service. Direktori tersebut digunakan untuk unit yang ditambahkan administrator, dan memiliki prioritas lebih tinggi daripada unit bawaan paket di /lib/systemd/system/. Setelah membuat atau mengedit file di sana, jalankan sudo systemctl daemon-reload agar systemd mengenali perubahan tersebut.

Bagaimana cara membuat service memulai ulang jika mengalami crash?

Tambahkan Restart=on-failure dan RestartSec=5 ke bagian [Service], lalu jalankan sudo systemctl daemon-reload dan restart service tersebut. systemd akan menjalankan ulang program saat program berhenti dengan kode non-nol atau mati karena sinyal crash, dengan jeda lima detik antar percobaan. Uji dengan sudo systemctl kill -s SIGKILL myapp.service — SIGTERM, sinyal default, dianggap sebagai penghentian bersih dan tidak memicu on-failure — dan perhatikan systemctl status menunjukkan PID baru dalam beberapa detik.

Bagaimana cara menjalankan systemd service sebagai user non-root?

Buat akun sistem dengan sudo useradd --system --no-create-home --shell /usr/sbin/nologin myapp, lalu tambahkan User=myapp ke bagian [Service]. Tambahkan NoNewPrivileges=true, PrivateTmp=true, dan ProtectSystem=strict agar proses berjalan dengan hak akses minimal yang dibutuhkan. Menjalankan service sebagai user tanpa hak istimewa adalah perubahan tunggal terpenting untuk keamanan service.

Mengapa service saya gagal dijalankan?

Jalankan systemctl status myapp.service untuk ringkasan dan journalctl -u myapp.service untuk output lengkap. Penyebab paling umum adalah jalur yang salah di ExecStart, WorkingDirectory yang hilang, kesalahan izin karena User= tidak dapat membaca file, atau lupa menjalankan sudo systemctl daemon-reload setelah melakukan pengeditan. Journal akan menampilkan pesan error dari program itu sendiri, yang biasanya menyebutkan masalah secara langsung.