Diese Datei ist in Markdown geschrieben und kann mit
<Strg><Shift>vin Visual Studio Code leicht gelesen werden. Näheres zu Markdown gibt es z.B. bei Markdown Guide. Die Anleitung ist für Windows 11; für andere Betriebssysteme oder Windows-Emulationen sind Anpassungen notwendig.
- Inhalt
- Vorbereitung der Installation
- Download- und ggf. Upload Geschwindigkeit
- Lokaler Appserver mit dem Watch-Modus
- Tests aufrufen
- Docker-Image und Docker Compose
- Statische Codeanalyse und Formattierer
- Sicherheitslücken
- OpenAPI
- AsciiDoctor und PlantUML
- Empfohlene Code-Konventionen
- Port bereits belegt?
-
Das Beispiel nicht in einem Pfad mit Leerzeichen installieren. Viele Javascript-Bibliotheken werden unter Linux entwickelt und dort benutzt man keine Leerzeichen in Pfaden. Ebenso würde ich das Beispiel nicht auf dem Desktop auspacken bzw. installieren.
-
Bei GitHub oder GitLab registrieren, falls man dort noch nicht registriert ist.
In einem Webbrowser kann man z.B. mit der URL https://speed.cloudflare.com die
Download- und die Upload-Geschwindigkeit testen.
Alternativ kann man durch das Kommando fast in einer Powershell die aktuelle
Download-Geschwindigkeit ermitteln. Mit der zusätzlichen Option --upload kann
zusätzlich die aktuelle Upload-Geschwindigkeit ermittelt werden.
Durch pnpm run dev wird der Appserver im Watch-Modus für die
Entwicklung gestartet, d.h. bei Code-Änderungen wird der Server automatisch
neu gestartet. pnpm start startet den Appserver ohne Watch-Modus.
Beim Starten des Appservers wird außerdem mit Prisma die DB-Verbindung
aufgebaut. Der Benutzername und das Passwort sind in der Datei
src\config\db.ts auf admin und p voreingestellt. Durch die Property
db.populate in src\config\resources\app.toml wird festgelegt, ob die
DB buch neu geladen wird.
Wenn der Appserver mit Bun statt Node gestartet werden soll, ruft man
bun run dev:bun auf und muss zuvor in src\config\resources\app.toml die
Property server.runtime auf Bun setzen bzw. auskommentieren. Außerdem muss
man in .env die Properties für die DB-URLs ohne TLS definieren.
Folgende Voraussetzungen müssen oder sollten erfüllt sein:
- Der DB-Server muss gestartet sein.
- Der Mailserver muss gestartet sein.
- Der Appserver muss gestartet sein.
Nun können die Tests in einer Shell aufgerufen werden:
pnpm tBei der Fehlersuche ist es ratsam, nur eine einzelnen Testdatei oder sogar geziehlt eine Test-Funktion aufzurufen, z.B.:
# Filter für den Namen der Testdatei
pnpm test GET-id
# Test-Funktion an einer bestimmten Zeile in der Testdatei
pnpm test test/integration/rest/GET-id.test.mts:45Man kann auch nur die Unit-Tests, d.h. ohne gestartete Server, laufen lassen, um schnelles Feedback zu bekommen:
pnpm test --project unitFür ein minimales Basis-Image gibt es z.B. folgende Alternativen:
- Hardened Image mit Debian 13
- Debian Trixie slim: Trixie ist der Codename für Debian 13
- Alpine
- C-Bibliothek musl statt von GNU
- ash als Shell
- apk ("Alpine Package Keeper") als Package-Manager
Durch eine Default-Datei Dockerfile kann man ein Docker-Image erstellen und
durch ein Multi-stage Build optimieren. Eine weitverbreitete Namenskonvention
für ein Docker-Image ist <registry-name>/<username>/<image-name>:<image-tag>.
Ob das Dockerfile gemäß Best Practices (https://docs.docker.com/develop/develop-images/dockerfile_best-practices)
erstellt wurde, kann man mit Hadolint überprüfen.
# Hardened Image mit Debian 13 (Trixie) slim
Get-Content Dockerfile | docker run --rm --interactive hadolint/hadolint:v2.15.1-debian
docker build bake
# Debian Trixie slim
Get-Content Dockerfile.trixie | docker run --rm --interactive hadolint/hadolint:v2.15.1-debian
docker build bake trixie
# Alpine
Get-Content Dockerfile.alpine | docker run --rm --interactive hadolint/hadolint:v2.15.1-debian
docker build bake alpineMit dem Unterkommando history kann man ein Docker-Image und die einzelnen Layer
inspizieren:
docker history juergenzimmermann/buch:2026.10.1-hardened
docker history juergenzimmermann/buch:2026.10.1-trixie
docker history juergenzimmermann/buch:2026.10.1-alpineMit dem Unterkommando inspect kann man die Metadaten, z.B. Labels, zu einem
Image inspizieren:
docker inspect juergenzimmermann/buch:2026.10.1-hardened
docker inspect juergenzimmermann/buch:2026.10.1-trixie
docker inspect juergenzimmermann/buch:2026.10.1-alpineMit dem Unterkommando sbom (Software Bill of Materials) von docker kann man
inspizieren, welche Bestandteilen in einem Docker-Images enthalten sind, z.B.
npm-Packages oder Debian-Packages.
docker sbom juergenzimmermann/buch:2026.10.1-hardened
docker sbom juergenzimmermann/buch:2026.10.1-trixie
docker sbom juergenzimmermann/buch:2026.10.1-alpineMit Docker Compose und der Konfigurationsdatei compose.yml im Verzeichnis
extras\compose\buch lässt sich der Container mit dem "hardened" Basis-Image mit
Node und Debian Trixie (13) Slim folgendermaßen starten und später in einer
weiteren PowerShell herunterfahren.
cd extras\compose\buch
# Shell fuer buch-Server mit Trixie-Image zzgl. DB-Server und Mailserver
docker compose up
# Nur zur Fehlersuche: weitere Shell für bash/ash bei Trixie oder Alpine
cd extras\compose\buch
docker compose exec buch bash
id
env
exit
# 2 Shells fuer Fehlersuche im Netzwerk:
cd extras\compose\debug
docker compose up
docker compose exec busybox sh
nslookup postgres
exit
# Shell: buch-Server einschl. DB-Server und Mailserver herunterfahren
cd extras\compose\buch
docker compose downOxlint wird durch oxslint.config.ts` konfiguriert und durch folgendes Skript ausgeführt:
pnpm run lintOxfmt (statt Prettier) ist ein Formatierer, der durch oxfmt.config.mts
konfiguriert und durch folgendes Skript ausgeführt wird:
pnpm run fmtSiehe extras\compose\sonarqube\ReadMe.md.
Mit dem Unterkommando audit von pnpm kann man npm_modules auf Sicherheitslücken
analysieren. Wenn man - sinnvollerweise - nur die dependencies aus package.json
berücksichtigen möchte, ergänzt man die Option -P ("Production"):
pnpm audit --prodMit OWASP Dependency Check werden alle in node_modules installierten
Packages mit den CVE-Nummern der NIST-Datenbank abgeglichen.
Von https://nvd.nist.gov/developers/request-an-api-key fordert man einen "API Key"
an, um im Laufe des Semesters mit OWASP Dependency Check die benutzte Software
("3rd Party Libraries") auf Sicherheitslücken zu prüfen. Diesen API Key trägt
man im Skript scripts\dependency-check.mts als Wert der Variablen nvdApiKey ein.
cd scripts
node dependency-check.mtsMit dem Unterkommando quickview von Scout kann man sich zunächst einen
groben Überblick verschaffen, wieviele Sicherheitslücken in den Bibliotheken im
Image enthalten sind:
docker scout quickview juergenzimmermann/buch:2026.10.1-hardened
docker scout quickview juergenzimmermann/buch:2026.10.1-trixie
docker scout quickview juergenzimmermann/buch:2026.10.1-alpineDabei bedeutet:
- C ritical
- H igh
- M edium
- L ow
Sicherheitslücken sind als CVE-Records (CVE = Common Vulnerabilities and Exposures)
katalogisiert: https://www.cve.org (ursprünglich: https://cve.mitre.org/cve).
Übrigens bedeutet CPE in diesem Zusammenhang Common Platform Enumeration.
Die Details zu den CVE-Records im Image kann man durch das Unterkommando cves
von Scout auflisten:
docker scout cves juergenzimmermann/buch:2026.10.1-hardened
docker scout cves --format only-packages juergenzimmermann/buch:2026.10.1-hardenedStatt der Kommandozeile kann man auch den Menüpunkt "Docker Scout" im Docker Dashboard verwenden.
Durch die Decorators @Api...() kann man OpenAPI bzw. Swagger in den
Controller-Klassen und -Methoden konfigurieren und dann in einem Webbrowser mit
https://localhost:3000/swagger aufrufen. Die Swagger JSON Datei kann man mit
https://localhost:3000/swagger-json abrufen.
Siehe extras\doc\projekthandbuch\ReadMe.md.
In Anlehnung an die Guidelines von TypeScript
- Klassennamen mit PascalCase
- Union-Types (mit Strings) statt Enums
- Attribute und Funktionen mit camelCase
#für private Properties- private Properties nicht mit vorangestelltem _
- Interfaces nicht mit vorangestelltem I
- Higher-Order Functions: [...].
forEach(), [...].filter() und [...].map() - Arrow-Functions statt function()
undefinedverwenden und nichtnull- Geschweifte Klammern bei if-Anweisungen
- Maximale Dateigröße: 400 Zeilen
- Maximale Funktionslänge: 75 Zeilen
Falls der Server nicht gestartet werden kann, weil z.B. der Port 3000 belegt ist,
kann man bei Windows in der Powershell zunächst die ID vom Betriebssystem-Prozess ermitteln,
der den Port belegt und danach diesen Prozess beenden:
netstat -ano | findstr ':3000'
taskkill /F /PID <Prozess-ID>Bei macOS:
ps -af
kill <Prozess-ID>
# ggf.
kill -9 <Prozess-ID>