---
title: "Cara Membuat Service systemd untuk Aplikasi Kamu"
description: "Jalankan aplikasi Node.js, Python, atau Go sebagai service systemd: file unit, restart otomatis, environment, user non-root, dan journalctl."
url: "https://nivelva.com/insight/membuat-service-systemd"
category: "Server \u0026 Infrastruktur"
tags: ["systemd","service linux","journalctl","nodejs","deploy aplikasi"]
author: "Theresia Candiawan"
published: "2026-11-07T02:28:00+07:00"
updated: "2026-11-07T02:28:00+07:00"
language: "id"
publisher: "Nivelva (https://nivelva.com)"
---

# Cara Membuat Service systemd untuk Aplikasi Kamu

> **Jawaban singkat:** Buat file unit di /etc/systemd/system/nama.service berisi perintah start, user non-root, folder kerja, file environment, dan Restart=on-failure. Jalankan systemctl daemon-reload, lalu systemctl enable --now nama. Log dibaca dengan journalctl -u nama.

Aplikasimu mati begitu jendela SSH ditutup, atau tidak hidup lagi setelah server reboot? Itu tanda aplikasi masih dijalankan secara manual dari terminal. Di server Linux modern, cara yang rapi adalah menjadikannya service systemd: aplikasi berjalan di latar belakang, otomatis hidup saat boot, otomatis dinyalakan ulang bila crash, dan lognya tersimpan di satu tempat.

Kamu cukup menulis satu file teks pendek. Langkah di bawah memakai contoh aplikasi Node.js, lalu menunjukkan apa yang berubah untuk Python dan Go.

## Apa yang sebenarnya dilakukan systemd?

systemd adalah sistem init di sebagian besar distro Linux saat ini, termasuk Ubuntu, Debian, dan keluarga Red Hat. Ia menyalakan dan mengawasi semua layanan, dari SSH sampai web server. Setiap layanan dijelaskan dalam file **unit**. Untuk aplikasi yang berjalan terus, jenis unitnya adalah `.service`.

Dibanding `nohup`, `screen`, atau menjalankan dengan `&`, service systemd memberi pengawasan: systemd tahu kapan proses mati, bisa menyalakannya lagi, dan mencatat semua output ke journal.

## Langkah membuat service systemd

### Langkah 1. Siapkan user khusus aplikasi

Jangan jalankan aplikasi web sebagai root. Bila aplikasi dibobol, penyerang hanya mendapat hak user tersebut.

```bash
sudo useradd --system --create-home --shell /usr/sbin/nologin appku
sudo mkdir -p /opt/appku
sudo chown -R appku:appku /opt/appku
```

Pindahkan kode aplikasi ke `/opt/appku`. Prinsip memisahkan hak akses ini bagian dari [langkah awal mengamankan VPS](https://nivelva.com/insight/cara-mengamankan-vps-baru).

### Langkah 2. Pisahkan konfigurasi ke file environment

Simpan variabel seperti port, alamat database, dan API key di file terpisah, bukan di file unit:

```bash
sudo nano /etc/appku.env
```

```ini
NODE_ENV=production
PORT=3000
DATABASE_URL=postgres://appku:rahasia@localhost/appku
```

```bash
sudo chown root:appku /etc/appku.env
sudo chmod 640 /etc/appku.env
```

File ini hanya bisa dibaca root dan grup aplikasi.

### Langkah 3. Tulis file unit

Buat `/etc/systemd/system/appku.service`:

```ini
[Unit]
Description=Aplikasi appku
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=appku
Group=appku
WorkingDirectory=/opt/appku
EnvironmentFile=/etc/appku.env
ExecStart=/usr/bin/node /opt/appku/server.js
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
```

Penjelasan singkat bagian yang penting:

- `After` dan `Wants` membuat service menunggu jaringan siap. Bila aplikasi bergantung pada database di server yang sama, tambahkan juga unit database di `After`, misalnya `postgresql.service`.
- `ExecStart` wajib memakai path lengkap ke program. Cek dengan `command -v node`. Kalau Node dipasang lewat nvm, path-nya ada di folder home user, jadi lebih aman memasang Node dari paket sistem atau menulis path lengkap hasil nvm.
- `Restart=on-failure` menyalakan ulang proses bila keluar dengan error atau terbunuh sinyal. Pilih `always` bila aplikasi harus hidup apa pun alasan berhentinya.
- `WantedBy=multi-user.target` membuat service ikut menyala saat boot normal.

### Langkah 4. Muat, nyalakan, dan aktifkan saat boot

```bash
sudo systemctl daemon-reload
sudo systemctl enable --now appku
sudo systemctl status appku
```

`daemon-reload` wajib setiap kali file unit diubah. `enable --now` sekaligus mengaktifkan saat boot dan menyalakan sekarang. Status yang benar menunjukkan `active (running)`.

### Langkah 5. Baca log dengan journalctl

Semua yang ditulis aplikasi ke stdout dan stderr masuk ke journal:

```bash
journalctl -u appku -f          # ikuti log secara langsung
journalctl -u appku -b          # log sejak boot terakhir
journalctl -u appku --since "1 hour ago"
```

Tidak perlu lagi mengurus file log sendiri, asalkan ukuran journal dibatasi. Atur `SystemMaxUse=` di `/etc/systemd/journald.conf` agar journal tidak memakan disk tanpa batas.

### Langkah 6. Uji restart otomatis

Pastikan pengawasan benar-benar bekerja:

```bash
sudo systemctl kill -s SIGKILL appku
sleep 6
systemctl status appku
```

Dalam beberapa detik, status harus kembali `active (running)` dengan PID baru. Uji juga dengan reboot server sekali, karena itu skenario yang pasti terjadi suatu saat.

## Bagaimana untuk Python dan Go?

Struktur file unit sama, yang berubah hanya `ExecStart`.

Untuk aplikasi Python di virtualenv, arahkan langsung ke program di folder `bin` venv sehingga tidak perlu "activate":

```ini
ExecStart=/opt/appku/venv/bin/gunicorn --bind 127.0.0.1:8000 app:app
```

Tambahkan `Environment=PYTHONUNBUFFERED=1` agar output Python langsung muncul di journal, tidak tertahan di buffer.

Untuk Go, hasil build berupa satu file biner, jadi `ExecStart` cukup menunjuk ke biner itu:

```ini
ExecStart=/opt/appku/appku-server
```

Di depan aplikasi biasanya dipasang web server sebagai reverse proxy yang menangani domain dan HTTPS. Pilihannya dibahas di [Nginx vs Apache vs LiteSpeed](https://nivelva.com/insight/nginx-apache-litespeed).

## Opsi tambahan yang berguna

| Opsi | Fungsi | Contoh |
|:--|:--|:--|
| `Restart=` | Kapan proses dinyalakan ulang | `on-failure`, `always` |
| `RestartSec=` | Jeda sebelum restart | `5` |
| `Environment=` | Satu variabel langsung di unit | `Environment=PORT=3000` |
| `EnvironmentFile=` | Variabel dari file terpisah | `/etc/appku.env` |
| `NoNewPrivileges=` | Cegah proses menaikkan hak | `true` |
| `ProtectSystem=` | Jadikan sebagian besar sistem file hanya-baca | `full` atau `strict` |
| `PrivateTmp=` | Folder /tmp terpisah untuk service | `true` |
| `MemoryMax=` | Batas memori service | `512M` |
| `ExecReload=` | Perintah untuk reload tanpa restart | `/bin/kill -HUP $MAINPID` |

Opsi pengerasan seperti `ProtectSystem=strict` bisa membuat aplikasi gagal menulis file. Tambahkan satu per satu, uji, dan izinkan folder tertentu dengan `ReadWritePaths=`. Perintah `systemd-analyze security appku` memberi gambaran opsi mana yang belum dipakai.

## Pertanyaan yang sering diajukan

### Apa beda systemctl restart dan reload?

Restart menghentikan lalu menyalakan proses baru. Reload menjalankan perintah ExecReload, biasanya memberi tahu aplikasi untuk membaca ulang konfigurasi tanpa berhenti. Reload hanya bisa bila aplikasinya mendukung.

### Kenapa service berhenti mencoba restart setelah beberapa kali gagal?

systemd punya batas percobaan start dalam rentang waktu tertentu (StartLimitBurst dan StartLimitIntervalSec). Bila terlampaui, service masuk status gagal. Perbaiki penyebabnya, lalu jalankan systemctl reset-failed appku.

### Apakah perlu PM2 kalau sudah pakai systemd?

Tidak wajib. systemd sudah menangani start saat boot, restart otomatis, dan log. PM2 bisa tetap dipakai bila kamu butuh fiturnya seperti mode cluster, tapi jangan sampai dua pengawas saling berebut proses.

### Bisakah service systemd dibuat tanpa root?

Bisa, dengan user service di ~/.config/systemd/user dan perintah systemctl --user. Agar tetap berjalan setelah logout, aktifkan lingering dengan loginctl enable-linger nama-user.

### Bagaimana menjalankan tugas terjadwal dengan systemd?

Buat service bertipe oneshot lalu pasangkan dengan file .timer. Bandingannya dengan cron dibahas di [cara membuat cron job di Linux](https://nivelva.com/insight/cron-job-linux).

Daftar periksa singkat:

- Aplikasi berjalan sebagai user non-root
- Rahasia ada di file environment dengan izin 640
- `ExecStart` memakai path lengkap
- `Restart=on-failure` atau `always` sudah dipasang
- `systemctl enable` dijalankan, dan uji reboot berhasil
- Ukuran journal dibatasi

---

Diterbitkan oleh Nivelva Insight (https://nivelva.com/insight/). Artikel ini: https://nivelva.com/insight/membuat-service-systemd
Kontak Nivelva: WhatsApp https://wa.me/6285111245007, email hello@nivelva.com
