Apple Silicon リモート Mac上の self-hosted CI で dotnet restoreタイムアウト・浮動バージョン・ソース散在に悩むチーム向けです。NuGet.Config のミラー連鎖、MaxHttpRequestsPerSourceglobalPackagesFolder中央パッケージ管理(CPM)RestoreLockedModepackages.lock.json を一枚の判断表に落とし、検証コマンドまで繋ぎます。入口はホーム、一覧は技術ブログ。関連:Gradle/Maven の CI キャッシュマトリクスGit・npm・Homebrew のミラー最適化Go modules/GOPROXY マトリクス

課題:ソース順・並列 HTTP・ロック運用の三層

  • packageSources の列挙順と packageSourceMapping がズレると、意図せず nuget.org 直叩きが残り、国境越え RTT が支配的になります。
  • MaxHttpRequestsPerSource を上げたまま同時パイプラインを積むと、429 やソケット枯渇で restore がフラップします。
  • RestoreLockedMode を main で必須にしたのに packages.lock.json 更新フローが無いと、PR ごとに還元が赤くなり疲弊します。

決定マトリクス(シナリオ別のおすすめ組合せ)

シナリオソース連鎖MaxHttp/ソースglobalPackagesFolderRestoreLockedMode
社内プロキシ完結clear 後に社内 v3 → 必要なら public ミラー8〜12 から共有 SSD(ジョブ ID サブフォルダ可)main true/topic branch は段階導入
国境越え+キャッシュ重視地域ミラー v3 index を先頭、nuget.org をフォールバック帯域次第で 12→16、429 出たら 8runner ローカル+ CI アーティファクト同期CPM+ lock コミット後に true
マルチリポ短期検証ユーザー単位 Config で一時 source を上書き--disable-parallel で切り分け時は 4既定のまま(混乱時は明示パス)検証中は false、合流時に true
オフラインに近い帯域全パッケージを社内フィードへプロモートし一本化低め(4〜8)で安定優先NFS 共有は競合に注意、推奨はローカルtrue で浮動を拒否

中央パッケージ管理と MSBuild フラグの対応

Directory.Packages.propsManagePackageVersionsCentrally を有効化し、バージョンは中央のみに置きます。ロックファイル運用では RestorePackagesWithLockFile を有効にして packages.lock.json を生成し、CI では /p:RestoreLockedMode=true で浮動更新を弾きます。

キー/プロパティ役割メモ
ManagePackageVersionsCentrallyバージョンの単一情報源csproj から Version を外す移行が前提
RestorePackagesWithLockFileロック生成初回は false→生成→コミットの運用が扱いやすい
RestoreLockedModeロック不一致をエラーブランチ戦略と更新 PR をセットで決める
CentralPackageTransitivePinningEnabled推移的依存のピン留めロックの見え方が変わるため段階導入を推奨

NuGet.Config 断片(コピペ用)

packageSourceMapping はチーム標準の id プレフィックスに合わせて増減してください。実 URL は自社ミラーに読み替えます。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <config>
    <add key="globalPackagesFolder" value="/var/ci/nuget-global" />
    <add key="maxHttpRequestsPerSource" value="12" />
  </config>
  <packageSources>
    <clear />
    <add key="corp" value="https://nuget.corp.example/v3/index.json" />
    <add key="nugetorg" value="https://api.nuget.org/v3/index.json" />
  </packageSources>
  <packageSourceMapping>
    <packageSource key="corp"><package pattern="Corp.*" /></packageSource>
    <packageSource key="nugetorg"><package pattern="*" /></packageSource>
  </packageSourceMapping>
</configuration>

再現手順(五ステップ+検証)

1

リポジトリ直下に NuGet.Config を置き、packageSources の順と packageSourceMapping をレビューに回します。

2

globalPackagesFolder を self-hosted 全台で揃え、ディスククォータと CI キャッシュキー(lock ハッシュ)を一致させます。

3

MaxHttpRequestsPerSource を 8 から起動し、ログで同時接続と 429 を見て 12〜16 へ段階的に上げます。

4

CPM 化後に packages.lock.json を生成しコミット、dotnet restore /p:RestoreLockedMode=true を CI に固定します。

5

異常時は dotnet restore --disable-parallel -v:n でボトルネック URL を特定し、ソースを一つずつ無効化して切り分けます。

  • 数値メモ:同時パイプライン p、ソースあたり HTTP h のとき、ピーク接続の目安は パッケジ数×h に比例。出口 NAT のセッション上限と突き合わせます。
  • 運用メモ:lock 更新は専用 PR に限定し、レビューでバージョン差分だけを見える化します。
  • 環境メモ:HTTPS_PROXY/NO_PROXY は対話シェル・launchd・CI YAML の三経路で一致させ、curl -I で v3 index の応答を先に確認します。

FAQ(本文と JSON-LD の両方に対応)

MaxHttpRequestsPerSource を上げると速くなりますか?

帯域と相手サーバの制限次第です。429 やソケットエラーが増えるなら下げ、パイプライン本数との積で調整します。

RestoreLockedMode で CI が頻繁に落ちる

lock がブランチと不一致です。ロック更新 PR の運用にするか、開発線だけ一時的に false に戻してから段階的に true へ寄せます。

globalPackagesFolder を NFS で共有してよいか

小規模なら可ですが競合リスクがあります。ローカル SSD+CI キャッシュの方が無難なことが多いです。

まとめ:国境越え restore は「ソース順・並列・ロック」の三本柱

2026 年の リモート Mac CI では、NuGet.Config で外向き経路を制御し、MaxHttpRequestsPerSource で同時取得を抑え、CPM+packages.lock.json で再現性を固定するのが実務的な黄金パターンです。検証は restorebuild --no-restore を分離してログを読み切ると早いです。

パッケージ取得のボトルネックを 地理的に近いリージョンのリモート Mac ノードへ寄せると、dotnet restore の RTT 短縮とキャッシュヒット率向上を同時に狙いやすいです。次の一手:MacPull ホームで概要を確認し、料金プラン購入ページ(ログイン不要で閲覧できる範囲)からプランを選び、ヘルプセンターで SSH 接続を押さえてください。技術ブログ一覧の CI/依存記事もあわせてどうぞ。

NuGet × リモート Mac

国境越え restore を安定させるなら、ノードと Config をセットで

ヘルプ購入ホームはログイン不要で閲覧できる範囲です。関連記事はブログ一覧から。