# Systemd Service untuk Background Job: Cara yang Benar Menjalankan Node.js di Produksi

> Cara menulis file service systemd siap produksi untuk Node.js, NestJS, dan background worker — dengan kebijakan restart, batas sumber daya, dan manajemen variabel lingkungan.

URL: https://www.matthewswong.com/id/blog/systemd-services-jobs/

- Author: Matthews Wong (https://www.matthewswong.com/id/about/)
- Published: 2025-06-10
- Updated: 2026-10-17
- Category: DevOps

Systemd mengelola lebih dari 70% sistem Linux dalam produksi dan merupakan init system standar untuk Ubuntu, Debian, CentOS, dan setiap distribusi Linux utama. Namun sebagian besar tutorial untuk menjalankan aplikasi Node.js dalam produksi masih merekomendasikan pm2 — manajer proses userspace yang menduplikasi fungsi yang sudah dibangun ke dalam systemd. Memigrasikan background worker NestJS dari pm2 ke service systemd native memberi startup otomatis saat boot, logging terstruktur lewat journald, penegakan batas resource, dan integrasi yang lebih baik dengan tool monitoring.

## Mengapa Systemd Daripada pm2

pm2 sangat baik untuk pengembangan dan prototyping namun menambahkan lapisan yang tidak diperlukan dalam produksi. Systemd menangani: startup otomatis saat boot, restart otomatis saat crash dengan backoff yang dapat dikonfigurasi, batas CPU dan memori yang diterapkan oleh kernel, log terstruktur melalui journald yang dapat diakses dengan journalctl, dan integrasi dengan systemctl untuk status dan kontrol.

### Anatomi File Service

File service systemd berada di /etc/systemd/system/your-service.service dan memiliki tiga bagian: [Unit] mendeskripsikan service dan dependensinya, [Service] mendefinisikan cara menjalankan service, dan [Install] menentukan kapan service dimulai. Restart=on-failure me-restart saat crash namun tidak pada exit bersih — perilaku yang tepat untuk produksi.

### Variabel Lingkungan di Systemd

Jangan pernah hardcode secret di file service. Gunakan EnvironmentFile=/etc/your-service/.env untuk memuat variabel lingkungan dari file dengan izin 640 yang dimiliki oleh root dan pengguna service Anda. File ini hanya dapat dibaca oleh pengguna service dan root, tidak dapat dibaca semua orang seperti file .env di direktori aplikasi.

> Saat menjalankan service NestJS di bawah systemd, gunakan direktif StandardOutput=journal+console dan StandardError=journal+console untuk mengirim stdout/stderr ke journald DAN ke konsol secara bersamaan. Tambahkan direktif SyslogIdentifier=your-service-name dan log ditandai dengan nama service Anda — kritis untuk pemfilteran saat Anda memiliki 10+ service yang semuanya menulis ke journald.

## Kebijakan Restart dan Backoff

Perilaku restart systemd dikendalikan oleh Restart=, RestartSec=, dan StartLimitIntervalSec= / StartLimitBurst=. Untuk service produksi: Restart=on-failure me-restart pada kode exit bukan nol, RestartSec=5s menunggu 5 detik antar restart (mencegah crash loop ketat dari memukuli CPU), StartLimitIntervalSec=60 dan StartLimitBurst=5 berarti jika service me-restart 5 kali dalam 60 detik, systemd menyerah.

### Batas Sumber Daya dan Hardening Keamanan

Systemd dapat menerapkan batas sumber daya langsung di file service: MemoryMax=512M (OOM-kill service jika melebihi 512MB), CPUQuota=50% (batasi ke setengah CPU core), LimitNOFILE=65535 (batas file descriptor untuk service), dan direktif hardening keamanan: PrivateTmp=true, ProtectSystem=strict, NoNewPrivileges=true.

> **After= di Systemd Bukan Berarti Ready=**

> Saya menghabiskan beberapa jam men-debug service yang mulai sebelum dependensi PostgreSQL-nya siap. After=postgresql.service hanya menjamin urutan — ia tidak memeriksa apakah PostgreSQL benar-benar siap menerima koneksi. Untuk aplikasi NestJS yang membutuhkan PostgreSQL, gunakan After=postgresql.service ditambah logika retry tingkat aplikasi.

## Mengelola Service dengan systemctl

Perintah systemctl penting: systemctl start/stop/restart your-service, systemctl enable your-service (mulai saat boot), systemctl status your-service (menampilkan 10 baris log terakhir plus PID dan penggunaan sumber daya), systemctl daemon-reload (diperlukan setelah mengedit file service), dan journalctl -u your-service -f (tail log untuk service).

## Systemd Timers: Pengganti Cron

Systemd timer adalah pengganti modern untuk pekerjaan cron, dengan logging yang lebih baik, manajemen dependensi, dan penanganan pekerjaan yang terlewat. Buat file .service yang mendeskripsikan apa yang akan dijalankan dan file .timer yang mendeskripsikan kapan menjalankannya. Gunakan OnCalendar=daily untuk pekerjaan sekali sehari.

## Template Service Produksi untuk NestJS

Template service systemd NestJS produksi saya mencakup: User=nestjs (akun service khusus), WorkingDirectory=/opt/nestjs/app, ExecStart=/usr/bin/node dist/main.js, EnvironmentFile=/etc/nestjs/.env, Restart=on-failure dengan RestartSec=10s dan StartLimitBurst=3, MemoryMax=512M, LimitNOFILE=65535, NoNewPrivileges=true, PrivateTmp=true.

## Sumber & Bacaan Lanjutan

- Linux Expert — 7 Praktik Terbaik Lanjutan Unit Service Systemd
- DEV Community — Cara Mengelola Service Background dengan systemctl dan systemd
- Akash Rajpurohit — Jaga Service Anda Berjalan di Background dengan SystemD

## Source links

- https://www.linuxoperatingsystem.net/systemd-service-unit-best-practices
- https://dev.to/chetansingh63/how-to-manage-background-services-with-systemctl-and-systemd-with-celery-example-320f
- https://akashrajpurohit.com/blog/keep-your-services-running-in-the-background-with-systemd/

## FAQ

### Mengapa menggunakan systemd alih-alih pm2 untuk mengelola proses Node.js dan NestJS di produksi?

pm2 sangat cocok untuk pengembangan dan prototyping, namun di produksi ia menambahkan lapisan userspace yang tidak diperlukan karena menduplikasi fungsi yang sudah ada di systemd. Systemd secara native menangani startup otomatis saat boot, restart saat crash dengan backoff yang dapat dikonfigurasi, batas CPU dan memori yang diterapkan kernel, serta logging terstruktur melalui journald — tanpa dependensi tambahan.

### Bagaimana cara mengelola variabel lingkungan dan secret di file service systemd?

Jangan pernah hardcode secret langsung di file service. Gunakan direktif EnvironmentFile yang menunjuk ke file (misalnya /etc/your-service/.env) dengan izin 640, dimiliki oleh root dan pengguna service, sehingga tidak dapat dibaca semua orang seperti file .env di direktori aplikasi. Nilai konfigurasi yang tidak sensitif bisa menggunakan direktif Environment= secara langsung, dan kedua pendekatan tersebut dapat dikombinasikan dalam satu file service yang sama.

### Pengaturan kebijakan restart apa yang direkomendasikan untuk service NestJS di produksi?

Kombinasi yang direkomendasikan adalah Restart=on-failure (hanya restart pada kode exit bukan nol, bukan pada exit bersih), RestartSec=5s (menambahkan jeda 5 detik untuk mencegah crash loop ketat yang membebani CPU), serta StartLimitIntervalSec=60 dengan StartLimitBurst=5 (jika service restart 5 kali dalam 60 detik, systemd berhenti mencoba dan menempatkannya dalam keadaan failed, memerlukan intervensi manual). Ini mencegah restart loop tak terbatas yang dapat menutupi masalah yang mendasarinya.

### Apakah After=postgresql.service di unit systemd menjamin PostgreSQL siap menerima koneksi?

Tidak — After=postgresql.service hanya mengontrol urutan start, bukan kesiapan service. Ia memastikan service Anda dimulai setelah unit PostgreSQL, namun PostgreSQL mungkin belum siap menerima koneksi pada saat itu. Pendekatan yang benar adalah menggabungkan After=postgresql.service dengan logika retry di level aplikasi, seperti mengonfigurasi TypeORM atau Prisma dengan retryAttempts dan retryDelay untuk menangani kegagalan koneksi sementara saat startup.

### Bagaimana systemd timer dibandingkan dengan cron tradisional untuk pekerjaan background terjadwal?

Systemd timer menawarkan logging yang lebih baik, manajemen dependensi, dan penanganan pekerjaan yang terlewat dibandingkan cron. Setiap timer dipasangkan dengan file .service (apa yang dijalankan) dan file .timer (kapan dijalankan), dan output masuk ke journald — sehingga Anda dapat melihat kapan pekerjaan berjalan, berapa lama, dan apakah berhasil. Timer juga muncul di output systemctl status dan melacak pekerjaan yang terlewat, yang tidak dilakukan cron secara native.

---

- HTML version: https://www.matthewswong.com/id/blog/systemd-services-jobs/
- English: https://www.matthewswong.com/en/blog/systemd-services-jobs/
- Site index for agents: https://www.matthewswong.com/llms.txt
- Sitemap: https://www.matthewswong.com/sitemap.xml
- API description (OpenAPI): https://www.matthewswong.com/openapi.json
