Start Debugging

Aspire 13.2 --isolated: ポート衝突なしで並列 AppHost インスタンスを走らせる

Aspire 13.2 は --isolated フラグを出荷し、各 aspire run に独自のランダムポートと secrets store を与えます。マルチ checkout ワーク、エージェント worktree、ライブ AppHost を必要とする統合テストのロックを解除します。

同じ Aspire アプリのコピーを 2 つ同時に走らせることは常に address already in use との戦いを意味しました。今週発表された Aspire 13.2 は、その戦いを取り除く小さくても有用なフラグを追加します: --isolated です。呼び出しごとに独自のランダムポート、独自の user secrets store、独自の dashboard URL が付くので、2 つの AppHost が手動のポートリマッピングなしで並んで生きられます。

衝突はどこから来たか

デフォルトでは aspire run は固定ポートにバインドします: dashboard は 18888、OTLP は 4317/4318、各リソースにも予測可能なバインディング。これは単一ブランチの単一開発者には問題ありません。2 つ目の worktree を追加したり、別のインスタンスを立ち上げる coding エージェントを入れたり、ライブ AppHost が必要な統合テストが加わるや、全てが衝突します。チームは launchSettings.json 調整やカスタムポートマップでこれをパッチしてきましたが、どれも組み合わせが効きません。

--isolated が実際に変えること

aspire runaspire start に付ける --isolated は、呼び出しごとに 2 つのことを行います。まず、通常固定番号にバインドされるすべてのポート (dashboard、OTLP、リソースエンドポイント) が代わりにランダムな空きポートにバインドされます。Service discovery が動的な値をピックアップするので、アプリ自体は兄弟が何を選んだか知る必要がありません。次に、user secrets のバッキングストアが run ごとに一意な instance ID でキーされ、connection strings や API key が並列 AppHost 間で漏れません。

典型的な 2 ブランチワークフローは今やこう見えます:

# Terminal 1 - feature branch worktree
cd ~/src/my-app-feature
aspire run --isolated

# Terminal 2 - bug fix worktree
cd ~/src/my-app-bugfix
aspire run --isolated

両方のプロセスが立ち上がり、両方の dashboard が異なる URL で到達可能で、どちらも相手を知らず気にしません。片方をシャットダウンしても、もう片方のポート予約は乱されません。

「複数ターミナル」を超えてなぜ重要か

より興味深い消費者は tooling です。Detached モード は coding エージェントが --detach で AppHost を起動してターミナルを取り戻すことを許します。--isolated と組み合わせれば、同じエージェントが N 個の git worktree にまたがる N 個の AppHost を並列に立ち上げ、それぞれに対して HTTP probe や統合テストを走らせ、解体することができます。すべて手動のポート会計なしで。それは VS Code のバックグラウンドエージェントが探索作業のために worktree を作るときすでに使っているパターンです。

統合テストスイートも同じ恩恵を受けます。以前は、開発者がアプリをローカルで開いている間に CI で dotnet test から AppHost を走らせるには environment override が必要でした。--isolated があれば、test fixture はただこうすれば済みます:

[Fact]
public async Task ApiReturnsHealthy()
{
    var apphost = await DistributedApplicationTestingBuilder
        .CreateAsync<Projects.MyApp_AppHost>(["--isolated"]);

    await using var app = await apphost.BuildAsync();
    await app.StartAsync();

    var client = app.CreateHttpClient("api");
    var response = await client.GetAsync("/health");

    response.StatusCode.Should().Be(HttpStatusCode.OK);
}

静的ポートマップなし、テスト run 間のクリーンアップなし、「アプリ走らせっぱなしにしたっけ?」のサプライズなし。

—detach と aspire wait との組み合わせ

13.2 の完全なエージェントフレンドリーループは、バックグラウンドで起動する aspire run --isolated --detach、リソースが立ち上がるまでブロックする aspire wait api --status healthy --timeout 120、グラフ全体を解体せずにピースをサイクルする aspire resource api restart のように見えます。--isolated はそれらのループを N 部の間でコンポーザブルにするピースです。

13.2 の CLI 追加の完全なリストは isolated モードのドキュメント を参照してください。

< 戻る