Skip to content

IT Installation Windows

IT-Master Heizmann edited this page Sep 18, 2026 · 1 revision

Installation unter Windows

Caution

Diese Seite richtet sich ausschliesslich an Informatikerinnen und Informatiker. Nicht für Laien geeignet: Dienste, Firewall-Regeln und Berechtigungen falsch einzurichten kann den Server gefährden oder Daten unzugänglich machen. Ohne Fachkenntnisse bitte Installation Schritt für Schritt verwenden.

Für wen ist diese Seite? Für Informatikerinnen und Informatiker, die SmallTime 2027 auf Windows Server oder Windows 10/11 dauerhaft als Dienst betreiben oder im Repository unter Windows bauen.

Inhalt

  1. Voraussetzungen
  2. Pfade und Berechtigungen
  3. Paket installieren
  4. Als Dienst mit NSSM
  5. Alternative: Aufgabenplanung
  6. Firewall
  7. HTTPS unter Windows
  8. dev.cmd und prod.cmd im Repository

Voraussetzungen

  • Windows Server 2019+ oder Windows 10/11, x64.
  • Node.js >= 26.9.0 < 27 (MSI von https://nodejs.org/dist/v26.9.0/, systemweit nach C:\Program Files\nodejs). npm >= 11.19.1 < 12 ist enthalten. Mehrere Versionen parallel: nvm-windows (nvm install 26.9.0, nvm use 26.9.0); für einen Dienst aber einen festen Pfad zu node.exe verwenden.
  • sqlite3 und bcrypt sind native Module. Normalerweise werden vorgebaute Binärdateien geladen. Gibt es für die Node-Version keine, kompiliert npm lokal; dafür «Visual Studio Build Tools» (Workload Desktopentwicklung mit C++) und Python 3 installieren.
  • Ausgehend HTTPS zu lizenz.small.li (Lizenzprüfung) und zur npm-Registry (Installation).

Prüfen:

node -v    # v26.x, mindestens v26.9.0
npm -v     # 11.19.1 oder neuer

Pfade und Berechtigungen

Empfohlene Ablage:

Pfad Inhalt
C:\SmallTime\ Betriebspaket (app.cjs, dist\, public\, config\, .env, …)
C:\SmallTime\data\, C:\SmallTime\uploads\ Laufzeitdaten (werden beim Start angelegt)
C:\SmallTime\logs\ Logdateien des Dienstes (NSSM)

Einen eigenen Dienstbenutzer verwenden (z. B. virtuelles Konto NT SERVICE\SmallTime oder ein lokales Konto ohne Anmelderecht):

# Lesen/Ausführen auf den ganzen Ordner, Ändern nur auf Laufzeitordner
icacls C:\SmallTime /inheritance:r /grant:r "Administrators:(OI)(CI)F" "SYSTEM:(OI)(CI)F" "NT SERVICE\SmallTime:(OI)(CI)RX"
foreach ($d in 'data','uploads','config','convert','logs') {
  New-Item -ItemType Directory -Force "C:\SmallTime\$d" | Out-Null
  icacls "C:\SmallTime\$d" /grant "NT SERVICE\SmallTime:(OI)(CI)M"
}
icacls C:\SmallTime\.env /inheritance:r /grant:r "Administrators:F" "SYSTEM:F" "NT SERVICE\SmallTime:R"

config\ braucht Schreibrecht, weil security.json beim ersten Start und über Administration → Sicherheit geschrieben wird. convert\ braucht Schreibrecht für mapping.json und den Konvertierungsbericht.

Note

Das virtuelle Konto NT SERVICE\SmallTime existiert erst, nachdem der Dienst angelegt wurde. Reihenfolge: Dienst anlegen (siehe unten), dann icacls ausführen.


Paket installieren

# Paket nach C:\SmallTime entpacken, dann:
Set-Location C:\SmallTime
npm install --omit=dev
notepad .env               # FRONTEND_ORIGIN, SECURE_COOKIE, TRUST_PROXY prüfen
npm start                  # Probelauf im Vordergrund, Ctrl+C beendet

Die .env wird aus dem Arbeitsverzeichnis geladen; der Dienst muss daher in C:\SmallTime starten. Werte siehe Konfiguration.


Als Dienst mit NSSM

NSSM startet node.exe als Windows-Dienst, leitet stdout/stderr in Dateien um und rotiert sie.

$nssm = 'C:\Tools\nssm\win64\nssm.exe'
$node = (Get-Command node).Source          # z. B. C:\Program Files\nodejs\node.exe

& $nssm install SmallTime $node app.cjs
& $nssm set SmallTime AppDirectory C:\SmallTime
& $nssm set SmallTime DisplayName "SmallTime 2027"
& $nssm set SmallTime Description "SmallTime 2027 Zeiterfassung (Node.js, Port 55000)"
& $nssm set SmallTime Start SERVICE_DELAYED_AUTO_START
& $nssm set SmallTime AppStdout C:\SmallTime\logs\smalltime.log
& $nssm set SmallTime AppStderr C:\SmallTime\logs\smalltime-error.log
& $nssm set SmallTime AppRotateFiles 1
& $nssm set SmallTime AppRotateOnline 1
& $nssm set SmallTime AppRotateBytes 10485760
& $nssm set SmallTime AppStopMethodConsole 10000     # Ctrl+C senden, 10 s warten (sauberes Schliessen der DB)
& $nssm set SmallTime AppExit Default Restart
& $nssm set SmallTime AppRestartDelay 5000

# Virtuelles Dienstkonto statt LocalSystem (danach icacls aus dem Abschnitt Pfade ausführen)
sc.exe config SmallTime obj= "NT SERVICE\SmallTime"

# Umgebungsvariablen alternativ zur .env (haben Vorrang vor .env):
# & $nssm set SmallTime AppEnvironmentExtra NODE_ENV=production PORT=55000

Start-Service SmallTime
Get-Service SmallTime
Get-Content C:\SmallTime\logs\smalltime.log -Tail 20 -Wait

Bedienung: Start-Service, Stop-Service, Restart-Service SmallTime. Entfernen: nssm remove SmallTime confirm.

Tip

Die Logdateien rotieren nach Grösse, alte Dateien löscht NSSM aber nicht. Aufräumen per geplanter Aufgabe, z. B. Dateien älter als 90 Tage in C:\SmallTime\logs löschen.


Alternative: Aufgabenplanung

Ohne Zusatzsoftware, aber ohne Neustart bei Absturz und ohne Log-Rotation.

C:\SmallTime\start-smalltime.cmd:

@echo off
cd /d "%~dp0"
if not exist logs mkdir logs
"C:\Program Files\nodejs\node.exe" app.cjs >> logs\smalltime.log 2>&1

Aufgabe anlegen (als SYSTEM oder als Dienstkonto mit Kennwort):

$action   = New-ScheduledTaskAction -Execute 'C:\SmallTime\start-smalltime.cmd' -WorkingDirectory 'C:\SmallTime'
$trigger  = New-ScheduledTaskTrigger -AtStartup
$settings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit ([TimeSpan]::Zero) -RestartCount 3 -RestartInterval (New-TimeSpan -Minutes 1)
Register-ScheduledTask -TaskName 'SmallTime' -Action $action -Trigger $trigger -Settings $settings -User 'SYSTEM' -RunLevel Limited
Start-ScheduledTask -TaskName 'SmallTime'

Warning

Stop-ScheduledTask beendet den Prozess hart (kein SIGINT). SQLite im WAL-Modus ist dagegen robust, eine laufende Schreiboperation wird aber abgebrochen. Für Produktivbetrieb NSSM bevorzugen.


Firewall

Port 55000 nur öffnen, wenn kein Reverse-Proxy auf demselben Host läuft und der Zugriff auf ein internes Netz beschränkt ist. Mit Proxy auf demselben Host bleibt 55000 zu und nur 443 (und 80 für die Weiterleitung/ACME) wird geöffnet.

# Nur Proxy-Ports öffentlich
New-NetFirewallRule -DisplayName 'SmallTime HTTPS' -Direction Inbound -Protocol TCP -LocalPort 443 -Action Allow
New-NetFirewallRule -DisplayName 'SmallTime HTTP (Redirect/ACME)' -Direction Inbound -Protocol TCP -LocalPort 80 -Action Allow

# Nur falls der Proxy auf einem anderen Host läuft: 55000 nur für dessen IP
New-NetFirewallRule -DisplayName 'SmallTime Backend' -Direction Inbound -Protocol TCP -LocalPort 55000 `
  -RemoteAddress 10.0.0.10 -Action Allow

Die automatische Windows-Rückfrage «Node.js darf kommunizieren» nicht pauschal für «Öffentlich» bestätigen.

Note

Node.js lauscht auf allen Schnittstellen (listen(PORT) ohne Host). Eine Bindung nur an 127.0.0.1 ist nicht konfigurierbar; die Abschottung erfolgt über die Firewall.


HTTPS unter Windows

Varianten:

  • Caddy für Windows als Dienst (einfachste Variante, automatische Zertifikate), Konfiguration siehe Reverse-Proxy und HTTPS.
  • nginx für Windows, Konfiguration wie dort beschrieben.
  • IIS mit Application Request Routing und URL Rewrite: Reverse-Proxy-Regel auf http://127.0.0.1:55000/{R:1}, Feature WebSocket-Protokoll aktivieren, Server-Variablen HTTP_X_FORWARDED_PROTO = https setzen, Preserve Host Header aktivieren (appcmd set config -section:system.webServer/proxy /preserveHostHeader:true /commit:apphost). Keine eigene CSP im IIS setzen.

In jedem Fall in .env: TRUST_PROXY=true, SECURE_COOKIE=true, FRONTEND_ORIGIN=https://…; in config\security.json: "allowLocalhost": false.


dev.cmd und prod.cmd im Repository

Beide liegen im Repository-Stamm und setzen npm im PATH voraus.

dev.cmd – Entwicklung:

  1. npm ci in frontend\ und backend\, falls node_modules fehlt.
  2. backend\.env aus backend\.env.example erzeugen, falls nicht vorhanden.
  3. Zwei Konsolenfenster: npm run dev im Frontend (Vite, http://localhost:55001) und im Backend (tsx watch, http://localhost:55000).

prod.cmd – Betriebspaket bauen:

  1. npm ci wie oben, falls node_modules fehlt (bestehende node_modules werden nicht aktualisiert).
  2. npm run build im Frontend (tsc -b && vite build) und im Backend (esbuild).
  3. node scripts\package-dist.mjs → Ordner dist\ im Repository-Stamm (Inhalt wird vorher geleert).
  4. Ausgabe der Plesk-Schritte.
rem Öffentliche Adresse direkt in die erzeugte .env schreiben lassen:
set SMALLTIME_ORIGIN=https://zeit.example.ch
prod.cmd

Warning

Jeder Lauf von prod.cmd erzeugt eine neue dist\.env mit neuem SESSION_SECRET. Beim Update eines Servers die .env (sowie config\, data\, uploads\) nicht mitkopieren.

Details zum Paket: Entwicklung.


Weiter mit: Reverse-Proxy und HTTPS · Konfiguration · Sicherheit und Betrieb

Clone this wiki locally