How-To · Windows · 2026

Windows Services einrichten mit NSSM

Beitragsbild mit Titel „Windows Services einrichten mit NSSM“, Windows-Logo mit Zahnrad und Schraubenschlüssel sowie Monitor mit NSSM-Konfigurationsfenster und tiny-tool.de-Branding.

tiny-tool.de

NSSM (Non-Sucking Service Manager) ist der pragmatische “Wrapper”, wenn du eine normale Anwendung (Konsole, Skript, Java-Jar, Node-Server, Worker) als echten Windows-Dienst betreiben willst – inkl. Restart-Logik, sauberen Stop-Methoden, eigenen Umgebungsvariablen und Logging/Rotation.

Stand: 03. März 2026 · Ziel: stabiler Betrieb statt Bastellösung

Der 60-Sekunden-Überblick: Was du nach diesem Artikel kannst

  • NSSM sauber installieren (GUI + CLI) und “Configuration as Code” nutzen.
  • Java/Spring Boot als Dienst mit javaw.exe, Memory-Tuning und Log-Rotation.
  • Node.js-Worker/Server als Dienst mit NODE_ENV, PORT und Neustart-Backoff.
  • Python-Daemon als Dienst inkl. I/O-Redirect und robustem Shutdown.
  • Die wichtigsten NSSM-Features verstehen: Exit-Actions, Throttle/Delay, Stop-Methoden, Accounts, Dependencies.
  • Troubleshooting: die typischen 15 Fehlerbilder in Minuten diagnostizieren.
  • Real-world-Beispiele aus produktivem Dauerbetrieb (tiny-tool.de)

Warum NSSM und nicht Taskplaner?

Klar, du kannst eine App auch über den Taskplaner “beim Login” oder “beim Start” hochziehen. Das ist aber
oft eine Mogelpackung-Service: läuft nur in bestimmten Benutzer-Kontexten, hängt an Sessions, hat gern mal
komische Rechte, und Restart-Logik/Stop-Logik ist schnell ein Flickenteppich.

NSSM sitzt dagegen dort, wo Windows Dienste wirklich verwaltet: im Service Control Manager (SCM).
Damit bekommst du das komplette “Service-Feeling”: Starttyp, Abhängigkeiten, Service-Account, Stop/Restart,
Status in services.msc – ohne selbst C# oder Win32 zu schreiben.

Wann NSSM fast immer die beste Abkürzung ist

  • Du hast eine “normale” App (Jar, Node, Python, Go, .NET Console) und willst 24/7 Betrieb.
  • Du willst Auto-Restart bei Crash, aber ohne eigene Watchdog-Skripte.
  • Du willst Logs + Rotation in einem Rutsch.
  • Du willst pro Service eigene Environment-Variablen setzen (ohne globalen System-Murks).
  • Du willst Least Privilege (dedizierter Account, minimale NTFS-Rechte).

Grundlagen: SCM, Session 0 und das “Warum sehe ich kein Fenster?”

Windows Dienste laufen (seit Vista) in Session 0. Das ist Absicht: Dienste sollen nicht auf dem
Benutzer-Desktop rumturnen. Konsequenz: Eine GUI siehst du nicht, Tray-Icons funktionieren nicht,
gemappte Laufwerke sind oft weg – und relative Pfade sind im Service-Kontext schnell “überraschend”.

Goldene Regel

Teste deine App zuerst manuell im selben Kontext wie später: gleicher Ordner, gleiche Pfade, gleiche User-Rechte. Danach erst als Dienst. Ein Service “macht nichts kaputt” – er macht Probleme nur sichtbar, die vorher versteckt waren.

Installation & Setup (GUI/CLI)

cmd · NSSM in einen festen Ordner + PATH (empfohlen)
mkdir C:\tools\nssm
cd C:\tools\nssm

:: Offiziell: Download-Seite (stable)
:: https://nssm.cc/download

:: Optional (für neuere Windows-Setups): Development Builds („builds“).
:: Achtung: Die Builds-Seite warnt explizit vor Risiken – nutze das nur, wenn du’s brauchst.
:: https://nssm.cc/builds

:: Beispiel: stabile ZIP (Version 2.24)
curl -L -o nssm.zip https://nssm.cc/release/nssm-2.24.zip

tar -xf nssm.zip
:: nssm.exe aus win64/win32 passend kopieren
copy .\nssm-2.24\win64\nssm.exe .\nssm.exe

:: PATH dauerhaft setzen (Admin)
setx PATH "%PATH%;C:\tools\nssm" /M

Danach hast du zwei Workflows:
GUI (super fürs erste Setup) und CLI (super für reproduzierbare Deployments).

cmd · GUI öffnen (Install-Dialog)
nssm install MeinDienst
Häufiges Missverständnis: „NSSM ist nur eine GUI.“
So sieht’s in der Praxis aus: NSSM ist voll CLI-fähig und damit perfekt für “Infrastructure as Code”. Die GUI ist nur die komfortable Einstiegsoberfläche.

NSSM Feature-Tour: die Parameter, die wirklich zählen

NSSM speichert Konfiguration pro Dienst in der Registry (unter dem jeweiligen Service-Key).
Du musst die Registry nicht anfassen – aber es hilft, die “Bausteine” zu kennen.
Unten sind die wichtigsten Werte, die du im Alltag wirklich brauchst.

Feature NSSM-Setting / Registry Beispiel Warum es wichtig ist
Arbeitsverzeichnis AppDirectory C:\services\myapp Relative Pfade, Config-Files, Log-Ordner funktionieren zuverlässig.
Parameter AppParameters -jar app.jar --profile=prod Du startest die App exakt so, wie sie produktiv laufen soll.
Stdout/Stderr AppStdout / AppStderr logs\out.log / + Logs sind Debugging-Lebensversicherung. + merged stderr → stdout.
Log-Rotation AppRotateFiles, AppRotateSeconds, AppRotateBytes 10, 86400, 10485760 Verhindert “Log frisst Platte” – gerade bei Chatty-Apps.
Exit-Actions AppExit Default Restart / Ignore Steuert: Neustart bei Crash? Oder “Exit 0” ist okay?
Backoff / Crash-Loop Schutz AppThrottle, AppRestartDelay 2000, 5000 Verhindert CPU-Vollgas bei “sofort wieder starten”.
Environment pro Dienst AppEnvironmentExtra NODE_ENV=production Sauberer als System-weit – und pro Service getrennt.
Service-Account ObjectName .\svc_myapp Least Privilege statt “LocalSystem, weil YOLO”.
Stop-Methoden AppStopMethod* Console + WM_CLOSE + Terminate Damit deine App bei Stop “sauber” runterfährt (wichtig bei DB/Queues).
Dependencies DependOnService (Windows-Feature) Tcpip, MSSQLSERVER Startet erst, wenn Netzwerk/DB wirklich bereit ist.

Praxis-Shortcut: NSSM als “Config-Tool” verwenden

Du kannst Dienste komplett über CLI aufsetzen. Das ist ideal, wenn du Install-Skripte baust,
oder mehrere Maschinen identisch konfigurieren willst (Dev/Test/Prod).

Praxis 1: Java / Spring Boot als Dienst (robust & wartbar)

Java-Services sind ein typischer NSSM-Use-Case: Jar starten, Heap setzen, Profile aktivieren,
Logs in Dateien – fertig. Wichtig: nutze für Services meistens javaw.exe statt java.exe,
damit kein Konsolenfenster “dranhängt”.

cmd · Java/Spring Boot komplett per CLI installieren
:: Beispiel-Ordnerstruktur:
:: C:\services\spring-prod\app.jar
:: C:\services\spring-prod\logs\

nssm install MeineSpringApp "C:\Program Files\Eclipse Adoptium\jdk-21\bin\javaw.exe"

nssm set MeineSpringApp AppDirectory        "C:\services\spring-prod"
nssm set MeineSpringApp AppParameters       "-Xms512m -Xmx2048m -jar app.jar --spring.profiles.active=prod"

:: Pro Service Environment setzen (keine System-weiten Nebenwirkungen)
nssm set MeineSpringApp AppEnvironmentExtra "TZ=Europe/Berlin" "JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF-8"

:: I/O Logging + Rotation
nssm set MeineSpringApp AppStdout           "C:\services\spring-prod\logs\stdout.log"
nssm set MeineSpringApp AppStderr           "+"
nssm set MeineSpringApp AppRotateFiles      10
nssm set MeineSpringApp AppRotateSeconds    86400
nssm set MeineSpringApp AppRotateBytes      10485760

:: Crash-Loop Schutz
nssm set MeineSpringApp AppExit             Default Restart
nssm set MeineSpringApp AppThrottle         2000
nssm set MeineSpringApp AppRestartDelay     5000

nssm start MeineSpringApp

Wichtig bei Java: “Stop” soll nicht brutal sein

Wenn dein Service Daten verarbeitet (DB, Queue, Files), willst du bei Stop einen Graceful Shutdown.
Spring Boot kann das – aber nur, wenn dein Prozess die Stop-Signale sauber bekommt und Zeit hat.

cmd · Stop-Methoden & Timeout (Graceful Shutdown fördern)
:: Standard-Default in NSSM: 1500 ms pro Methode
:: Für produktive Java-Apps mit Graceful Shutdown oft sinnvoll: 15 Sekunden Zeit geben

nssm set MeineSpringApp AppStopMethodConsole  15000
nssm set MeineSpringApp AppStopMethodWindow   15000
nssm set MeineSpringApp AppStopMethodThreads  15000
nssm set MeineSpringApp AppKillProcessTree    1

Tipp aus der Praxis: Lass Spring Boot seine eigenen Logs schreiben (Logback/Log4j2) oder nutze NSSM-I/O-Redirect –
aber entscheide dich bewusst. Doppeltes Logging ist okay, aber nicht immer hübsch.

Praxis 2: Node.js als Dienst – generisches Muster (Worker oder HTTP-Service)

Node-Dienste sind oft entweder:
(a) ein kleiner HTTP-Server (Webhook, API, Health-Endpoint) oder
(b) ein Worker, der Dinge pollt (Ordner überwachen, Queue lesen, Kamera-Snapshots verarbeiten …).
NSSM ist für beide Varianten super – solange du zwei Dinge beachtest: Working Directory und Environment.

Beispiel-Szenario (absichtlich generisch)

  • Ein Node-Worker überwacht einen Ordner (incoming\)
  • Verarbeitet Dateien (z.B. Bilder/JSON) und schreibt Ergebnisse nach processed\
  • Optional: sendet Benachrichtigungen (Mail/Chat/Webhook)

(Das Muster passt 1:1 auch auf “Snapshotter/Client”-Setups – nur ohne Tool-Spezifika.)

cmd · Node-Service installieren (Worker)
:: Ordnerstruktur:
:: C:\services\node-worker\worker.js
:: C:\services\node-worker\logs\

nssm install NodeWorker "C:\Program Files\nodejs\node.exe"

nssm set NodeWorker AppDirectory        "C:\services\node-worker"
nssm set NodeWorker AppParameters       "worker.js --watch incoming --out processed"

:: Pro Service Env
nssm set NodeWorker AppEnvironmentExtra "NODE_ENV=production" "TZ=Europe/Berlin"

:: Logs + Rotation
nssm set NodeWorker AppStdout           "C:\services\node-worker\logs\stdout.log"
nssm set NodeWorker AppStderr           "+"
nssm set NodeWorker AppRotateFiles      10
nssm set NodeWorker AppRotateSeconds    86400

:: Neustart-Strategie (Crash-Loop Schutz)
nssm set NodeWorker AppExit             Default Restart
nssm set NodeWorker AppThrottle         3000
nssm set NodeWorker AppRestartDelay     8000

nssm start NodeWorker
Häufiges Missverständnis: „Wenn’s crasht, starte ich sofort neu – dann läuft’s wieder.“
So sieht’s in der Praxis aus: Sofortige Restarts können den Schaden vergrößern (Crash-Loop, 100% CPU, Log-Spam). Mit AppThrottle + AppRestartDelay baust du einen simplen, aber wirksamen Backoff.

Wenn du statt Worker einen HTTP-Service hast, sieht’s praktisch identisch aus – nur die Parameter ändern sich:

cmd · Node-HTTP-Service (z.B. Express) mit PORT & Health
nssm install NodeApi "C:\Program Files\nodejs\node.exe"

nssm set NodeApi AppDirectory        "C:\services\node-api"
nssm set NodeApi AppParameters       "server.js"

nssm set NodeApi AppEnvironmentExtra "NODE_ENV=production" "PORT=8080"

nssm set NodeApi AppStdout           "C:\services\node-api\logs\api.log"
nssm set NodeApi AppStderr           "+"
nssm set NodeApi AppRotateFiles      5
nssm set NodeApi AppRotateSeconds    86400

nssm set NodeApi AppExit             Default Restart
nssm set NodeApi AppThrottle         2000
nssm set NodeApi AppRestartDelay     5000

nssm start NodeApi

Praxis 3: Python-Daemon als Dienst

Python ist oft “ein Script, das dauerhaft laufen soll”: Scheduler, Poller, Watcher, ETL-Mini-Jobs.
NSSM macht daraus einen echten Dienst – ohne dass du mit Windows-Service-APIs kämpfen musst.

cmd · Python-Daemon installieren (einfach & stabil)
nssm install PyDaemon "C:\Python312\python.exe"

nssm set PyDaemon AppDirectory  "C:\services\py-daemon"
nssm set PyDaemon AppParameters "main.py --config prod.ini"

nssm set PyDaemon AppStdout     "C:\services\py-daemon\logs\stdout.log"
nssm set PyDaemon AppStderr     "+"
nssm set PyDaemon AppRotateFiles   10
nssm set PyDaemon AppRotateSeconds 86400

nssm set PyDaemon AppExit       Default Restart
nssm set PyDaemon AppThrottle   3000
nssm set PyDaemon AppRestartDelay 8000

nssm start PyDaemon

Praxis aus dem echten Einsatz (tiny-tool.de)

Warum dieser Abschnitt wichtig ist:
Theorie ist gut. Produktiver Betrieb ist besser. Die folgenden Beispiele zeigen NSSM im realen Dauerbetrieb mit getrennten Java- und Node-Services.

Klassischer Einstieg: Ein Tool als Windows-Service betreiben

Entscheidend für ein stabiles Setup sind:

  • Application Path → Pfad zur Runtime (python.exe, javaw.exe, node.exe etc.)
  • Startup Directory → Projektordner (wichtig für relative Pfade!)
  • Arguments → Startparameter, Skriptname, Jar-Datei etc.
  • I/O-Redirect → Logging in Datei statt ins Nichts (siehe nächstes Bild)

Multi-Service-Architektur: Java + Node getrennt betreiben

In realen Projekten (z. B. bei Datenverarbeitung, Überwachung oder Event-Handling) laufen oft mehrere unabhängige Komponenten parallel:

Java-Service
Lädt externe Datenquellen, verarbeitet Events und schreibt strukturierte Logs.
Läuft über javaw.exe mit definiertem Heap und sauberem Shutdown.

Node-Service
Überwacht eingehende Daten, verarbeitet diese weiter und sendet Benachrichtigungen.
Läuft isoliert über node.exe mit eigener Restart-Strategie.

Jeder dieser Prozesse wird einzeln als Windows-Dienst über NSSM registriert – mit eigenen Einstellungen für:

  • Logging und Rotation
  • Restart-Verhalten & Throttling
  • Environment-Variablen
  • Service-Account & NTFS-Rechte

Genau das macht NSSM so stark: ein Prozess = ein Dienst – ohne Sammel-Batchdateien oder verschachtelte Skripte. Das vereinfacht Debugging, Monitoring und Wartung erheblich.

Architektur-Prinzip:
Keine Sammel-Batchdateien, keine verschachtelten Startskripte.
Jeder Prozess wird einzeln als Dienst registriert. Das vereinfacht Debugging, Monitoring und Wartung massiv.

Hintergrundartikel dazu:

Produktivbetrieb: Security, Accounts, Rechte, Secrets

Least Privilege: eigener Service-User
“LocalSystem” ist bequem, aber oft viel zu mächtig. Für produktive Services: eigener Account,
nur NTFS-Rechte auf C:\services\deinservice + logs.

cmd · Lokalen Service-User anlegen
net user svc_myapp "BitteEinStarkesPasswort!" /add
:: Danach: secpol.msc -> Local Policies -> User Rights Assignment
:: "Log on as a service" -> svc_myapp hinzufügen

In NSSM bindest du den Account so:

cmd · Service-Account setzen
nssm set MeineSpringApp ObjectName ".\svc_myapp" "BitteEinStarkesPasswort!"
Secrets: lieber nicht in CLI-History brüllen
NSSM kann Env-Vars setzen – super für NODE_ENV, Pfade, Flags. Für echte Secrets: bevorzugt Windows Credential Manager, DPAPI-geschützte Files oder einen Secret-Store (je nach Umgebung). Wenn du Env nutzt: setze restriktive ACLs auf die Service-Registry/Ordner.

Minimal-Best-Practice: Config-Datei mit ACL nur für den Service-User + Admins.

Netzlaufwerke / gemappte Drives

Wenn deine App auf Z:\ zugreift und als Service “plötzlich” nicht mehr:
Das ist typisch. Services haben ihre eigene Session – gemappte Laufwerke existieren dort nicht zuverlässig. Nutze UNC-Pfade wie \\server\share\path und gib dem Service-Account Rechte.

Betrieb/Monitoring: Logs, Eventlog, Failure-Actions, Health

NSSM bringt schon viel mit, aber “Betrieb” ist mehr als “läuft bei mir”.
Ein gutes Setup hat immer: Logs, Rotation, Restart-Strategie,
und (wenn möglich) einen Healthcheck.

Empfohlenes Minimum für produktive Services

  • I/O-Redirect aktiv (oder App-Logging), Rotation an.
  • Crash-Loop Schutz über AppThrottle/AppRestartDelay.
  • Dedizierter Account + minimale NTFS-Rechte.
  • Windows-Failure-Actions zusätzlich setzen (zweite Sicherheitsleine).
  • Dokumentation: Pfade, Versionen, Parameter (damit “Future-You” nicht weint).
cmd · Windows Failure-Actions zusätzlich konfigurieren
:: Drei Neustarts, jeweils nach 60s, Reset nach 1 Tag
sc failure "MeineSpringApp" actions= restart/60000/restart/60000/restart/60000 reset= 86400

Wenn du Healthchecks hast (z.B. HTTP /health), kannst du Monitoring super simpel machen
(lokal per Script oder in deinem Monitoring-Stack).

Alternativen 2026: NSSM vs WinSW vs “richtiger” Service

Lösung Konfig Stärken Schwächen Wann ich’s nehmen würde
NSSM GUI + CLI Super schnell, pragmatisch, Logging/Rotation/Restart-Logik direkt drin Projekt wirkt “alt”, Konfig nicht als “schöne Datei” (Registry), letzte stabile Release 2014 Wenn du heute ein Ding als Service brauchst und es einfach laufen soll
WinSW XML / YAML Konfig als Datei, modernere Wrapper-Philosophie, gut für “Config-as-Code” Ein Tick mehr Setup-Overhead Für neue Projekte, wenn du standardisiert ausrollen willst
.NET Worker Service C# “Native” Integration in Windows/SCM, EventLog-Provider, Features ohne Wrapper Entwicklungsaufwand, für “nur Jar starten” Overkill Wenn du eh .NET bist und tiefe SCM-Features brauchst
Task Scheduler GUI/CLI Ok für Cron-ähnliche Jobs Nicht wirklich ein Service, Session/Rechte/Restart oft fummelig Für zeitbasierte Jobs, nicht für 24/7 Server

Troubleshooting: 15 häufige Probleme & schnelle Fixes

  1. Service startet und stoppt sofort
    Ursache: App beendet sich (auch “Exit 0”).
    Fix: Logs prüfen, AppStdout/AppStderr setzen. Optional: Exit-Action anpassen.
  2. Keine Logs werden geschrieben
    Ursache: Pfad falsch oder Service-Account darf nicht schreiben.
    Fix: Ordner logs anlegen + NTFS-Rechte geben, absolute Pfade nutzen.
  3. Relative Pfade funktionieren nicht
    Ursache: Working Directory ist nicht dein Projektordner.
    Fix: AppDirectory immer explizit setzen.
  4. Leerzeichen in Pfaden
    Ursache: nicht korrekt gequotet.
    Fix: überall "C:\Pfad mit Leerzeichen\..." sauber quoten.
  5. Gemappte Laufwerke (Z:\) gehen nicht
    Ursache: Session-Kontext des Dienstes.
    Fix: UNC-Pfad nutzen \\server\share + Rechte für Service-Account.
  6. Node-Service läuft manuell, als Dienst aber nicht
    Ursache: ENV fehlt (NODE_ENV, PATH), oder Working Directory passt nicht.
    Fix: AppEnvironmentExtra setzen, AppDirectory korrekt.
  7. Java findet Config/Keystore nicht
    Ursache: relative Pfade / falscher Startordner.
    Fix: AppDirectory + absolute Pfade in Parametern.
  8. Stop dauert ewig oder killt hart
    Ursache: App reagiert nicht auf Stop-Signale.
    Fix: Stop-Methoden/Timeouts sinnvoll setzen (z. B. 15 s statt Default 1,5 s), in der App graceful shutdown implementieren. Bei Child-Prozessen AppKillProcessTree beachten.
  9. Crash-Loop frisst CPU
    Ursache: sofortiger Restart bei sofortigem Crash.
    Fix: AppThrottle und AppRestartDelay erhöhen (z.B. 3–10s).
  10. Firewall blockiert
    Ursache: java/node/python darf nicht raus/rein.
    Fix: Firewall-Regel für javaw.exe/node.exe setzen.
  11. Service-Account “Log on as a service” fehlt
    Fix: secpol.msc → User Rights Assignment → hinzufügen.
  12. App braucht Netzwerk, startet aber zu früh
    Fix: Abhängigkeit via Windows-Service-Dependencies setzen (z.B. Tcpip) oder Startverzögerung nutzen.
  13. Du siehst kein Fenster / keine GUI
    Ursache: Session 0 Isolation.
    Fix: expected behavior. Für GUI brauchst du ein anderes Konzept (oder getrennte UI).
  14. Exit-Codes spammen Eventlog
    Fix: Exit-Action pro Code setzen (z.B. bestimmte Codes ignorieren, andere restart).
  15. “It works on my machine”
    Fix: Service-Kontext nachbauen: gleicher Account, gleiche Ordner, gleiche Rechte – dann debuggen.

Glossar

Kurze Begriffe, die dir beim Lesen von Logs, SCM-Meldungen und NSSM-Optionen wirklich helfen:

SCM (Service Control Manager)
Windows-Komponente, die Dienste startet/stoppt und deren Status verwaltet.
Session 0 Isolation
Dienste laufen in einer separaten Session ohne Benutzer-Desktop – keine GUI/Tray-Interaktion.
AppDirectory
Working Directory des Dienstes – entscheidend für relative Pfade.
AppStdout / AppStderr
Umleitung von Ausgabe in Dateien. + bedeutet “stderr in stdout mergen”.
AppRotate*
Rotation nach Anzahl/Zeit/Größe – verhindert “Logs fressen Platte”.
AppExit
Regel: Was macht NSSM bei Exit-Code? Restart, Ignore, usw.
Least Privilege
Der Dienst bekommt nur die Rechte, die er wirklich braucht. Weniger Risiko, weniger Chaos.

Fazit: Welche Lösung passt zu dir?

Meine Kurz-Empfehlung für 2026:

  • Du willst schnell, simpel, stabil: NSSM – und du dokumentierst sauber Service-Name, Pfade, Parameter. (Pre-Release 2.24-101 für Windows 10+ nutzen.)
  • Du willst “Config-as-Code” mit Datei-Konfig: WinSW als moderner Wrapper.
  • Du brauchst tiefe Windows-Integration: “richtiger” Service (z.B. .NET Worker).

NSSM ist vielleicht nicht “hip”, aber genau deshalb so beliebt: es ist boring – und boring ist im Betrieb ein Kompliment.
Wenn du die paar Klassiker beachtest (Working Directory, Logs, Rotation, Backoff, Service-User), läuft das Ding
auf Windows-Kisten oft jahrelang unauffällig durch.