dotnet restore auf einem gemieteten Remote-Mac (self-hosted Runner, geteilter Pool) ausführen, während nuget.org oder Upstream-Feeds eine internationale oder proxifierte Strecke durchlaufen. Dieser Leitfaden liefert: eine geordnete Spiegelkette in NuGet.Config, Startwerte für MaxHttpRequestsPerSource, die Platzierung von globalPackagesFolder bzw. NUGET_PACKAGES, das Paar RestoreLockedMode mit packages.lock.json sowie eine Checkliste zur zentralen Paketverwaltung (CPM). Einstieg ohne Login: Blog-Übersicht, MacPull-Startseite und die verlinkten CI-Artikel.
- Flache Feed-Liste: Jedes Paket fragt zuerst nuget.org ab; der interne Spiegel wird nie bevorzugt.
- Unbegrenztes HTTP: Standard-Fan-out erzeugt massenhaft kleine Random-Writes auf geteilter NVMe und TLS-Overhead.
- Drift ohne Lock: Die CI lädt „was sich heute auflöst“; Retries über Grenzen hinweg verschleiern Versionsverschiebungen bis zur Release.
① Entscheidungsmatrix: Defaults vor Parallelität festlegen
Nutzen Sie die Tabelle als Checkliste. Ändern Sie nur jeweils eine Dimension: gleichzeitig Spiegel und maxHttpRequestsPerSource zu verändern erschwert Regressionen.
| Szenario | Spiegel- / Feed-Strategie | MaxHttpRequestsPerSource | globalPackagesFolder | RestoreLockedMode |
|---|---|---|---|---|
| Azure Artifacts + nuget.org | Upstream in Artifacts; packageSourceMapping bindet Microsoft.* an Upstream, interne IDs an Artifacts |
8 im Pool; 4 bei wachsender SSD-Warteschlange | /usr/local/ci/nuget/global-packages per NUGET_PACKAGES |
true in CI sobald packages.lock.json versioniert ist |
| Nexus / selbst gehostetes BaGet | Spiegel zuerst; Fallback auf nuget.org nur mit Policy | 6–8; senken wenn die Spiegel-CPU steigt | Gemeinsamer Pool-Pfad; alte Ordner außerhalb der Peak-Zeiten bereinigen | true auf Release-Branches; false auf Experimentier-Branches möglich |
| Nur OSS, instabile Leitung | Regionaler Genehmigungs-Spiegel oder nuget.org mit längeren Timeouts | 4 als Start; nur erhöhen wenn p95-Restore stabil bleibt | Lokale SSD — kein Home auf SMB | true sobald der Graph stabil ist; Lock nach jedem Bump erneuern |
| Monorepo mit CPM | Mapping nutzt dieselben Quellnamen wie ohne CPM | Wie oben — CPM verringert nicht die HTTP-Anzahl | Geteilter globaler Ordner bleibt bester Hebel zur Deduplizierung | Lock pro Projekt oder zentrale Props je nach SDK-Version |
② NuGet.Config-Spiegelkette: ausführbares Grundgerüst
Benennen Sie jeden Feed, mappen Sie Paket-IDs explizit und legen Sie globalPackagesFolder auf der SSD des Mac mini neben Ihre Build-Wurzeln. Ersetzen Sie die URLs durch Ihre freigegebenen Endpunkte.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<config>
<add key="globalPackagesFolder" value="/usr/local/ci/nuget/global-packages" />
<add key="maxHttpRequestsPerSource" value="8" />
</config>
<packageSources>
<clear />
<add key="corp" value="https://pkgs.dev.azure.com/ihre-org/_packaging/main/nuget/v3/index.json" />
<add key="nugetorg" value="https://api.nuget.org/v3/index.json" />
</packageSources>
<packageSourceMapping>
<packageSource key="corp">
<package pattern="Contoso.*" />
</packageSource>
<packageSource key="nugetorg">
<package pattern="*" />
</packageSource>
</packageSourceMapping>
</configuration>
In der CI setzen Sie NUGET_PACKAGES oder dotnet restore --configfile ci.NuGet.Config, damit Entwicklerrechner unverändert bleiben. Unter macOS denselben Credential-Provider wie unter Windows/Linux installieren (z. B. für Azure Artifacts) und kurzlebige Tokens aus dem Secret Store injizieren — niemals PATs in die Config committen. Vor dem scharfen Lock-Modus einen minimalen Restore auf ein Referenzprojekt fahren: der erste blockierende Identifier erscheint klar in den Logs.
Für Abgleich mit JVM- und Front-End-Pipelines auf demselben Runner siehe Gradle & Maven auf Remote-Mac, Git, npm und Homebrew in grenzüberschreitender CI sowie Deno & JSR Pull-Matrix.
③ MSBuild- / CLI-Parameter vs. NuGet.Config
| Parameter | Ort | Typischer CI-Wert | Hinweis |
|---|---|---|---|
| maxHttpRequestsPerSource | NuGet.Config → <config> |
4–8 | Deckelt gleichzeitige Requests pro Feed; Haupthebel gegen IO-Spitzen |
| RestoreMaxHttpRequestsPerSource | MSBuild / CLI -p: |
Überschreibt oder spiegelt Config | Nützlich wenn Pipeline keine Config-Datei schreiben darf |
| RestoreLockedMode | Directory.Build.props oder CLI, nur CI |
true |
Verlangt eingechecktes Lockfile — gewollter Fehler bei Drift |
| RestorePackagesWithLockFile | Projekt oder Props | true |
Erzeugt das Lock; PR-Review-Pflicht für Änderungen |
| ContinuousIntegrationBuild | CI-Umgebung | true |
Stabilisiert Asset-Metadaten; mit Restore-Lock kombinieren |
Kopierbare CI-Zeile:
dotnet restore /p:RestoreLockedMode=true /p:ContinuousIntegrationBuild=true
④ Central Package Management: Lock-kompatible Parameter
CPM verschiebt Versionen nach Directory.Packages.props; Downloads laufen weiter über dieselbe NuGet-HTTP-Schicht. Behalten Sie Feed-Namen und Mappings bei klassischen Repos bei, damit Security-Reviews vergleichbar bleiben.
| Artefakt | Rolle | CI-Folge |
|---|---|---|
Directory.Packages.props |
Zentrale PackageVersion-Einträge |
Eine Fläche für Bumps; Spiegel-Gesundheit bleibt kritisch |
ManagePackageVersionsCentrally |
Schaltet CPM in Directory.Build.props ein |
Einmalig an der Repo-Wurzel setzen |
CentralPackageTransitivePinningEnabled |
Optional Transitives aus Zentraldatei pinnen | Nur nach grünen Restores mit Lock aktivieren |
PackageVersionOverride |
Projektbezogene Ausnahme | Jede Ausnahme dokumentieren — verriegelte CI bricht sonst ab |
⑤ Rollout in fünf Schritten auf dem Mac-Agenten
global.json mit exakter Feature-Band committen, damit Lock- und CPM-Verhalten auf allen Hosts identisch bleibt.ci.NuGet.Config neben dem Repo oder unter ~/.nuget/NuGet für den CI-Benutzer; NUGET_PACKAGES als erste Zeile im Job exportieren.RestorePackagesWithLockFile einschalten, lokal restoren, packages.lock.json committen, danach RestoreLockedMode=true in der CI setzen.maxHttpRequestsPerSource=8 starten; SSD-Warteschlange beobachten; vor Netzwerk-Triage auf 4 reduzieren.dotnet restore --verbosity minimal auf ein kleines Projekt vor dem Solution-Restore — TLS und Cache werden warmgefahren.⑥ Kennzahlen für Architektur- und Runbooks
Acht parallele Requests je Quelle ist ein gängiges Limit auf geteilten Apple-Silicon-Runnern; wechseln Sie zu vier, wenn parallel Git LFS oder Docker zieht. Restore im Lock-Modus deckt Drift sofort auf — behalten Sie einen wöchentlichen Job ohne Lock auf einem Wartungsbranch. Ein globalPackagesFolder pro Pool schlägt oft ein Ordner pro Job, sofern Compliance öffentliche und private Artefakte auf einem Volume erlaubt.
⑦ FAQ: NuGet auf Remote-Mac-Runnern
Sollen alle Jobs denselben globalPackagesFolder teilen? Meist ja: ein ausreichend großes NVMe-Verzeichnis dedupliziert entpackte Pakete. Trennen nur bei strikter Trennungspflicht für private Artefakte.
Was passiert bei RestoreLockedMode=true? Jede Abweichung vom packages.lock.json scheitert. Nach Versionsupdates das Lock regenerieren und committen.
Wie wirkt MaxHttpRequestsPerSource auf dotnet restore? Es begrenzt gleichzeitige Verbindungen pro Feed. Zu hohe Werte erhöhen TLS- und Random-Write-Last auf gemeinsamer SSD.
Ersetzt CPM den Lock-Modus? Nein — CPM bündelt Versionen, das Lock fixiert den Graphen. Kombination liefert reproduzierbare CI bei klarer Bump-Fläche.
Warum geht Traffic trotz Spiegel zu nuget.org? Prüfen Sie packageSourceMapping und projektnahe Configs; mit dotnet restore -v detailed die effektive URL verifizieren.
Lock nach Security-Patch? dotnet restore --force-evaluate (SDK-abhängig) oder kurz ohne Lock regenerieren, neu committen, CI wieder scharf schalten.
Strukturierte Daten: HowTo & FAQPage
Im <head> liegen bereits JSON-LD für BlogPosting, BreadcrumbList, HowTo und FAQPage. Fork-Hinweis: Fragen und Antworten im Markup an die sichtbare FAQ anpassen; keine Secrets oder internen URLs eintragen, die nicht öffentlich sind.
Fazit
Ordnen Sie Feeds mit packageSourceMapping, legen Sie Pakete per globalPackagesFolder oder NUGET_PACKAGES auf NVMe, begrenzen Sie MaxHttpRequestsPerSource und schalten Sie RestoreLockedMode mit versioniertem packages.lock.json scharf. Einen Remote-Mac in der Nähe Ihrer freigegebenen Spiegel zu mieten verwandelt diese Einstellungen in messbar kürzere dotnet restore-Phasen und stabilere nachgelagerte Tests — besonders wenn Ihr Team stündlich grenzüberschreitend baut.
Ohne Login weiter: Startseite, Preise, Kaufen, Hilfe, Technik-Blog.
Platzieren Sie den Agenten mit gesundem Ausgangsnetz nah an Ihren Spiegeln, fixieren Sie den Abhängigkeitsgraphen und behandeln Sie Restore-Parallelität als SSD-Budget — nicht als kostenlosen Multiplikator.
Remote-Mac für .NET-Restore & CI
Apple-Silicon-Host mit lokalem SSD-Cache und SSH — sinnvoll, wenn Sie NuGet-Zugriff näher an Spiegel und Peering legen möchten. Alle verlinkten Seiten sind ohne Anmeldung lesbar.