- Rust 49.5%
- JavaScript 32.7%
- Shell 13.3%
- Awk 1.7%
- Dockerfile 1.7%
- Other 1.1%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .cargo | ||
| .forgejo/workflows | ||
| .githooks | ||
| docs | ||
| examples | ||
| scripts | ||
| src | ||
| tests | ||
| .dockerignore | ||
| .gitignore | ||
| .updatarr.yaml | ||
| AGENTS.md | ||
| build.rs | ||
| Cargo.lock | ||
| Cargo.toml | ||
| CLAUDE.md | ||
| cliff.toml | ||
| deny.toml | ||
| Dockerfile | ||
| GEMINI.md | ||
| Justfile | ||
| README.md | ||
| rust-toolchain.toml | ||
| RUST_REBUILD.md | ||
rust-template
Modulare Vorlage für Rust-Microservices im Wuastbude-Homelab: Axum, Tokio, gemeinsame Libraries aus Kellnr, Dracula-UI und ein statisches Nonroot-Image auf scratch.
Zuständigkeit
wuast-crates ist das eigenständige Repository für wuast-common und wuast-ui. Wiederverwendbare Konfigurationsparser, Problem-Details-Antworten, Logging, Shutdown und UI-Komponenten werden dort entwickelt und veröffentlicht. Dieses Repository enthält die Service-Konfiguration, Domain-Fehler, Handler und Router-Zusammenstellung. Die verbindlichen Regeln stehen in AGENTS.md; CLAUDE.md verweist auf dieselbe Zuständigkeit.
rust-template ist die verbindliche Referenz für Grundaufbau, CI, Tooling, Justfile, Agenten-Regeln und Container/Lifecycle aller Apps. wuast-ui ist der gemeinsame UI-Baukasten: Apps wählen und arrangieren Elemente frei und verwenden dokumentierte Optionen für Schriftgröße, semantische Farben, Größen und Dichte. Der Grundstil und seine Defaults bleiben in der Library, damit zentrale Styling-Updates beim nächsten Dependency-Update übernommen werden. Fehlende Bausteine oder Optionen werden dort kompatibel ergänzt und vor der App-Integration veröffentlicht. Potenziell inkompatible Änderungen benötigen vorher die ausdrückliche Entscheidung des Users. CLAUDE.md und GEMINI.md enthalten über Symlinks denselben vollständigen Regelsatz wie AGENTS.md.
Entwicklung
Voraussetzungen: Rust über rustup (Toolchain aus rust-toolchain.toml), just, Git; Docker für die isolierten Datenbanktests und Container-Checks. CI stellt die Testdienste selbst bereit.
just setup # gepinnte cargo-deny/cargo-machete/git-cliff-Versionen und Hooks
just run
just gate # Pflicht bei funktionalen Änderungen; derselbe Aufruf läuft in Forgejo
just push # Git-Push; nach Erfolg repo-eigenes target/ vollständig aufräumen
just push origin main oder just push --set-upstream origin feature/mein-thema reichen Git-Argumente unverändert weiter. Nach einem erfolgreichen tatsächlichen Push entfernt cargo clean ausschließlich das lokale target/, einschließlich Coverage-/Browser-Ausgaben. Fehler und Dry-Runs erhalten den Ordner. just clean räumt separat auf; globale Cargo-/Rustup-/Docker-Caches und Anwendungsdaten bleiben erhalten. Der nächste lokale Build kompiliert erneut. Notwendige kompakte Nachweise vorher dokumentieren; direkter git push oder ein IDE-Push lösen die Bereinigung nicht aus. Git bietet keinen lokalen Post-Push-Hook.
just gate prüft Formatierung, Clippy ohne Warnungen, alle Tests, RustSec-Advisories/Dependency-Bans und ungenutzte Dependencies. Cargo-Builds und Tests verwenden --locked. Duplicate-Versionen werden entsprechend deny.toml als Warnungen gemeldet; Lizenzprüfungen sind nicht Teil dieses Gates. Reine Dokumentation, beschreibende Metadaten und nachweislich ungenutzte Migrationsreste benötigen nach Prüfung des Diffs keinen lokalen Gate; die genaue Abgrenzung steht in AGENTS.md.
Tests prüfen eigene Verarbeitung anhand definierter Inputs und unabhängig erwarteter Ergebnisse. Keine Quelltext-, Versionspin-, UI-Titel- oder CSS-Klassen-Prüfungen. Der verbindliche Standard und die Testebenen sind in docs/testing.md dokumentiert und gelten für alle abgeleiteten Apps.
Bestehende Apps migrieren
Zuerst old/, working/ und den vollständigen Template-Grundaufbau herstellen; die vorher belegte Git-/Image-Identität erhalten. Danach vor der fachlichen Rust-Implementierung ein vollständiges, quell- und laufzeitgestütztes App-/Dependency-Inventar erstellen. Jede Funktion muss vollständig ersetzt und durch tatsächlich ausgeführte Szenarien einschließlich Daten und Nebenwirkungen nachgewiesen werden. Altcode erst nach geprüftem Ersatz entfernen; keine Platzhalter oder Teilstände als fertige Migration. Die echten Rust-Tests laufen über just gate in CI; just parity ist optional, kein dauerhafter Go-Doppelrunner erforderlich. Verbindlicher Startauftrag, Inventarvorlage, Abschlussnachweis.
Konfiguration
| Variable | Default | Verhalten |
|---|---|---|
HOST |
0.0.0.0 |
IPv4-/IPv6-Adresse, z. B. 127.0.0.1 oder ::1; keine DNS-Namen |
PORT |
8080 |
u16; 0 lässt das Betriebssystem einen freien Port wählen |
SHUTDOWN_TIMEOUT_SECS |
10 |
Positive Zahl; gemeinsames begrenztes HTTP-/Worker-Draining nach SIGTERM/SIGINT; anschließend separat begrenztes Schließen der Verbindungen |
LOG_LEVEL |
info |
error, warn, info, debug, trace; abgeschlossene HTTP-Antworten mit Status, Dauer und Request-ID ab info |
LOG_FORMAT |
automatisch | Pretty bei TTY, JSON bei Pipe/Container; json/pretty überschreiben die Auswahl |
RUST_LOG |
— | Individueller Tracing-Filter, überschreibt LOG_LEVEL |
Fehlende Konfigurationswerte verwenden Defaults. Ungültige oder nicht als Unicode lesbare Werte für Host, Port und Shutdown-Timeout verhindern den Start. Der Log nennt die tatsächlich gebundene Adresse, auch bei PORT=0.
HTTP-Vertrag
| Pfad | Antwort |
|---|---|
GET /healthz |
200, {"status":"ok"} |
GET /ready |
200 mit ready oder 503 mit not_ready |
GET /api/v1/status |
JSON mit name, version, status, uptime_secs |
GET / |
Dracula-Dashboard |
GET /_assets/* |
Eingebettete Assets aus wuast-ui |
Domain-Fehler sowie unbekannte API-Routen und nicht unterstützte API-Methoden liefern RFC-9457-Problem-Details mit application/problem+json. Interne Fehlerdetails werden ausschließlich serverseitig geloggt. Neue Handler müssen ihre Domain- und Extractor-Fehler in AppError überführen, damit dieser Vertrag erhalten bleibt.
Einen Service initialisieren
Nach Erstellung eines neuen Forgejo-Repositories aus diesem Template:
bash scripts/init-service.sh --dry-run mein-service harbor.wuastbude.de/mein-projekt/mein-image
just init mein-service harbor.wuastbude.de/mein-projekt/mein-image
just gate
just docker-build
Der Initialisierer verlangt den Service-Namen und das vollständige Image-Repository ohne Tag/Digest. Bei bestehenden Apps dieses Ziel vorher aus alter CI und Deployment belegen und unverändert übernehmen; bei neuen Apps ausdrücklich festlegen. Paket/Lockfile, Rust-Imports, Tests und Binary-Pfade werden umbenannt; Justfile und Release inklusive Harbor-Login und unsignierter SBOM verwenden das angegebene Image-Ziel. Binary- und Image-Name dürfen verschieden sein. Gitremote/Owner bleiben bestehen, die CI verwendet den tatsächlichen Forgejo-Repository-Kontext. Der Namespace rust-template gehört ausschließlich zur Referenz selbst.
Für Image-Releases erforderlich: HARBOR_USERNAME und HARBOR_PASSWORD. Die SPDX-SBOM wird ohne Signierung im eigenen Harbor mit dem Image-Digest verknüpft und zurückgeprüft; siehe SBOM-Vertrag. Der gemeinsame S3-Compiler-Cache benötigt lokal gültige Credentials und in CI AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY; Endpoint/Bucket haben gemeinsame Defaults. Einrichtung und Buildpfade. Der Release bricht bei fehlender erforderlicher Konfiguration vor dem Image-Push ab.
Releases und Container
PRs durchlaufen .forgejo/workflows/ci.yml; Pushes auf main und manuelle Releases .forgejo/workflows/release.yaml. Release-Läufe werden serialisiert und laufende Veröffentlichungen nicht abgebrochen. Fehler bei der Versionsberechnung führen zu einem fehlgeschlagenen Workflow. Wiederholungen verwenden die Notes des bereits getaggten Releases.
Ein erneuter Lauf desselben getaggten Commits darf dessen Release wiederholen. Spätere reine test:-/style:-Commits erzeugen keinen Release und überschreiben keine veröffentlichte Image-Version. Eine berechnete Version auf einer anderen Git-Historie stoppt die Veröffentlichung vor dem Build.
git-cliff bestimmt die Version aus Conventional Commits. Diese wird als APP_VERSION beim Build übergeben und erscheint identisch im Image-Tag, OCI-Label, Startup-Log, Status-Endpunkt und HTTP-User-Agent. Lokale Builds verwenden die Cargo-Paketversion. APP_VERSION akzeptiert stabile SemVer-Versionen ohne v-Präfix.
Das Image verwendet scratch, UID/GID 65532, CA-Roots, Europe/Berlin, /tmp und Cargo-Manifeste für SBOM-Scanner. Bei readOnlyRootFilesystem benötigen schreibende Anwendungen ein separates temporäres Volume. Health-Probes erfolgen per HTTP durch den Kubelet. Die unsignierte SPDX-SBOM wird am Image-Digest erstellt, im eigenen Harbor veröffentlicht und zurückgeprüft; scratch ersetzt keine Dependency-Advisory-Prüfung.
CI-Actions sind auf Commit-SHAs gepinnt. scripts/ci-tools.lock enthält Versionen, feste Download-URLs und SHA256-Hashes der Linux/amd64-Tools. Aktualisierungen müssen URL, Version und verifizierten Hash gemeinsam ändern; der Installer führt ungeprüfte Downloads nicht aus.
Weitere Befehle: just test, just clippy, just fmt, just outdated, just build, just version, just changelog, just verify-image [tag]. Details: Architektur.
Optionale PostgreSQL- und Redis-/Dragonfly-Referenz
Eigene PostgreSQL-Daten verwenden SeaORM 2.0.4 mit nativen, versionierten Rust-Migrationen; Redis/Dragonfly verwendet redis 1.7.1. Beides liegt vollständig in diesem Template. Apps ohne Bedarf lassen die Features aus. Builds brauchen keine Datenbank und keine SQL-Vorbereitung.
# Dauerhaft benötigte Features einmalig in Cargo.toml unter [features].default setzen.
DATABASE_URL='postgres://user:password@localhost/app' \
REDIS_URL='redis://localhost/' \
cargo run --locked --features postgres,redis
just schema-diagram # Mermaid aus frisch migrierter Testdatenbank aktualisieren
just gate # einschließlich Upgrade, Parallelstart, Rollback und Diagrammprüfung
Vor HTTP/Workern werden die Migrationen unter PostgreSQL-Lock ausgeführt. Fehler verhindern den Start; Abhängigkeitsausfälle setzen /ready auf 503. Die kleine Domain projects/tasks zeigt CRUD, JSONB, Filter, Pagination, Relationen und Transaktionen. Sie wird beim Ableiten durch die App-Domain ersetzt. Datenbank-Vertrag und Konfiguration, automatisch erzeugtes Schema.
Coverage
just gate, just test und CI führen die vollständigen echten Tests ohne Coverage-Instrumentierung aus. just coverage misst separat während der Entwicklung und zeigt Zusammenfassung sowie fehlende Zeilen im Terminal; just coverage html erzeugt HTML nur auf ausdrücklichen Bedarf. Keine LCOV-/JSON-/Summary-Dateien, Forgejo-Reportartefakte oder Screenshots. Lokale Einrichtung über just setup; Messverfahren und Grenzen.
Hintergrundprozesse und Betriebsinformationen
src/workers.rs komponiert fachliche Jobs über den veröffentlichten Common-Supervisor. Die optionale Dependency-Probe zeigt den vollständigen Weg: begrenzte Verarbeitung, gemeinsame Job-ID, beobachtete Job-Fehler, Readiness und geordneter Shutdown. /metrics liefert HTTP-/Job-Messungen; Request-IDs erscheinen in Response und JSON-Logs. Vertrag und Erweiterungspunkte.