diff --git a/src/frontend/config/aspire-versions.mjs b/src/frontend/config/aspire-versions.mjs index 8c27e3ae9..b10a6988f 100644 --- a/src/frontend/config/aspire-versions.mjs +++ b/src/frontend/config/aspire-versions.mjs @@ -1,5 +1,5 @@ -export const currentAspireMajorMinorVersion = '13.5'; -export const currentAspireVersion = '13.5.0'; +export const currentAspireMajorMinorVersion = '13.6'; +export const currentAspireVersion = '13.6.0'; export const aspireVersionPlaceholders = Object.freeze({ '%ASPIRE_VERSION_MAJOR_MINOR%': currentAspireMajorMinorVersion, diff --git a/src/frontend/config/sidebar/dashboard.topics.ts b/src/frontend/config/sidebar/dashboard.topics.ts index 157791190..41bea5052 100644 --- a/src/frontend/config/sidebar/dashboard.topics.ts +++ b/src/frontend/config/sidebar/dashboard.topics.ts @@ -126,6 +126,27 @@ export const dashboardTopics: StarlightSidebarTopicsUserConfig = { 'zh-CN': '数据功能', }, items: [ + { + label: 'Data persistence', + translations: { + da: 'Datapersistens', + de: 'Datenpersistenz', + en: 'Data persistence', + es: 'Persistencia de datos', + fr: 'Persistance des données', + hi: 'डेटा स्थायित्व', + id: 'Persistensi data', + it: 'Persistenza dei dati', + ja: 'データの永続化', + ko: '데이터 지속성', + 'pt-BR': 'Persistência de dados', + ru: 'Сохранение данных', + tr: 'Veri kalıcılığı', + uk: 'Збереження даних', + 'zh-CN': '数据持久性', + }, + slug: 'dashboard/data-persistence', + }, { label: 'AI coding agents', translations: { diff --git a/src/frontend/config/sidebar/docs.topics.ts b/src/frontend/config/sidebar/docs.topics.ts index be4f35931..e8c73fb1f 100644 --- a/src/frontend/config/sidebar/docs.topics.ts +++ b/src/frontend/config/sidebar/docs.topics.ts @@ -90,6 +90,10 @@ export const docsTopics: StarlightSidebarTopicsUserConfig = { label: "What's new", collapsed: true, items: [ + { + label: 'Aspire 13.6', + slug: 'whats-new/aspire-13-6', + }, { label: 'Aspire 13.5', slug: 'whats-new/aspire-13-5', diff --git a/src/frontend/src/assets/whats-new/aspire-13.6.0/.gitkeep b/src/frontend/src/assets/whats-new/aspire-13.6.0/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/src/frontend/src/content/docs/app-host/configuration.mdx b/src/frontend/src/content/docs/app-host/configuration.mdx index f46f876c7..f40f2a52a 100644 --- a/src/frontend/src/content/docs/app-host/configuration.mdx +++ b/src/frontend/src/content/docs/app-host/configuration.mdx @@ -164,6 +164,8 @@ By default, the dashboard is automatically started by the AppHost. The dashboard | `ASPIRE_DASHBOARD_TELEMETRY_OPTOUT` | `false` | Configures the dashboard to never send [usage telemetry](/dashboard/microsoft-collected-dashboard-telemetry/). | | `ASPIRE_DASHBOARD_API_ENABLED` | `true` | Enables the dashboard [telemetry API](/dashboard/configuration/#api) (`/api/telemetry/*`) endpoints. The AppHost always sets this to `true`. | | `ASPIRE_DASHBOARD_FORWARDEDHEADERS_ENABLED` | `false` | Enables the Forwarded headers middleware that replaces the scheme and host values on the Request context with the values coming from the `X-Forwarded-Proto` and `X-Forwarded-Host` headers. | +| `ASPIRE_DASHBOARD_PERSISTENCE_MODE` | `Run` | Configures [dashboard data persistence](/dashboard/data-persistence/). Valid values are `None`, `Run`, and `Resume`. The AppHost automatically sets this value to `Run`. | +| `ASPIRE_DASHBOARD_DATA_DIRECTORY` | `/dashboard` | Configures the root directory for persistent dashboard data. The directory must be writable by the account running the dashboard and have restrictive file-system permissions because it can contain sensitive data. | ## Internal diff --git a/src/frontend/src/content/docs/app-host/typescript-apphost.mdx b/src/frontend/src/content/docs/app-host/typescript-apphost.mdx index 7c83b91dc..ddee03826 100644 --- a/src/frontend/src/content/docs/app-host/typescript-apphost.mdx +++ b/src/frontend/src/content/docs/app-host/typescript-apphost.mdx @@ -167,6 +167,121 @@ Projects created with Aspire CLI versions earlier than 13.4 used `apphost.ts` an For compatibility details and optional migration steps, see [Legacy `apphost.ts` projects in the Aspire 13.4 release notes](/whats-new/aspire-13-4/#legacy-apphostts-projects-pre-134). +## Configuration with appsettings.json + +TypeScript AppHosts read configuration from JSON files that live next to `apphost.mts`. Add an `appsettings.json` file to your AppHost and Aspire loads it into the AppHost's configuration at startup. You read the effective values in `apphost.mts` through the builder's configuration accessor. + + + +- example-app/ + - .aspire/modules/ + - apphost.mts + - aspire.config.json + - appsettings.json Base configuration + - appsettings.Development.json Environment-specific overrides + - appsettings.Production.json Environment-specific overrides + - package.json + + + +Start with base settings as plain JSON. Settings can be flat, like `message`, or grouped in nested objects, like `deployment.region`. Keys are matched case-insensitively, so camelCase fits naturally in a TypeScript project: + +```json title="appsettings.json" +{ + "message": "From appsettings.json", + "deployment": { + "region": "westus" + } +} +``` + +With only `appsettings.json` present, read a flat value by its key. For a nested value, use `:` to separate each level of the JSON path. The `getConfigValue()` method returns `null` if the key isn't found: + +```typescript title="apphost.mts" twoslash +import { createBuilder } from './.aspire/modules/aspire.mjs'; + +const builder = await createBuilder(); +const configuration = await builder.getConfiguration(); + +const message = await configuration.getConfigValue('message'); +// message === 'From appsettings.json'; + +const region = await configuration.getConfigValue('deployment:region'); +// region === 'westus'; +``` + +### Environment-specific settings + +Aspire always loads `appsettings.json` first, then layers `appsettings.{Environment}.json` on top. The value passed to `--environment` replaces `{Environment}` in the filename. For example, `--environment Development` loads `appsettings.Development.json`, while `--environment Production` loads `appsettings.Production.json`. + +The environment-specific file overrides matching values from `appsettings.json`. The merged configuration is available through `getConfiguration()` when the AppHost starts. + +#### Development + +Add the Development overrides: + +```json title="appsettings.Development.json" +{ + "message": "From appsettings.Development.json", + "deployment": { + "region": "westus2" + } +} +``` + +Start the AppHost with the `Development` environment: + +```bash title="Start with Development settings" +aspire start --environment Development +``` + +The lookups in `apphost.mts` now return the Development values: + +```typescript title="apphost.mts — Development values" +const message = await configuration.getConfigValue('message'); +// message === 'From appsettings.Development.json'; + +const region = await configuration.getConfigValue('deployment:region'); +// region === 'westus2'; +``` + +#### Production + +Add the Production overrides: + +```json title="appsettings.Production.json" +{ + "message": "From appsettings.Production.json", + "deployment": { + "region": "eastus2" + } +} +``` + +Start the AppHost with the `Production` environment: + +```bash title="Start with Production settings" +aspire start --environment Production +``` + +The same lookups now return the Production values: + +```typescript title="apphost.mts — Production values" +const message = await configuration.getConfigValue('message'); +// message === 'From appsettings.Production.json'; + +const region = await configuration.getConfigValue('deployment:region'); +// region === 'eastus2'; +``` + + + For the full list of run options, see the [`aspire start` CLI reference](/reference/cli/commands/aspire-start/). + + + + ## Package managers The Aspire CLI supports the following package managers at the **AppHost root** — the directory that contains your `apphost.mts` and `aspire.config.json`. The CLI selects between them by inspecting package manager signals, including the `packageManager` field in `package.json`, lock files, and package manager configuration in the AppHost root. diff --git a/src/frontend/src/content/docs/community/index.mdx b/src/frontend/src/content/docs/community/index.mdx index 383bf353c..6efe16251 100644 --- a/src/frontend/src/content/docs/community/index.mdx +++ b/src/frontend/src/content/docs/community/index.mdx @@ -7,7 +7,7 @@ next: false description: Connect with the Aspire team and community across Discord, GitHub Discussions, livestreams, social channels, and contribution platforms for distributed apps. banner: content: | - ✨ Aspire 13.5 is available!Explore the latest features and improvements + ✨ Aspire 13.6 is available!Explore the latest features and improvements bannerAutoDismissAfterDays: 14 editUrl: false giscus: false diff --git a/src/frontend/src/content/docs/da/index.mdx b/src/frontend/src/content/docs/da/index.mdx index d182d166e..2e345a9d3 100644 --- a/src/frontend/src/content/docs/da/index.mdx +++ b/src/frontend/src/content/docs/da/index.mdx @@ -11,7 +11,7 @@ prev: false next: false banner: content: | - ✨ Aspire 13.5 er udgivet!Se hvad der er nyt i Aspire 13.5. + ✨ Aspire 13.6 er udgivet!Se hvad der er nyt i Aspire 13.6. bannerAutoDismissAfterDays: 14 hero: tagline: Din stack, forenklet.

Orkestrér frontends, APIs, containere og databaser ubesværet—ingen omskrivninger, ingen grænser. Udvid Aspire til at drive ethvert projekt.

diff --git a/src/frontend/src/content/docs/dashboard/configuration.mdx b/src/frontend/src/content/docs/dashboard/configuration.mdx index 9db526726..7b887f2ef 100644 --- a/src/frontend/src/content/docs/dashboard/configuration.mdx +++ b/src/frontend/src/content/docs/dashboard/configuration.mdx @@ -25,22 +25,14 @@ How you configure the dashboard depends on whether it's started by the Aspire Ap ### Aspire AppHost -The AppHost automatically configures the dashboard, but you can override values if needed. The recommended way to configure the dashboard from the Aspire AppHost is by adding environment variables to the _launchSettings.json_ file. +The AppHost automatically configures the dashboard, but you can override values if needed. The recommended way to configure the dashboard from the AppHost is to add environment variables to a launch profile in _aspire.config.json_. This configuration works with both C# and TypeScript AppHosts. -```json title="launchSettings.json" {14} +```json title="aspire.config.json" {6} { - "$schema": "https://json.schemastore.org/launchsettings.json", + "$schema": "https://aspire.dev/reference/cli/configuration/schema.json", "profiles": { "https": { - "commandName": "Project", - "dotnetRunMessages": true, - "launchBrowser": true, - "applicationUrl": "https://localhost:17134;http://localhost:15170", "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development", - "DOTNET_ENVIRONMENT": "Development", - "ASPIRE_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21030", - "ASPIRE_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:22057", "DASHBOARD__TELEMETRYLIMITS__MAXLOGCOUNT": "50000" } } @@ -48,7 +40,7 @@ The AppHost automatically configures the dashboard, but you can override values } ``` -These launch settings increase the `Dashboard:TelemetryLimits:MaxLogCount` [telemetry limit](#telemetry-limits) to 50,000. The `:` delimiter must be replaced with double underscore (`__`) in environment variable names. +This profile increases the `Dashboard:TelemetryLimits:MaxLogCount` [telemetry limit](#telemetry-limits) to 50,000. The `:` delimiter must be replaced with double underscore (`__`) in environment variable names. ### Standalone dashboard @@ -130,7 +122,7 @@ Alternatively, these same values could be configured using a JSON configuration |--------|-------------| | `ASPNETCORE_URLS`
Default: `http://localhost:18888` | One or more HTTP endpoints through which the dashboard frontend is served. The frontend endpoint is used to view the dashboard in a browser. When the dashboard is launched by the Aspire AppHost this address is secured with HTTPS. Securing the dashboard with HTTPS is recommended. | | `ASPIRE_DASHBOARD_OTLP_ENDPOINT_URL`
Default: `http://localhost:18889` | The [OTLP/gRPC](https://opentelemetry.io/docs/specs/otlp/#otlpgrpc) endpoint. This endpoint hosts an OTLP service and receives telemetry using gRPC. When the dashboard is launched by the Aspire AppHost this address is secured with HTTPS. Securing the dashboard with HTTPS is recommended. | -| `ASPIRE_DASHBOARD_OTLP_HTTP_ENDPOINT_URL`
Default: `http://localhost:18890` | The [OTLP/HTTP](https://opentelemetry.io/docs/specs/otlp/#otlphttp) endpoint. This endpoint hosts an OTLP service and receives telemetry using Protobuf over HTTP. When the dashboard is launched by the Aspire AppHost the OTLP/HTTP endpoint isn't configured by default. To configure an OTLP/HTTP endpoint with the AppHost, set an `ASPIRE_DASHBOARD_OTLP_HTTP_ENDPOINT_URL` env var value in _launchSettings.json_. Securing the dashboard with HTTPS is recommended. | +| `ASPIRE_DASHBOARD_OTLP_HTTP_ENDPOINT_URL`
Default: `http://localhost:18890` | The [OTLP/HTTP](https://opentelemetry.io/docs/specs/otlp/#otlphttp) endpoint. This endpoint hosts an OTLP service and receives telemetry using Protobuf over HTTP. When the dashboard is launched by the Aspire AppHost the OTLP/HTTP endpoint isn't configured by default. To configure an OTLP/HTTP endpoint with the AppHost, set an `ASPIRE_DASHBOARD_OTLP_HTTP_ENDPOINT_URL` environment variable in an _aspire.config.json_ launch profile. Securing the dashboard with HTTPS is recommended. | | `ASPIRE_DASHBOARD_UNSECURED_ALLOW_ANONYMOUS`
Default: `false` | Configures the dashboard to not use authentication and accepts anonymous access. This setting is a shortcut to configuring `Dashboard:Frontend:AuthMode`, `Dashboard:Otlp:AuthMode`, and `Dashboard:Api:AuthMode` to `Unsecured`. See [Dashboard security considerations](/dashboard/security-considerations/#anonymous-access) for the security implications. | | `ASPIRE_DASHBOARD_CONFIG_FILE_PATH`
Default: `null` | The path for a JSON configuration file. If the dashboard is being run in a Docker container, then this is the path to the configuration file in a mounted volume. This value is optional. | | `ASPIRE_DASHBOARD_FILE_CONFIG_DIRECTORY`
Default: `null` | The directory where the dashboard looks for key-per-file configuration. This value is optional. | @@ -221,6 +213,23 @@ export DASHBOARD__OTLP__ALLOWEDCERTIFICATES__0__THUMBPRINT="HEX_SHA256_THUMBPRIN If no allowed certificates are configured then all certificates that pass [ASP.NET Core certificate validation](https://learn.microsoft.com/aspnet/core/security/authentication/certauth#configure-certificate-validation) can authenticate. +## Data persistence + +The dashboard stores resources and telemetry in a SQLite database. Persistence behavior depends on how the dashboard is started: an AppHost-launched dashboard defaults to retaining separate application runs, while the standalone dashboard defaults to deleting its temporary database when it stops. The [application name](#other) is used to partition persisted data. + +| Option | Environment variable | Description | +|--------|----------------------|-------------| +| `Dashboard:Data:Directory`
Default: `/dashboard` | `ASPIRE_DASHBOARD_DATA_DIRECTORY` | The root directory for persistent dashboard data. The default `ASPIRE_HOME` is the _.aspire_ directory in the current user's profile. This option doesn't affect the temporary directory used by `None` mode. | +| `Dashboard:Data:PersistenceMode`
Default: `None` | `ASPIRE_DASHBOARD_PERSISTENCE_MODE` | The persistence mode. The AppHost automatically sets it to `Run`. Valid values are `None`, `Run`, and `Resume`. | + +The `aspire dashboard run` command also provides `--application-name` and `--persistence` options. For example, the following command reopens the same standalone database after a restart: + +```bash title="Aspire CLI" +aspire dashboard run --application-name my-app --persistence Resume +``` + +For a comparison of the modes and details about run history, storage layout, retention, and schema compatibility, see [Aspire dashboard data persistence](/dashboard/data-persistence/). + ## OTLP CORS Cross-origin resource sharing (CORS) can be configured to allow browser apps to send telemetry to the dashboard. @@ -282,7 +291,7 @@ The resource service client authentication is configured with `Dashboard:Resourc ### Telemetry limits -Telemetry is stored in memory. To avoid excessive memory usage, the dashboard limits stored telemetry. Log, trace, and metric retention limits evict the oldest stored values when full; attribute and span-event limits truncate incoming data, and the resource limit rejects telemetry for new resources after the limit is reached. +Telemetry is stored in SQLite. To bound the amount of retained telemetry, the dashboard applies limits to each database. Log, trace, and metric retention limits evict the oldest stored values when full; attribute and span-event limits truncate incoming data, and the resource limit rejects telemetry for new resources after the limit is reached. Telemetry limits have different scopes depending upon the telemetry type: @@ -303,7 +312,7 @@ Telemetry limits have different scopes depending upon the telemetry type: | Option | Description | |--------|-------------| -| `Dashboard:ApplicationName`
Default: `Aspire` | The application name to be displayed in the UI. This applies only when no resource service URL is specified. When a resource service exists, the service specifies the application name. | +| `Dashboard:ApplicationName`
Default: `Aspire` | The logical application name used to partition persisted data. The AppHost supplies its application name automatically. Set it with the `ASPIRE_DASHBOARD_APPLICATION_NAME` environment variable. | | `Dashboard:UI:DisableResourceGraph`
Default: `false` | Disables displaying the resource graph UI in the dashboard. | | `Dashboard:UI:DisableImport`
Default: `false` | Disables the telemetry import UI in the dashboard. | | `Dashboard:UI:DisableAgentHelp`
Default: `false` | Disables the **AI Agents** button in the dashboard header. When `false`, a button is shown in the header that opens a dialog with instructions for using AI coding agents with the dashboard. | diff --git a/src/frontend/src/content/docs/dashboard/data-persistence.mdx b/src/frontend/src/content/docs/dashboard/data-persistence.mdx new file mode 100644 index 000000000..a447af735 --- /dev/null +++ b/src/frontend/src/content/docs/dashboard/data-persistence.mdx @@ -0,0 +1,149 @@ +--- +title: Aspire dashboard data persistence +description: Learn how SQLite persistence modes, run history, retention, storage limits, and data protection work in the Aspire dashboard. +--- + +import { FileTree } from '@astrojs/starlight/components'; + +The Aspire dashboard stores resource snapshots and telemetry in SQLite. Persistence keeps completed application runs available after the AppHost and dashboard processes stop, while the active run continues to update in real time. + +The dashboard is intended for development and short-term diagnostics. Its persistence is useful for comparing runs or resuming a standalone dashboard, but it isn't a durable production telemetry backend. It doesn't provide replication, backups, database-level authentication, encryption at rest, or a disk-space quota. + +## Persistence modes + +| Mode | Database lifetime | Historical run selector | Default scenario | +|------|-------------------|-------------------------|------------------| +| `None` | One temporary database per dashboard process | No | Standalone dashboard | +| `Run` | One persistent database per dashboard process | Yes | AppHost dashboard | +| `Resume` | One persistent database reused across dashboard restarts | No | Explicit opt-in | + +All three modes use SQLite. The mode controls the database location and lifecycle, not which repository implementation the dashboard uses. + +### None + +`None` creates a database in a temporary `aspire-dashboard-*` directory. The database is deleted when the dashboard shuts down cleanly. The dashboard also attempts to remove abandoned temporary dashboard directories that aren't locked by another process. + +This mode is the standalone dashboard default and works well for a single development or diagnostic session: + +```bash title="Aspire CLI" +aspire dashboard run +``` + +### Run + +`Run` creates a separate persistent database each time the dashboard starts. It is the default when an AppHost launches the dashboard. No additional configuration is required. + +The dashboard header displays a run selector with the live run followed by completed runs. Switching runs doesn't reload the browser. Historical runs are read-only: + +- Resource commands and parameter changes are disabled. +- Clearing or importing telemetry is disabled. +- Pausing incoming data is disabled. +- Metric views use the latest stored timestamp as a fixed end time. + +You can pin runs that you want to keep. The dashboard retains up to 10 unpinned runs for an application and prunes the oldest unpinned runs after a new run starts. Pinned runs don't count toward this limit. A run currently selected by another dashboard session or owned by another dashboard process isn't pruned until its lock is released. + +### Resume + +`Resume` reopens one persistent database when the dashboard restarts. It doesn't create separate run records or show the run selector. Use it for a standalone dashboard that should continue from its previous data: + +```bash title="Aspire CLI" +aspire dashboard run --application-name my-app --persistence Resume +``` + +Reuse the same application name, data directory, and persistence mode each time. For a container example that keeps the database in a Docker named volume, see [Persist data between container runs](/dashboard/standalone/#persist-data-between-container-runs). + +Only one dashboard process can write to a `Resume` database at a time. Starting another process for the same application and data directory fails while the first process holds the ownership lock. + +## Configure persistence + +The dashboard reads these settings from configuration or their environment-variable equivalents: + +| Configuration key | Environment variable | Purpose | +|-------------------|----------------------|---------| +| `Dashboard:ApplicationName` | `ASPIRE_DASHBOARD_APPLICATION_NAME` | Partitions persisted data by logical application. | +| `Dashboard:Data:Directory` | `ASPIRE_DASHBOARD_DATA_DIRECTORY` | Sets the root directory for persistent dashboard data. | +| `Dashboard:Data:PersistenceMode` | `ASPIRE_DASHBOARD_PERSISTENCE_MODE` | Selects `None`, `Run`, or `Resume`. | + +An AppHost supplies its normalized application name and defaults to `Run`. A standalone dashboard defaults to the application name `Aspire` and mode `None`. The `aspire dashboard run` command maps `--application-name` and `--persistence` to the corresponding settings. + +When no data directory is configured, persistent modes use the _dashboard_ directory under `ASPIRE_HOME`. By default, `ASPIRE_HOME` is _.aspire_ in the current user's profile, such as `%USERPROFILE%\.aspire` on Windows or `$HOME/.aspire` on Unix-like systems. + +See [Aspire dashboard configuration](/dashboard/configuration/#data-persistence) for the configuration reference. + +## Storage layout + +Persistent data is partitioned by application. The application directory name combines a readable, sanitized application-name prefix with a stable hash. The hash prevents distinct names that sanitize to the same prefix from sharing data. + +`Run` mode stores each run in a timestamped directory: + +**Run mode data layout** + + +- \/ + - \/ + - runs/ + - \.lock + - \/ + - dashboard.db + - run.json + + +The metadata in _run.json_ includes the schema version, run ID, start and end times, application name, database file name, pin state, and whether the dashboard shut down cleanly. A run that doesn't shut down cleanly remains available after its process releases the lock. + +`Resume` mode stores one database for the application: + +**Resume mode data layout** + + +- \/ + - \.lock + - \/ + - dashboard.db + + +SQLite can create _dashboard.db-wal_ and _dashboard.db-shm_ beside a writable database. Include these files when inspecting, protecting, or copying live data. + +## Stored data + +The SQLite schema stores data in relational tables rather than retaining opaque OTLP payloads. It includes: + +- The latest resource snapshot, including properties, environment variables, URLs, volumes, health reports, relationships, and commands. +- Console logs that the dashboard has viewed or exported. +- Structured logs and their attributes. +- Traces, spans, events, links, and attributes. +- Metric instruments, dimensions, points, histogram data, and exemplars. + +Console logs are persisted only after their stream is viewed or exported. A historical run can therefore omit console logs that weren't captured. The frontend's `Dashboard:Frontend:MaxConsoleLogCount` setting limits how many console entries are retained in the viewer, but it doesn't bound the number already persisted to disk. + +## Telemetry retention and disk use + +Telemetry limits apply independently to each database. By default, the dashboard retains up to 10,000 structured logs and 10,000 traces per database, and up to 50,000 metric points per dimension. When these limits are exceeded, the oldest corresponding data is removed. Attribute, span-event, resource, instrumentation-scope, instrument, and dimension limits also apply. + +These limits aren't disk quotas. Database size also depends on attribute size, span events, metric cardinality, and captured console logs. Removing rows makes database pages reusable but doesn't shrink _dashboard.db_, because the dashboard doesn't run SQLite `VACUUM`. Write-ahead log files also consume disk space. + +For long-running `Resume` databases, keep finite attribute and span-event limits, control metric cardinality, and monitor disk use and query latency. See [Telemetry limits](/dashboard/configuration/#telemetry-limits) for all configurable limits. + +## Schema compatibility and locking + +The database has a versioned schema and doesn't run migrations between incompatible versions: + +- `None` always creates a new temporary database. +- `Run` creates a new database and omits incompatible historical runs from the selector. +- `Resume` replaces an incompatible database after successfully reading its schema version. If the compatibility check itself fails, startup fails and leaves the existing files in place. + +The dashboard uses exclusive lock files to prevent two processes from writing to the same run or resumed database. It also locks a historical run while that run is selected so background pruning can't remove it. + +Don't modify dashboard databases with non-Aspire tools. Changes made by other apps or tools can cause unexpected behavior. + +## Protect persisted data + +Persisted resources and telemetry can contain secrets and other sensitive application data. Resource property values marked as sensitive remain masked in the dashboard UI, but their underlying values are stored without redaction or encryption. + +On Unix-like systems, the dashboard sets the application-specific directory to owner-only permissions (`0700`). On Windows, it relies on the directory's inherited ACL. You are responsible for restricting access to the configured data root and to backups, snapshots, and copies. + +For complete guidance, see [Protect persisted data](/dashboard/security-considerations/#protect-persisted-data). + +## Next steps + +- [Configure the Aspire dashboard](/dashboard/configuration/) +- [Run the Aspire dashboard standalone](/dashboard/standalone/) diff --git a/src/frontend/src/content/docs/dashboard/overview.mdx b/src/frontend/src/content/docs/dashboard/overview.mdx index 8777c3707..5819af0bf 100644 --- a/src/frontend/src/content/docs/dashboard/overview.mdx +++ b/src/frontend/src/content/docs/dashboard/overview.mdx @@ -18,6 +18,7 @@ Key features of the dashboard include: - Real-time tracking of logs, traces, and environment configurations. - User interface to [stop, start, and restart resources](/dashboard/explore/#resource-actions). - Collects and displays logs and telemetry; [view structured logs, traces, and metrics](/dashboard/explore/#monitoring-pages) in an intuitive UI. +- Persists resources and telemetry so you can inspect and compare completed application runs. - Enhanced debugging with [AI coding agents](/dashboard/ai-coding-agents/) that use the Aspire CLI and MCP server to fetch logs and telemetry from the dashboard. ## Use the dashboard with Aspire projects diff --git a/src/frontend/src/content/docs/dashboard/security-considerations.mdx b/src/frontend/src/content/docs/dashboard/security-considerations.mdx index 5b78c82af..927bf07a2 100644 --- a/src/frontend/src/content/docs/dashboard/security-considerations.mdx +++ b/src/frontend/src/content/docs/dashboard/security-considerations.mdx @@ -40,6 +40,23 @@ The telemetry endpoint accepts incoming " ``` +## Enable persistence + +The standalone dashboard defaults to no persistence and telemetry is lost when the dashboard shuts down. To retain data, choose one of the persistent modes: + +- `Run` preserves each dashboard session as a separate run and enables selection of historical runs. +- `Resume` continues the same telemetry history across dashboard restarts. New telemetry is appended. + +For more information about persistence modes, run history, and retention, see [Aspire dashboard data persistence](/dashboard/data-persistence/). + +### Aspire CLI persistence + +Pass a persistent mode and a stable application name to `aspire dashboard run`. + +```bash title="Aspire CLI" +aspire dashboard run --application-name my-app --persistence run +``` + +The application name partitions persisted data. + +### Persist data between container runs + +For a dashboard container more configuration is required because the local filesystem is ephemeral. You must mount persistent storage. + + +
+ +```bash title="Create the volume and run the dashboard" +docker volume create aspire-dashboard-data + +docker run --rm -d --name aspire-dashboard \ + -p 18888:18888 \ + -p 4317:18889 \ + -p 4318:18890 \ + --mount type=volume,source=aspire-dashboard-data,target=/dashboard-data \ + -e ASPIRE_DASHBOARD_APPLICATION_NAME=my-app \ + -e ASPIRE_DASHBOARD_DATA_DIRECTORY=/dashboard-data \ + -e ASPIRE_DASHBOARD_PERSISTENCE_MODE=run \ + mcr.microsoft.com/dotnet/aspire-dashboard:latest +``` + +
+
+ +```powershell title="Create the volume and run the dashboard" +docker volume create aspire-dashboard-data + +docker run --rm -d --name aspire-dashboard ` + -p 18888:18888 ` + -p 4317:18889 ` + -p 4318:18890 ` + --mount type=volume,source=aspire-dashboard-data,target=/dashboard-data ` + -e ASPIRE_DASHBOARD_APPLICATION_NAME=my-app ` + -e ASPIRE_DASHBOARD_DATA_DIRECTORY=/dashboard-data ` + -e ASPIRE_DASHBOARD_PERSISTENCE_MODE=run ` + mcr.microsoft.com/dotnet/aspire-dashboard:latest +``` + +
+
+ +Stop the container and run the same `docker run` command again to access the retained data. Keep the volume, application name, and persistence mode unchanged between container runs. + +Persisted telemetry can contain sensitive data. Restrict access to the volume and see [Aspire dashboard data persistence](/dashboard/data-persistence/) for persistence behavior and [Dashboard security considerations](/dashboard/security-considerations/#protect-persisted-data) for security requirements. + ## Sample For a sample of using the standalone dashboard, see the [Standalone Aspire dashboard sample app](https://github.com/microsoft/aspire-samples/tree/main/samples/standalone-dashboard). diff --git a/src/frontend/src/content/docs/dashboard/telemetry-after-deployment.mdx b/src/frontend/src/content/docs/dashboard/telemetry-after-deployment.mdx index feb03e090..98849e2fe 100644 --- a/src/frontend/src/content/docs/dashboard/telemetry-after-deployment.mdx +++ b/src/frontend/src/content/docs/dashboard/telemetry-after-deployment.mdx @@ -6,7 +6,7 @@ description: Understand how telemetry and the Aspire dashboard work after you de import { Aside, Steps } from '@astrojs/starlight/components'; import LearnMore from '@components/LearnMore.astro'; -The Aspire dashboard is designed for local development and short-term diagnostics. It stores telemetry in memory, which means telemetry is lost when the dashboard restarts and there are built-in limits on how much data it retains. After deploying your app to a production environment, you need to configure a persistent telemetry backend. +The Aspire dashboard is designed for local development and short-term diagnostics. It offers configurable persistence and built-in limits on how much data it retains, but it isn't intended for long-term production observability. After deploying your app to a production environment, configure a durable telemetry backend. This article explains what changes when you deploy your app, how to configure production telemetry with Azure Monitor, and how to access the Aspire dashboard if it's included in your deployment. @@ -16,13 +16,14 @@ During development, Aspire automatically starts the dashboard and configures you | | Aspire dashboard | Production telemetry backend | |---|---|---| -| **Storage** | In-memory only | Persistent (database, cloud service) | -| **Retention** | Lost on restart | Configurable (days, months, indefinitely) | +| **Data durability** | Configurable for development and short-term diagnostics | Designed for durable, long-term telemetry | +| **Retention** | Temporary by default; persistence is configurable | Configurable (days, months, indefinitely) | | **Telemetry limits** | Default 10,000 log entries, 10,000 traces | Configurable or unlimited | +| **Scalability** | Fast access to development session telemetry | Scales to production telemetry volume and application lifetimes | | **Access** | Local or private | Secured, multi-user | | **Alerting** | None | Configurable alerts and dashboards | -After deploying, configure your app to send telemetry to a persistent backend. Any OTEL-compatible backend will work. For Azure-hosted apps, Azure Monitor with Application Insights is the recommended production telemetry solution. +After deploying, configure your app to send telemetry to a production telemetry backend. Any OTEL-compatible backend will work. For Azure-hosted apps, Azure Monitor with Application Insights is the recommended production telemetry solution. ## Export to an OpenTelemetry-compatible backend @@ -138,7 +139,7 @@ The Aspire dashboard supports both gRPC OTLP (port 18889) and HTTP OTLP (port 18 When you deploy an Aspire app to Azure Container Apps using `aspire deploy`, the Aspire dashboard is included as a Container Apps environment in your deployment. This gives you a familiar UI for viewing telemetry from your deployed app. ### Find the dashboard URL diff --git a/src/frontend/src/content/docs/de/index.mdx b/src/frontend/src/content/docs/de/index.mdx index edfb37766..02919a7fd 100644 --- a/src/frontend/src/content/docs/de/index.mdx +++ b/src/frontend/src/content/docs/de/index.mdx @@ -11,7 +11,7 @@ prev: false next: false banner: content: | - ✨ Aspire 13.5 wurde veröffentlicht!Was ist neu in Aspire 13.5. + ✨ Aspire 13.6 wurde veröffentlicht!Was ist neu in Aspire 13.6. bannerAutoDismissAfterDays: 14 hero: tagline: Dein Stack, vereinfacht.

Orchestriere Frontends, APIs, Container und Datenbanken mühelos—ohne Umschreiben, ohne Grenzen. Erweitere Aspire, um jedes Projekt anzutreiben.

diff --git a/src/frontend/src/content/docs/deployment/kubernetes/persistent-volumes.mdx b/src/frontend/src/content/docs/deployment/kubernetes/persistent-volumes.mdx index 29c922edb..32fbba5b3 100644 --- a/src/frontend/src/content/docs/deployment/kubernetes/persistent-volumes.mdx +++ b/src/frontend/src/content/docs/deployment/kubernetes/persistent-volumes.mdx @@ -181,6 +181,41 @@ await api.withKubernetesPersistentVolumeMount(media, '/srv/media'); +### Bind with a portable path environment variable + +Add the `env` parameter to expose the volume's effective storage path through an environment variable instead of hardcoding the mount path in your application: + + + + +```csharp title="AppHost.cs" +var data = k8s.AddPersistentVolume("data") + .WithCapacity("20Gi"); + +builder.AddProject("api") + .WithPersistentVolume(data, "/data", env: "DATA_PATH"); +``` + + + + +```typescript title="apphost.mts" +const data = await k8s.addPersistentVolume('data'); +await data.withCapacity('20Gi'); + +const api = await builder.addProject('api'); +await api.withKubernetesPersistentVolumeMount(data, '/data', { env: 'DATA_PATH' }); +``` + + + + +When a project or executable runs locally, `DATA_PATH` points to a persistent directory in the AppHost's local store — normally under the AppHost's intermediate-output directory, so cleaning build outputs can remove the local data. In publish and deploy modes, `DATA_PATH` contains the mount path (`/data` above), so the application reads the same environment variable in both environments. + +Local containers use a worktree-scoped container volume instead when the mount names an environment variable; mounts that don't name one keep the persistent volume's own name for the local container volume, so data written by an earlier version of the AppHost stays attached. A single persistent-volume resource can't be shared between local containers and local projects or executables, because those execution types can't reliably share one backing store. + +The `isReadOnly` mount option is enforced after deployment, but Aspire can't make a directory read-only for a process running directly on the host. + diff --git a/src/frontend/src/content/docs/docs.mdx b/src/frontend/src/content/docs/docs.mdx index 77e85dbae..7c1236e2b 100644 --- a/src/frontend/src/content/docs/docs.mdx +++ b/src/frontend/src/content/docs/docs.mdx @@ -7,7 +7,7 @@ next: description: 'Browse the official Aspire documentation: get started with C# and TypeScript AppHosts, model distributed apps, deploy to Azure and Kubernetes, and observe in the dashboard.' banner: content: | - ✨ Aspire 13.5 is available!Explore the latest features and improvements + ✨ Aspire 13.6 is available!Explore the latest features and improvements bannerAutoDismissAfterDays: 14 editUrl: false tableOfContents: false diff --git a/src/frontend/src/content/docs/es/index.mdx b/src/frontend/src/content/docs/es/index.mdx index 876e7aee7..4955da538 100644 --- a/src/frontend/src/content/docs/es/index.mdx +++ b/src/frontend/src/content/docs/es/index.mdx @@ -11,7 +11,7 @@ prev: false next: false banner: content: | - ✨ ¡Aspire 13.5 está disponible!Explora las últimas características y mejoras. + ✨ ¡Aspire 13.6 está disponible!Explora las últimas características y mejoras. bannerAutoDismissAfterDays: 14 hero: tagline: Tu stack, simplificado.

Orquesta frontends, APIs, contenedores y bases de datos sin esfuerzo—sin reescrituras, sin límites. Extiende Aspire para impulsar cualquier proyecto.

diff --git a/src/frontend/src/content/docs/extensibility/interaction-service.mdx b/src/frontend/src/content/docs/extensibility/interaction-service.mdx index 7eff752cf..d24e5120b 100644 --- a/src/frontend/src/content/docs/extensibility/interaction-service.mdx +++ b/src/frontend/src/content/docs/extensibility/interaction-service.mdx @@ -901,12 +901,14 @@ if (result.Canceled) return CommandResults.Failure("Canceled"); } -var file = result.Data.Files?[0]; -if (file is null) +using var files = result.Data.GetFiles(); +if (files.Count == 0) { return CommandResults.Failure("No file uploaded"); } +var file = files[0]; + // Read all file content as bytes var content = await file.ReadAllBytesAsync(cancellationToken); @@ -914,6 +916,8 @@ var content = await file.ReadAllBytesAsync(cancellationToken); await using var stream = file.OpenRead(); ``` +The uploaded files are temporary files on the AppHost. `GetFiles()` returns a disposable `InteractionFileCollection`, and the caller owns it: dispose the collection when the files are no longer needed to delete them from disk before AppHost shutdown. Files that are never disposed are deleted when the AppHost shuts down. After disposal, `InteractionFile.OpenRead()` and `ReadAllBytesAsync()` throw `ObjectDisposedException`, but any stream already opened before disposal remains usable until that stream is disposed. + @@ -943,11 +947,18 @@ if (files.length === 0) { return { success: false, message: 'No file uploaded' }; } -const file = files[0]; -// file.name - original filename -// file.filePath - path to uploaded file on disk +try { + const file = files[0]; + // file.name - original filename + // file.filePath - path to uploaded file on disk +} finally { + // Delete the uploaded temporary files from the AppHost. + await fileInput.releaseFiles(); +} ``` +Call `releaseFiles()` after the uploaded files have been processed to delete the temporary files on the AppHost. The call is idempotent, so a `finally` block is a good place for it. Files that are never released are deleted when the AppHost shuts down. + diff --git a/src/frontend/src/content/docs/fr/index.mdx b/src/frontend/src/content/docs/fr/index.mdx index f4960a9a5..8a274745b 100644 --- a/src/frontend/src/content/docs/fr/index.mdx +++ b/src/frontend/src/content/docs/fr/index.mdx @@ -11,7 +11,7 @@ prev: false next: false banner: content: | - ✨ Aspire 13.5 est disponible !Découvrez les nouveautés d'Aspire 13.5. + ✨ Aspire 13.6 est disponible !Découvrez les nouveautés d'Aspire 13.6. bannerAutoDismissAfterDays: 14 hero: tagline: Votre stack, simplifiée.

Orchestrez vos frontends, APIs, conteneurs et bases de données sans effort — sans réécriture, sans limites. Étendez Aspire pour propulser n'importe quel projet.

diff --git a/src/frontend/src/content/docs/fundamentals/persist-data-volumes.mdx b/src/frontend/src/content/docs/fundamentals/persist-data-volumes.mdx index 8516303e3..caf810d3f 100644 --- a/src/frontend/src/content/docs/fundamentals/persist-data-volumes.mdx +++ b/src/frontend/src/content/docs/fundamentals/persist-data-volumes.mdx @@ -126,6 +126,42 @@ With the AppHost project being named `VolumeMount.AppHost`, the `WithDataVolume` - `{appHostProjectName}-{resourceName}-data`: The volume name is derived from the AppHost project name and the resource name. +## Use a portable volume path environment variable + +Volume mount paths often differ between local process execution and deployed containers: projects and executables need a host filesystem path during the inner loop, while Docker Compose, Kubernetes, and Azure Container Apps need the in-container mount path. `WithVolume` accepts an optional `env` parameter so an application can read one environment variable in both modes instead of branching on how it's running: + + + + +```csharp title="AppHost.cs" +builder.AddProject("api") + .WithVolume("data", "/data", env: "DATA_PATH"); +``` + + + + +```typescript title="apphost.mts" +const api = await builder.addProject("api"); +await api.withVolume("/data", "data", "DATA_PATH"); +``` + + + + +In this example: + +- In run mode, the project or executable receives a deterministic, workload-scoped directory under the AppHost's local store as the value of `DATA_PATH`. +- Containers, and every workload in publish or deploy mode (Docker Compose, Kubernetes, and Azure Container Apps), receive `/data` — the configured `target` path — as the value of `DATA_PATH`. + + + +This convention also applies to Kubernetes persistent volumes bound with `WithPersistentVolume(..., env: ...)`. For details, see [Persistent volumes on Kubernetes](/deployment/kubernetes/persistent-volumes/#bind-with-a-portable-path-environment-variable). + ## Use bind mounts Bind mounts enable access to the data from both within the container and from processes on the host machine. For example, once a bind mount is established, you can copy a file into it on your host computer. The file is then available at the bound path within the container for your resource. With Aspire, you configure a bind mount for each resource container using the `WithBindMount` method, which accepts three parameters: diff --git a/src/frontend/src/content/docs/get-started/aspire-vscode-extension.mdx b/src/frontend/src/content/docs/get-started/aspire-vscode-extension.mdx index 4dc735010..41d941a41 100644 --- a/src/frontend/src/content/docs/get-started/aspire-vscode-extension.mdx +++ b/src/frontend/src/content/docs/get-started/aspire-vscode-extension.mdx @@ -93,12 +93,20 @@ Each resource shows its type, state, health summary, and exit code, plus a healt `aspire.globalAppHostsPollingInterval` is deprecated. Use `aspire.appHostsPollingInterval` to configure how often the Aspire view polls for running AppHosts. ::: +:::note[Single-AppHost auto-expansion] +When a workspace contains exactly one AppHost, the Aspire view automatically expands it — but only once you explicitly open the Aspire view. Reloading the window (**Developer: Reload Window**) while another sidebar view, such as **Explorer**, is active no longer switches focus to Aspire or reveals a hidden Aspire icon in the Activity Bar. +::: + ## Run, debug, and deploy :::note[Debugging] The Aspire Dashboard is no longer opened by default when the AppHost starts, as most operations can be performed using the Aspire view inside VS Code. To launch the dashboard, use the **Open Dashboard** CodeLens, the **Aspire: Open Dashboard** command, or open it from the Aspire view. ::: +:::note[Build failure notifications] +If the AppHost fails to build during a run or debug launch, VS Code shows a single error notification with **Open CLI Log** and, when available, **Open AppHost Log** actions that open the relevant log file directly in a non-preview editor. Full diagnostics and log locations are still available in the Debug Console. +::: + **Aspire: Configure launch.json file** adds a minimal launch configuration `.vscode/launch.json` that supports AppHosts written in any language. AppHosts are discovered automatically in the workspace. diff --git a/src/frontend/src/content/docs/hi/index.mdx b/src/frontend/src/content/docs/hi/index.mdx index 67ec807b5..8bf3802bf 100644 --- a/src/frontend/src/content/docs/hi/index.mdx +++ b/src/frontend/src/content/docs/hi/index.mdx @@ -11,7 +11,7 @@ prev: false next: false banner: content: | - ✨ Aspire 13.5 रिलीज़ हो गया है!Aspire 13.5 में नया क्या है देखें। + ✨ Aspire 13.6 रिलीज़ हो गया है!Aspire 13.6 में नया क्या है देखें। bannerAutoDismissAfterDays: 14 hero: tagline: आपका स्टैक, सरल।

फ्रंटएंड, API, कंटेनर और डेटाबेस को आसानी से ऑर्केस्ट्रेट करें—बिना रीराइट, बिना सीमा। किसी भी प्रोजेक्ट को शक्ति देने के लिए Aspire को विस्तारित करें।

diff --git a/src/frontend/src/content/docs/id/index.mdx b/src/frontend/src/content/docs/id/index.mdx index 85a910831..925fb90a7 100644 --- a/src/frontend/src/content/docs/id/index.mdx +++ b/src/frontend/src/content/docs/id/index.mdx @@ -11,7 +11,7 @@ prev: false next: false banner: content: | - ✨ Aspire 13.5 telah dirilis!Lihat apa yang baru di Aspire 13.5. + ✨ Aspire 13.6 telah dirilis!Lihat apa yang baru di Aspire 13.6. bannerAutoDismissAfterDays: 14 hero: tagline: Stack Anda, disederhanakan.

Orkestrasi frontend, API, container, dan database dengan mudah—tanpa menulis ulang, tanpa batasan. Perluas Aspire untuk mendukung proyek apa pun.

diff --git a/src/frontend/src/content/docs/index.mdx b/src/frontend/src/content/docs/index.mdx index bd8f115da..03e34248e 100644 --- a/src/frontend/src/content/docs/index.mdx +++ b/src/frontend/src/content/docs/index.mdx @@ -11,7 +11,7 @@ prev: false next: false banner: content: | - ✨ Aspire 13.5 is available!Explore the latest features and improvements + ✨ Aspire 13.6 is available!Explore the latest features and improvements bannerAutoDismissAfterDays: 14 hero: title: Compose distributed apps in code. diff --git a/src/frontend/src/content/docs/integrations/ai/github-models/github-models-connect.mdx b/src/frontend/src/content/docs/integrations/ai/github-models/github-models-connect.mdx index 7b68bd694..5d5130dca 100644 --- a/src/frontend/src/content/docs/integrations/ai/github-models/github-models-connect.mdx +++ b/src/frontend/src/content/docs/integrations/ai/github-models/github-models-connect.mdx @@ -19,8 +19,8 @@ import githubIcon from '@assets/icons/github-icon.png'; data-zoom-off /> -:::caution[Integration deprecated] -The GitHub Models service is **no longer available to new customers**. The `Aspire.Hosting.GitHub.Models` integration is sunset as of Aspire 13.5. All public APIs are marked `[Obsolete]` and the package no longer appears in `aspire add` output. The package will ship one final obsolete release on NuGet and will be removed entirely in a future version. For new and existing apps, use the [Azure AI Foundry integration](/integrations/cloud/azure/azure-ai-foundry/azure-ai-foundry-get-started/) instead, which provides access to a broad catalog of models — including OpenAI's GPT models — and supports local development with `RunAsFoundryLocal()`. See [microsoft/aspire#18402](https://github.com/microsoft/aspire/issues/18402) for details. +:::caution[GitHub Models retired] +[GitHub Models was retired for all customers on July 30, 2026](https://github.blog/changelog/2026-07-30-github-models-is-now-retired/). The `Aspire.Hosting.GitHub.Models` integration is discontinued. Its final release shipped with Aspire 13.5, and the integration will be removed after that release. Migrate new and existing apps to the [Microsoft Foundry integration](/integrations/cloud/azure/azure-ai-foundry/azure-ai-foundry-get-started/). The rest of this article is retained as a historical reference. For more information about the retired service, see the [GitHub Models documentation](https://docs.github.com/github-models). ::: This page describes how consuming apps connect to a GitHub Model resource that's already modeled in your AppHost. For the AppHost API surface — adding a model resource, API key parameters, organization configuration, and health checks — see [GitHub Models hosting integration](../github-models-host/). @@ -361,7 +361,7 @@ console.log(response.choices[0].message.content); ## See also -- [Get started with the GitHub Models integrations](/integrations/ai/github-models/github-models-get-started/) +- [Migrate Aspire apps from GitHub Models](/integrations/ai/github-models/github-models-get-started/) - [GitHub Models hosting integration](/integrations/ai/github-models/github-models-host/) - [GitHub Models Marketplace](https://github.com/marketplace/models) - [GitHub Models documentation](https://docs.github.com/github-models) diff --git a/src/frontend/src/content/docs/integrations/ai/github-models/github-models-get-started.mdx b/src/frontend/src/content/docs/integrations/ai/github-models/github-models-get-started.mdx index e78f6db59..d1b0b9a9b 100644 --- a/src/frontend/src/content/docs/integrations/ai/github-models/github-models-get-started.mdx +++ b/src/frontend/src/content/docs/integrations/ai/github-models/github-models-get-started.mdx @@ -1,11 +1,11 @@ --- -title: Get started with the GitHub Models integrations -description: Learn how the Aspire GitHub Models integrations register a GitHub Models resource and wire the .NET client to call models hosted on GitHub. +title: Migrate Aspire apps from GitHub Models +description: Learn how to migrate Aspire apps from the discontinued GitHub Models integration to Microsoft Foundry for continued AI model access. prev: false --- import { Image } from 'astro:assets'; -import { LinkButton, Steps } from '@astrojs/starlight/components'; +import { Steps } from '@astrojs/starlight/components'; import githubIcon from '@assets/icons/github-icon.png'; -:::caution[Integration deprecated] -The GitHub Models service is **no longer available to new customers**. The `Aspire.Hosting.GitHub.Models` integration is sunset as of Aspire 13.5. All public APIs are marked `[Obsolete]` and the package no longer appears in `aspire add` output. The package will ship one final obsolete release on NuGet and will be removed entirely in a future version. For new and existing apps, use the [Azure AI Foundry integration](/integrations/cloud/azure/azure-ai-foundry/azure-ai-foundry-get-started/) instead, which provides access to a broad catalog of models — including OpenAI's GPT models — and supports local development with `RunAsFoundryLocal()`. See [microsoft/aspire#18402](https://github.com/microsoft/aspire/issues/18402) for details. +:::caution[GitHub Models retired] +[GitHub Models was retired for all customers on July 30, 2026](https://github.blog/changelog/2026-07-30-github-models-is-now-retired/). The `Aspire.Hosting.GitHub.Models` integration is discontinued. Its final release shipped with Aspire 13.5, and the integration will be removed after that release. Migrate new and existing apps to the [Microsoft Foundry integration](/integrations/cloud/azure/azure-ai-foundry/azure-ai-foundry-get-started/). For more information about the retired service, see the [GitHub Models documentation](https://docs.github.com/github-models). ::: -[GitHub Models](https://github.com/marketplace/models) provides access to a broad catalog of AI models — including OpenAI's GPT models, DeepSeek, Microsoft's Phi models, and more — through GitHub's infrastructure and your existing GitHub token. The Aspire GitHub Models integration lets you model a GitHub Model resource as a first-class resource in your AppHost, then hand the connection information to any consuming app — regardless of language. +The GitHub Models playground, model catalog, inference API, and bring your own key (BYOK) capabilities are no longer available. Existing apps that use the Aspire GitHub Models integration can't send inference requests to the retired service. -## Why use GitHub Models with Aspire +## Migrate to Microsoft Foundry -Adding GitHub Models through Aspire — rather than hard-coding API keys and endpoints in each service — gives you: - -- **Centralized credential management.** The GitHub token is stored once as a secret parameter in the AppHost and injected into each consuming app automatically. -- **Typed model resources with connection strings.** Each GitHub Model resource composes a connection string from the endpoint, API key, and model identifier, giving consuming apps a single named connection. -- **Consistent connection info across languages.** Once you reference a model resource from a consuming app, Aspire injects connection properties as environment variables in a predictable format that works from C#, TypeScript, Python, Go, or any other language. -- **Automatic `GITHUB_TOKEN` fallback.** In Codespaces and GitHub Actions the ambient `GITHUB_TOKEN` is used automatically — no extra secrets to configure. -- **A first-class C# client integration.** C# apps can use `Aspire.Azure.AI.Inference` or `Aspire.OpenAI` for dependency injection, health checks, and OpenTelemetry, all wired up from the same resource name. - -## How the pieces fit together - -The GitHub Models integration has two sides: a **hosting integration** that you use in your AppHost to model the GitHub Model resource, and a **connection story** for consuming apps that reference it. - -```mermaid -architecture-beta - - group apphost(server)[AppHost] - group consumer(server)[Consuming app] - - service hosting(server)[Hosting integration] in apphost - service githubmodels(internet)[GitHub Models API] in apphost - service model(database)[chat model] in apphost - - service client(iconoir:server-connection)[Client integration] in consumer - service app(server)[App] in consumer - - hosting:R --> L:githubmodels - githubmodels:R --> L:model - model:R --> L:client - client:R --> L:app -``` - -The **hosting integration** lives in your AppHost project and models the GitHub Model resource. The **client integration** lives in each consuming app and uses the connection information Aspire injects to call the GitHub Models API. - -Getting there is a two-step process: model the GitHub Model resource in your AppHost, then connect to the API from each app that needs it. +Microsoft Foundry provides a broad model catalog and supports both cloud-hosted deployments and local development. To migrate: -1. ### Model GitHub Models in your AppHost - - Add the GitHub Models hosting integration to your AppHost, then declare a model resource and reference it from the apps that need to call the API. The [GitHub Models hosting integration](/integrations/ai/github-models/github-models-host/) article walks through every capability — adding model resources, API key parameters, organization configuration, and health checks — with side-by-side C# and TypeScript examples. +1. Remove the `Aspire.Hosting.GitHub.Models` package from your AppHost and remove GitHub Models resources, API key parameters, and `GITHUB_TOKEN` configuration. +2. Follow the [Microsoft Foundry hosting integration guide](/integrations/cloud/azure/azure-ai-foundry/azure-ai-foundry-host/) to add a Foundry resource and model deployment. For local development, you can configure the resource to run with Foundry Local. +3. Reference the Foundry deployment from each consuming app that needs model access. +4. Follow [Connect to Microsoft Foundry](/integrations/cloud/azure/azure-ai-foundry/azure-ai-foundry-connect/) to update client configuration and environment-variable handling. Don't reuse retired GitHub Models endpoints, tokens, or model identifiers. - - Set up GitHub Models in the AppHost - - -2. ### Connect from your consuming app + - When you reference a GitHub Model resource from a consuming app, Aspire injects its connection information as environment variables. See [Connect to GitHub Models](/integrations/ai/github-models/github-models-connect/) for the connection properties reference and per-language examples for C#, Go, Python, and TypeScript — including the full C# client integration. +## Aspire 13.5 historical reference - - Connect to GitHub Models - +The following articles document the final Aspire 13.5 integration surface for migration and historical reference. Their examples don't restore access to the retired GitHub Models service: - +- [GitHub Models hosting integration](/integrations/ai/github-models/github-models-host/) +- [Connect to GitHub Models](/integrations/ai/github-models/github-models-connect/) ## See also -- [GitHub Models on GitHub Marketplace](https://github.com/marketplace/models) +- [Microsoft Foundry integration](/integrations/cloud/azure/azure-ai-foundry/azure-ai-foundry-get-started/) +- [GitHub Models retirement notice](https://github.blog/changelog/2026-07-30-github-models-is-now-retired/) - [GitHub Models documentation](https://docs.github.com/github-models) diff --git a/src/frontend/src/content/docs/integrations/ai/github-models/github-models-host.mdx b/src/frontend/src/content/docs/integrations/ai/github-models/github-models-host.mdx index c470cde2d..c19ff645b 100644 --- a/src/frontend/src/content/docs/integrations/ai/github-models/github-models-host.mdx +++ b/src/frontend/src/content/docs/integrations/ai/github-models/github-models-host.mdx @@ -5,7 +5,6 @@ description: Learn how to use the Aspire GitHub Models hosting integration to or import { Image } from 'astro:assets'; import { Aside, Steps, Tabs, TabItem } from '@astrojs/starlight/components'; -import LearnMore from '@components/LearnMore.astro'; import githubIcon from '@assets/icons/github-icon.png'; -:::caution[Integration deprecated] -The GitHub Models service is **no longer available to new customers**. The `Aspire.Hosting.GitHub.Models` integration is sunset as of Aspire 13.5. All public APIs are marked `[Obsolete]` and the package no longer appears in `aspire add` output. The package will ship one final obsolete release on NuGet and will be removed entirely in a future version. For new and existing apps, use the [Azure AI Foundry integration](/integrations/cloud/azure/azure-ai-foundry/azure-ai-foundry-get-started/) instead, which provides access to a broad catalog of models — including OpenAI's GPT models — and supports local development with `RunAsFoundryLocal()`. See [microsoft/aspire#18402](https://github.com/microsoft/aspire/issues/18402) for details. +:::caution[GitHub Models retired] +[GitHub Models was retired for all customers on July 30, 2026](https://github.blog/changelog/2026-07-30-github-models-is-now-retired/). The `Aspire.Hosting.GitHub.Models` integration is discontinued. Its final release shipped with Aspire 13.5, and the integration will be removed after that release. Migrate new and existing apps to the [Microsoft Foundry integration](/integrations/cloud/azure/azure-ai-foundry/azure-ai-foundry-get-started/). The rest of this article is retained as a historical reference. For more information about the retired service, see the [GitHub Models documentation](https://docs.github.com/github-models). ::: This article is the reference for the Aspire GitHub Models hosting integration. It enumerates the AppHost APIs — with examples for both `AppHost.cs` and `apphost.mts` — that you use to model GitHub Model resources in your [`AppHost`](/get-started/app-host/) project. -If you're new to the GitHub Models integration, start with the [Get started with GitHub Models integrations](/integrations/ai/github-models/github-models-get-started/) guide. For how consuming apps read the connection information this page exposes, see [Connect to GitHub Models](../github-models-connect/). +For migration guidance, see [Migrate Aspire apps from GitHub Models](/integrations/ai/github-models/github-models-get-started/). For how consuming apps read the connection information this page exposes, see [Connect to GitHub Models](../github-models-connect/). ## Installation -To start building an Aspire app that uses GitHub Models, install the [📦 Aspire.Hosting.GitHub.Models](https://www.nuget.org/packages/Aspire.Hosting.GitHub.Models) NuGet package: +The following examples pin the final [📦 Aspire.Hosting.GitHub.Models 13.5.1](https://www.nuget.org/packages/Aspire.Hosting.GitHub.Models/13.5.1) package for historical reference. The package is hidden from `aspire add` because the integration is discontinued. -```bash title="Terminal" -aspire add github-models -``` - - - Learn more about [`aspire add`](/reference/cli/commands/aspire-add/) in the command reference. - - -Or, choose a manual installation approach: - ```csharp title="AppHost.cs" -#:package Aspire.Hosting.GitHub.Models@* +#:package Aspire.Hosting.GitHub.Models@13.5.1 ``` ```xml title="AppHost.csproj" - + ``` -```bash title="Terminal" -aspire add github-models -``` - - - Learn more about [`aspire add`](/reference/cli/commands/aspire-add/) in the command reference. - - -This updates your `aspire.config.json` with the GitHub Models hosting integration package: - -```json title="aspire.config.json" ins={3} +```json title="aspire.config.json" { "packages": { - "Aspire.Hosting.GitHub.Models": "%ASPIRE_VERSION%" + "Aspire.Hosting.GitHub.Models": "13.5.1" } } ``` @@ -325,7 +304,7 @@ For the full reference of GitHub Models connection properties — and how consum ## See also -- [Get started with the GitHub Models integrations](/integrations/ai/github-models/github-models-get-started/) +- [Migrate Aspire apps from GitHub Models](/integrations/ai/github-models/github-models-get-started/) - [Connect to GitHub Models](/integrations/ai/github-models/github-models-connect/) - [GitHub Models Marketplace](https://github.com/marketplace/models) - [GitHub Models documentation](https://docs.github.com/github-models) diff --git a/src/frontend/src/content/docs/integrations/cloud/azure/ai-compatibility-matrix.mdx b/src/frontend/src/content/docs/integrations/cloud/azure/ai-compatibility-matrix.mdx index 85c07c1c1..314adf183 100644 --- a/src/frontend/src/content/docs/integrations/cloud/azure/ai-compatibility-matrix.mdx +++ b/src/frontend/src/content/docs/integrations/cloud/azure/ai-compatibility-matrix.mdx @@ -27,7 +27,6 @@ The following table shows the compatibility between Aspire AI hosting and client | `Aspire.Hosting.Foundry` | ❌ No | ⚠️ Partial | ✅ Yes (preferred) | | `Aspire.Hosting.Azure.CognitiveServices` | ❌ No | ✅ Yes (preferred) | ❌ No | | `Aspire.Hosting.OpenAI` | ✅ Yes (preferred) | ✅ Yes | ❌ No | -| `Aspire.Hosting.GitHub.Models` | ⚠️ Partial | ❌ No | ✅ Yes (preferred) |