Windows Services einrichten mit NSSM

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.
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,PORTund 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)
Inhaltsverzeichnis
- Warum NSSM und nicht Taskplaner?
- Grundlagen: Windows Service Control Manager, Session 0 & typische Stolperfallen
- Installation & Setup (GUI/CLI)
- NSSM Feature-Tour: die Parameter, die wirklich zählen
- Praxis 1: Java / Spring Boot als Dienst (inkl. Rotation + Graceful Stop)
- Praxis 2: Node.js als Dienst (Worker/HTTP) – generisches Muster
- Praxis 3: Python-Daemon als Dienst
- Praxis aus dem echten Einsatz (tiny-tool.de)
- Produktivbetrieb: Security, Accounts, Rechte, Secrets
- Betrieb/Monitoring: Logs, Eventlog, Healthchecks, Failure-Actions
- Alternativen 2026: NSSM vs WinSW vs “richtiger” Service
- Troubleshooting: 15 häufige Probleme & schnelle Fixes
- Glossar
- Fazit: Welche Lösung passt zu dir?
- Links & Ressourcen
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)
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).
nssm install MeinDienst
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”.
:: 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.
:: 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.)
:: 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
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:
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.
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)
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:
Lädt externe Datenquellen, verarbeitet Events und schreibt strukturierte Logs.
Läuft über
javaw.exe mit definiertem Heap und sauberem Shutdown.
Ü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.
Keine Sammel-Batchdateien, keine verschachtelten Startskripte.
Jeder Prozess wird einzeln als Dienst registriert. Das vereinfacht Debugging, Monitoring und Wartung massiv.
Hintergrundartikel dazu:
- Praxis-Update: Intelligente Bildüberwachung
- Snapshotter + Client Architektur
- Als Windows-Service betreiben
Produktivbetrieb: Security, Accounts, Rechte, Secrets
“LocalSystem” ist bequem, aber oft viel zu mächtig. Für produktive Services: eigener Account,
nur NTFS-Rechte auf
C:\services\deinservice + logs.
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:
nssm set MeineSpringApp ObjectName ".\svc_myapp" "BitteEinStarkesPasswort!"
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).
:: 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
- Service startet und stoppt sofort
Ursache: App beendet sich (auch “Exit 0”).
Fix: Logs prüfen,AppStdout/AppStderrsetzen. Optional: Exit-Action anpassen. - Keine Logs werden geschrieben
Ursache: Pfad falsch oder Service-Account darf nicht schreiben.
Fix: Ordnerlogsanlegen + NTFS-Rechte geben, absolute Pfade nutzen. - Relative Pfade funktionieren nicht
Ursache: Working Directory ist nicht dein Projektordner.
Fix:AppDirectoryimmer explizit setzen. - Leerzeichen in Pfaden
Ursache: nicht korrekt gequotet.
Fix: überall"C:\Pfad mit Leerzeichen\..."sauber quoten. - Gemappte Laufwerke (Z:\) gehen nicht
Ursache: Session-Kontext des Dienstes.
Fix: UNC-Pfad nutzen\\server\share+ Rechte für Service-Account. - Node-Service läuft manuell, als Dienst aber nicht
Ursache: ENV fehlt (NODE_ENV,PATH), oder Working Directory passt nicht.
Fix:AppEnvironmentExtrasetzen,AppDirectorykorrekt. - Java findet Config/Keystore nicht
Ursache: relative Pfade / falscher Startordner.
Fix:AppDirectory+ absolute Pfade in Parametern. - 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-ProzessenAppKillProcessTreebeachten. - Crash-Loop frisst CPU
Ursache: sofortiger Restart bei sofortigem Crash.
Fix:AppThrottleundAppRestartDelayerhöhen (z.B. 3–10s). - Firewall blockiert
Ursache: java/node/python darf nicht raus/rein.
Fix: Firewall-Regel fürjavaw.exe/node.exesetzen. - Service-Account “Log on as a service” fehlt
Fix:secpol.msc→ User Rights Assignment → hinzufügen. - App braucht Netzwerk, startet aber zu früh
Fix: Abhängigkeit via Windows-Service-Dependencies setzen (z.B.Tcpip) oder Startverzögerung nutzen. - Du siehst kein Fenster / keine GUI
Ursache: Session 0 Isolation.
Fix: expected behavior. Für GUI brauchst du ein anderes Konzept (oder getrennte UI). - Exit-Codes spammen Eventlog
Fix: Exit-Action pro Code setzen (z.B. bestimmte Codes ignorieren, andere restart). - “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.



tiny-tool.de
tiny-tool.de