ボリュームまたはバインド マウントを使用して Aspire プロジェクトのデータを保持する
Aspire プロジェクトを開始して停止するたびに、アプリはアプリ リソース コンテナーも作成し、破棄します。デバッグ セッション中にそれらのコンテナーに保存されたデータやファイルは、次のセッションでは失われます。多くの開発チームは、たとえば実行のたびにサンプル データでデータベースを再投入しなくて済むように、デバッグ セッション間でこのデータを保持したいと考えます。
この記事では、アプリの起動をまたいでデータを保持するように Aspire プロジェクトを構成する方法を学びます。ローカル開発中に連続したデータ セットを維持できることは、多くのシナリオで有用です。PostgreSQL、Redis、Azure Storage など、さまざまな Aspire リソース コンテナーの種類でボリュームやバインド マウントを活用できます。
プロジェクト データを保持するタイミング
Section titled “プロジェクト データを保持するタイミング”データベース リソースを含む Aspire ソリューションがあるとします。既定では、データはそのリソースのコンテナーに保存されます。アプリを停止するとすべてのリソース コンテナーが破棄されるため、そのデータは失われ、次にソリューションを実行したときには表示されません。この構成は、テストやデバッグのためにアプリ起動間でデータベースやストレージ サービスのデータを保持したい場合に問題を生みます。たとえば、次のような要件です:
- 複数回の再起動にまたがる長時間の開発セッション中、データベースで連続したデータ セットを扱いたい。
- Azure Blob Storage エミュレーター内で変化するファイル セットをテストまたはデバッグしたい。
- アプリの起動をまたいで Redis インスタンス内のキャッシュ データやメッセージを維持したい。
これらの目的は、ボリュームまたはバインド マウントを使って実現できます。これらの仕組みはコンテナー外、つまりコンテナー ホスト上のディレクトリにデータを保存するため、コンテナーと一緒に破棄されません。この方法により、Aspire プロジェクトの起動間でどのサービスのデータを保持するかを選べます。
ボリュームとバインド マウントの比較
Section titled “ボリュームとバインド マウントの比較”ボリュームとバインド マウントはどちらも、コンテナー ホスト上のディレクトリにデータを保存します。このディレクトリはコンテナーの外にあるため、コンテナーが停止してもデータは破棄されません。ただし、ボリュームとバインド マウントの動作には違いがあります:
- ボリューム: コンテナー ランタイムがボリュームを作成および制御します。ボリュームはコンテナー ホストの中核機能から分離されています。
- バインド マウント: コンテナー ランタイムがホスト マシン上のファイルまたはディレクトリをマウントします。コンテナーとホスト マシンの両方がバインド マウントの内容にアクセスできます。
ボリュームはバインド マウントよりも安全で移植性が高く、パフォーマンスも優れています。可能な限りボリュームを使用してください。ホスト マシンからデータにアクセスまたは変更する必要がある場合にのみ、バインド マウントを使用します。
ボリュームの使用
Section titled “ボリュームの使用”ボリュームはコンテナーによって生成されるデータを保持するための推奨方法で、Windows と Linux の両方でサポートされています。ボリュームは複数のコンテナーのデータを同時に保存でき、高いパフォーマンスを提供し、バックアップや移行も容易です。Aspire では WithVolume メソッドを使って各リソース コンテナーのボリュームを構成します。このメソッドは 3 つのパラメーターを受け取ります:
name: ボリュームの省略可能な名前。target: 保持したいデータのコンテナー内ターゲット パス。isReadOnly: ボリューム内データを変更可能かどうかを示すブール値です。既定値はfalseです。
この記事の残りでは、分散アプリ ビルダーの基本がすでに定義されている Aspire の AppHost プロジェクト にある Program クラスを確認していると想定します:
var builder = DistributedApplication.CreateBuilder(args);
// TODO:// ここでボリュームの構成と// 永続パスワードの設定に関するさまざまなコード スニペットを検討する。
builder.Build().Run();import { function createBuilder(): IDistributedApplicationBuilder
Creates a new distributed application builder
createBuilder } from './.aspire/modules/aspire.mjs';
const const builder: IDistributedApplicationBuilder
builder = await function createBuilder(): IDistributedApplicationBuilder
Creates a new distributed application builder
createBuilder();
// TODO:// ここでボリュームの構成と// 永続パスワードの設定に関するさまざまなコード スニペットを検討する。
await const builder: IDistributedApplicationBuilder
builder.IDistributedApplicationBuilder.build(): DistributedApplication
Builds the distributed application
build().DistributedApplication.run(cancellationToken?: cancellationToken): void
Runs the distributed application
run();最初に示すコード スニペットでは WithVolume API を使用して SQL Server リソースのボリュームを構成します。次のコードは Aspire AppHost プロジェクトで SQL Server リソースにボリュームを構成する方法を示しています:
var sql = builder.AddSqlServer("sql") .WithVolume(target: "/var/opt/mssql") .AddDatabase("sqldb");const sql = await builder.addSqlServer("sql");await sql.withVolume("/var/opt/mssql");const sqldb = await sql.addDatabase("sqldb");この例では /var/opt/mssql がコンテナー内のデータベース ファイルへのパスを設定します。
すべての Aspire コンテナー リソースでボリュームを利用でき、さらに一部ではリソースから派生した名前付きボリュームを追加するための便利な API が提供されています。WithDataVolume メソッドを例にすると、次のコードは先ほどの例と機能的に等価ですが、より簡潔です:
var sql = builder.AddSqlServer("sql") .WithDataVolume() .AddDatabase("sqldb");const sql = await builder.addSqlServer("sql");await sql.withDataVolume();const sqldb = await sql.addDatabase("sqldb");AppHost プロジェクト名が VolumeMount.AppHost の場合、WithDataVolume メソッドは自動的に VolumeMount.AppHost-sql-data という名前付きボリュームを作成し、SQL Server コンテナー内の /var/opt/mssql パスにマウントします。命名規則は次のとおりです:
{appHostProjectName}-{resourceName}-data: ボリューム名は AppHost プロジェクト名とリソース名から派生します。
バインド マウントの使用
Section titled “バインド マウントの使用”バインド マウントを使うと、コンテナー内部とホスト マシン上のプロセスの両方からデータへアクセスできます。たとえばバインド マウントを確立した後、ホスト コンピューター上でそこにファイルをコピーできます。そのファイルはリソースのコンテナー内でバインド先パスから利用できます。Aspire では WithBindMount メソッドを使って各リソース コンテナーのバインド マウントを構成します。このメソッドは 3 つのパラメーターを受け取ります:
source: コンテナーにマウントするホスト マシン上のフォルダーへのパス。target: フォルダーのコンテナー内ターゲット パス。isReadOnly: バインド マウント内データを変更可能かどうかを示すブール値です。既定値はfalseです。
次のコード スニペットでは WithBindMount API を使用して SQL Server リソースのバインド マウントを構成しています:
var sql = builder.AddSqlServer("sql") .WithBindMount(source: @"C:\SqlServer\Data", target: "/var/opt/mssql") .AddDatabase("sqldb");const sql = await builder.addSqlServer("sql");await sql.withBindMount("C:\\SqlServer\\Data", "/var/opt/mssql");const sqldb = await sql.addDatabase("sqldb");この例では:
source: @"C:\SqlServer\Data"は、バインドされるホスト コンピューター上のフォルダーを設定します。target: "/var/opt/mssql"は、コンテナー内のデータベース ファイルへのパスを設定します。
ボリュームと同様に、一部の Aspire コンテナー リソースではバインド マウントを追加するための便利な API が提供されています。WithDataBindMount メソッドを例にすると、次のコードは先ほどの例と機能的に等価ですが、より簡潔です:
var sql = builder.AddSqlServer("sql") .WithDataBindMount(source: @"C:\SqlServer\Data") .AddDatabase("sqldb");const sql = await builder.addSqlServer("sql");await sql.withDataBindMount("C:\\SqlServer\\Data");const sqldb = await sql.addDatabase("sqldb");永続パスワードの作成
Section titled “永続パスワードの作成”名前付きボリュームでは、アプリ起動間で一貫したパスワードが必要です。Aspire にはランダムなパスワード生成機能が用意されています。先ほどの例をもう一度見てみましょう。ここではパスワードが自動生成されます:
var sql = builder.AddSqlServer("sql") .WithDataVolume() .AddDatabase("sqldb");const sql = await builder.addSqlServer("sql");await sql.withDataVolume();const sqldb = await sql.addDatabase("sqldb");AddSqlServer 呼び出し時に password パラメーターを指定しないため、Aspire は SQL Server リソース用パスワードを自動生成します。
永続 パスワードを作成するには、生成されたパスワードを上書きする必要があります。これを行うには、AppHost プロジェクト ディレクトリで次のコマンドを実行してローカル シークレットを設定します:
aspire secret set Parameters:sql-password <password>これらのシークレットの命名規則を理解することが重要です。パスワードは Parameters:sql-password キーで構成に保存されます。命名規則は次のパターンです:
Parameters:{resourceName}-password: SQL Server リソース(名前は"sql")の場合、パスワードはParameters:sql-passwordキーで構成に保存されます。
同じパターンは、次の表に示す他のサーバーベース リソースの種類にも適用されます:
| リソースの種類 | ホスティング パッケージ | リソース名の例 | 上書きキー |
|---|---|---|---|
| MySQL | 📦 Aspire.Hosting.MySql | mysql | Parameters:mysql-password |
| Oracle | 📦 Aspire.Hosting.Oracle | oracle | Parameters:oracle-password |
| PostgreSQL | 📦 Aspire.Hosting.PostgreSQL | postgresql | Parameters:postgresql-password |
| RabbitMQ | 📦 Aspire.Hosting.RabbitMq | rabbitmq | Parameters:rabbitmq-password |
| SQL Server | 📦 Aspire.Hosting.SqlServer | sql | Parameters:sql-password |
生成されたパスワードを上書きすることで、アプリ起動間でパスワードを一貫して保てます。別の方法として AddParameter メソッドを使用し、パスワードとして利用できるパラメーターを作成することもできます。次のコードは SQL Server リソースの永続パスワードを作成する方法を示しています:
var sqlPassword = builder.AddParameter("sql-password", secret: true);
var sql = builder.AddSqlServer("sql", password: sqlPassword) .WithDataVolume() .AddDatabase("sqldb");const sqlPassword = await builder.addParameter("sql-password", { secret: true });
const sql = await builder.addSqlServer("sql", { password: sqlPassword });await sql.withDataVolume();const sqldb = await sql.addDatabase("sqldb");AddParameter メソッドは sql-password という名前のパラメーターを作成し、それをシークレットとして扱います。続いて AddSqlServer メソッドを password パラメーター付きで呼び出し、SQL Server リソースのパスワードを設定します。詳しくは 外部パラメーター を参照してください。
次のステップ
Section titled “次のステップ”前述のコードにあるボリュームの概念は、アプリ起動間で保持されるデータを使ったデータベース シードなど、さまざまなサービスに適用できます。次のチュートリアルで示したリソース実装と組み合わせて試してみてください: