Linux Afry Rachmat · Jul 24, 2026 · 9 min read

Menjalankan Proses di Linux yang Bertahan setelah Logout

Tanpa nohup yang menipu. Dari sesi SSH sampai systemd — dan kenapa container butuh init sendiri.

IN THIS STORY

Mengapa proses ikut mati saat logout nohup hanya setengah solusi disown melepaskan dari shell, bukan terminal setsid: pelepasan sesi yang sebenarnya tmux dan screen: terminal virtual persisten Jawaban sesungguhnya: systemd Kesalahan umum dengan systemd Batasan yang perlu diakui Pendekatan alternatif Rekomendasi & Takeaways FAQ

Mengapa proses ikut mati saat logout

SSH login menciptakan sebuah session. Shell yang kamu pakai adalah session leader, dan terminal maya (/dev/pts/N) adalah controlling terminal-nya. Saat sesi berakhir — baik karena exit, koneksi putus, maupun laptop ditutup — kernel mengirim sinyal SIGHUP ke seluruh anggota process group di sesi itu. Proses yang di-background dengan & tetap berada di process group yang sama dan tetap terikat ke sesi yang sama, sehingga ia juga menerima SIGHUP dan mati.

Mengapa ini penting

& tidak membuat proses lepas dari sesi; ia hanya memindahkan proses ke background di dalam sesi yang tetap akan ditutup. Itu sebabnya python train.py & menghilang saat kamu logout.

nohup hanya setengah solusi

nohup menangani satu hal saja: ia membuat proses mengabaikan SIGHUP. Itu sebabnya kadang berhasil. Tapi nohup tidak melepaskan proses dari controlling terminal. Jika aplikasi masih menulis ke stdout/stderr yang terhubung ke PTY tersebut, atau membaca dari stdin, maka begitu terminalnya dicabut, operasi I/O itu gagal dengan broken pipe (SIGPIPE) atau error I/O.

nohup juga mem-redirect output ke nohup.out di current working directory — yang bisa memenuhi disk, atau berada di volume yang sudah tidak ada saat proses berjalan di konteks lain.

disown melepaskan dari shell, bukan terminal

disown memperbaiki satu kelemahan nohup: ia menghapus job dari tabel job shell sehingga shell tidak mengirim SIGHUP saat keluar. Tapi proses tetap menempel ke terminal sampai terminal itu benar-benar tertutup; setelah PTY dicabut, file descriptor-nya menjadi tidak valid, dan jika proses menulis ke sana, ia kena SIGPIPE. disown menyelamatkan dari hangup, bukan dari invalid fd.

setsid: pelepasan sesi yang sebenarnya

setsid adalah pelepasan sesi yang sebenarnya. Ia membuat sesi baru lewat setsid(2), sehingga proses menjadi session leader untuk sesinya sendiri yang tidak memiliki controlling terminal sama sekali. Tidak ada PTY yang bisa dicabut, tidak ada SIGHUP dari sesi SSH. Untuk pelepasan satu kali yang cepat:

setsid python app.py > /var/log/app.log 2>&1 < /dev/null &

Tips

Redirect ke /dev/null untuk stdin dan ke file log untuk stdout/stderr itu penting — tanpa itu, proses masih memegang fd ke PTY lama dan bisa gagal saat sesi mati.

Trade-off: setsid tidak me-restart proses yang mati. Ia hanya melepaskan. Kalau aplikasinya jatuh, ia tetap mati dan tidak kembali. Untuk itu kamu butuh supervisor.

tmux dan screen: terminal virtual persisten

tmux atau screen menawarkan jalan keluar yang berbeda: ia mempertahankan terminal virtual yang hidup lepas dari koneksi SSH kamu. Kamu bisa reattach besok dan melihat prosesnya jalan. Ini cocok untuk tugas interaktif jangka panjang (training model, migrasi database yang diawasi).

Kapan TIDAK pakai tmux sebagai daemon

tmux bergantung pada proses server tmux itu sendiri tetap hidup. Ia bukan cara yang tepat untuk layanan yang seharusnya jalan tanpa pengawasan — kalau server tmux mati, semua sesi di dalamnya mati juga.

Jawaban sesungguhnya: systemd

Untuk layanan produksi, jawabannya adalah service manager, bukan trik shell. Di Linux modern itu berarti systemd. Proses diawasi (supervised), otomatis di-restart kalau jatuh, lognya masuk ke journald, lingkungannya terisolasi, dan ia jalan saat boot tanpa bergantung pada terminal sama sekali. Unit yang minimal:

[Unit]
Description=My App
After=network.target

[Service]
Type=simple
User=appuser
WorkingDirectory=/opt/app
ExecStart=/usr/bin/python /opt/app/app.py
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
Environment=PYTHONUNBUFFERED=1

[Install]
WantedBy=multi-user.target

Aktifkan dengan systemctl daemon-reload && systemctl enable --now myapp. Satu detail kritis: Type=simple mengasumsikan ExecStart tidak melakukan fork — ia tetap di foreground. Banyak yang salah pakai Type=forking padahal aplikasinya tidak fork, maka systemd menunggu PID anak yang tak pernah muncul dan menandainya failed.

Kesalahan umum dengan systemd

  • Menjalankan sebagai root padahal tidak perlu (risiko keamanan).

  • Lupa WorkingDirectory sehingga path relatif di kode putus.

  • Berasumsi variabel environment dari .bashrc tersedia — padahal systemd tidak membaca shell profile, jadi variabel itu kosong.

  • Restart=always dipakai untuk menutupi crash loop; kamu menyembunyikan bug dan membakar CPU, bukan memperbaikinya.

Batasan yang perlu diakui

systemd spesifik Linux; BSD dan macOS pakai launchd/rc. Di dalam container, PID 1 biasanya adalah aplikasi itu sendiri atau init kecil, dan systemd di dalam container itu berat serta sering dimatikan. Di Docker, kamu menggunakan restart policy (restart: unless-stopped) dan init (tini) untuk men-forward sinyal dan men-reap zombie, bukan systemd.

Pendekatan

Survive logout

Auto-restart

Boots on reboot

Cocok untuk

&

tes cepat di sesi hidup

nohup &

sebagian

eksperimen sesi buangan

setsid

pelepasan satu kali

tmux

tugas interaktif panjang

systemd

layanan produksi

Pendekatan alternatif

supervisord berguna bila kamu punya banyak layanan kecil dan tidak ingin menulis unit systemd per aplikasi — konfigurasinya berbasis file dan language-agnostic. Orkestrasi container (Kubernetes, Docker Compose) memindahkan definisi layanan ke dalam YAML dan menangani restart serta health check di level orchestrator. Untuk tugas interaktif satu kali, tmux tetap juaranya.

Rekomendasi & Takeaways

Untuk eksperimen lokal atau sesi buangan, pakai setsid atau tmux. Untuk apa pun yang harus bertahan reboot dan bisa dioperasikan, pakai systemd (atau supervisord). Di container, definisikan restart policy dan gunakan init yang tepat; jangan jalankan systemd di dalamnya. Dan jangan pernah mengandalkan & lalu menutup laptop.

  • & saja bukanlah persistence; proses tetap ikut mati saat sesi tutup.

  • nohup hanya menangani SIGHUP, bukan pembatalan fd terminal atau reboot.

  • setsid benar-benar melepaskan proses dari terminal, tapi tidak me-restart-nya kalau jatuh.

  • systemd adalah jawaban sesungguhnya untuk layanan: supervise, log, restart, boot.

  • Di Docker, PID 1 penting; pakai restart policy + init, bukan systemd.

  • Redirect stdin/stdout/stderr secara eksplisit (< /dev/null, ke file log) sebelum me-detach.

FAQ

Apakah & cukup supaya proses bertahan?

Tidak. & hanya memindahkan proses ke background di dalam sesi yang sama. Saat sesi SSH ditutup, kernel mengirim SIGHUP ke seluruh process group, dan proses ikut mati.

Kapan pakai systemd vs setsid?

setsid untuk pelepasan cepat satu kali (eksperimen, sesi buangan). systemd untuk layanan yang harus survive reboot, diawasi, dan di-log. Di container, pakai restart policy + init, bukan systemd.

Afry Articles — ditulis dari pengalaman lapangan.