diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 463ddcdc9..41b99e069 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -31,6 +31,6 @@ "onAutoForward": "openBrowser" } }, - "postCreateCommand": "pnpm install && echo '\n✨ Ready to go! Run \"pnpm dev\" to start the dev server.\n'", + "postCreateCommand": "pnpm install && npx astro telemetry disable && echo '\n✨ Ready to go! Run \"pnpm dev\" to start the dev server.\n'", "remoteUser": "node" } \ No newline at end of file diff --git a/.github/workflows/frontend-build.yml b/.github/workflows/frontend-build.yml index 597f0f6d1..080dc1b5f 100644 --- a/.github/workflows/frontend-build.yml +++ b/.github/workflows/frontend-build.yml @@ -37,6 +37,9 @@ jobs: - name: Install deps run: pnpm install --frozen-lockfile + - name: Disable Astro telemetry + run: npx astro telemetry disable + - name: Build frontend env: MODE: production diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 619798e55..feb2fa18f 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -38,6 +38,9 @@ jobs: - name: Install frontend deps run: pnpm install --frozen-lockfile + - name: Disable Astro telemetry + run: npx astro telemetry disable + - name: Build frontend env: MODE: production diff --git a/src/frontend/config/sidebar/docs.topics.ts b/src/frontend/config/sidebar/docs.topics.ts index 0d2791c6e..b49e6f444 100644 --- a/src/frontend/config/sidebar/docs.topics.ts +++ b/src/frontend/config/sidebar/docs.topics.ts @@ -556,6 +556,28 @@ export const docsTopics: StarlightSidebarTopicsUserConfig = { }, slug: 'fundamentals/service-discovery', }, + { + label: 'Environment variables', + slug: 'fundamentals/environment-variables', + translations: { + da: 'Miljøvariabler', + de: 'Umgebungsvariablen', + en: 'Environment variables', + es: 'Variables de entorno', + fr: "Variables d'environnement", + hi: 'पर्यावरण चर', + id: 'Variabel lingkungan', + it: 'Variabili di ambiente', + ja: '環境変数', + ko: '환경 변수', + 'pt-BR': 'Variáveis de ambiente', + 'pt-PT': 'Variáveis de ambiente', + ru: 'Переменные среды', + tr: 'Ortam değişkenleri', + uk: 'Змінні середовища', + 'zh-CN': '环境变量', + }, + }, { label: 'Service defaults', translations: { diff --git a/src/frontend/src/content/docs/fundamentals/environment-variables.mdx b/src/frontend/src/content/docs/fundamentals/environment-variables.mdx new file mode 100644 index 000000000..150c4671a --- /dev/null +++ b/src/frontend/src/content/docs/fundamentals/environment-variables.mdx @@ -0,0 +1,222 @@ +--- +title: Environment variables +description: Learn how Aspire generates environment variables from resource names and how to access them in your applications. +--- + +import { Aside } from '@astrojs/starlight/components'; + +When you use `WithReference` to connect resources in the AppHost, Aspire automatically injects environment variables into the consuming resource—this is often referred to as *configuration injection*. + +These environment variable names follow specific conventions based on the referenced resource's name and its type. Understanding these conventions is especially important for non-.NET applications (such as Python, Node.js, or Go), where you read environment variables directly instead of relying on typed Aspire client integrations. + +## Naming conventions + +Aspire generates environment variables in different formats depending on the type of resource being referenced. The following sections describe each category. + +### Connection strings + +When you reference a resource that exposes a connection string (such as a database, cache, or messaging resource), Aspire generates an environment variable using the `ConnectionStrings__` prefix: + +```txt +ConnectionStrings__{resource-name} +``` + +The resource name is used **as-is** (preserving the original casing and hyphens). For example: + +```csharp title="C# — AppHost.cs" +var builder = DistributedApplication.CreateBuilder(args); + +var cache = builder.AddRedis("my-cache"); +var db = builder.AddPostgres("postgres").AddDatabase("my-db"); + +var api = builder.AddProject("api") + .WithReference(cache) + .WithReference(db); + +// After adding all resources, run the app... +builder.Build().Run(); +``` + +The `api` resource receives the following environment variables: + +| Environment variable | Description | +|---|---| +| `ConnectionStrings__my-cache` | Connection string for the Redis cache | +| `ConnectionStrings__my-db` | Connection string for the PostgreSQL database | + + + +### Endpoint URLs + +When you reference a resource that exposes HTTP or HTTPS endpoints (such as a project or container service), Aspire generates environment variables for the endpoint URLs. The resource name is first **encoded** (hyphens and other non-alphanumeric characters are replaced with underscores), then **uppercased**: + +```txt +{RESOURCE_NAME}_{SCHEME} +``` + +If the resource only exposes a single endpoint, the scheme suffix is omitted: + +```txt +{RESOURCE_NAME} +``` + +For example: + +```csharp title="C# — AppHost.cs" +var builder = DistributedApplication.CreateBuilder(args); + +var api = builder.AddProject("my-api"); + +var frontend = builder.AddJavaScriptApp("frontend", "./app") + .WithReference(api); + +// After adding all resources, run the app... +builder.Build().Run(); +``` + +The `frontend` resource receives: + +| Environment variable | Example value | +|---|---| +| `MY_API_HTTP` | `http://localhost:5000` | +| `MY_API_HTTPS` | `https://localhost:5001` | + +### Service discovery variables + +In addition to the endpoint URL variables, Aspire also generates service discovery variables for .NET service resolution. These use the format: + +```txt +services__{resourcename}__{scheme}__{index} +``` + +These variables use double underscores (`__`) as separators and are **lowercase**. For example, `services__my-api__http__0`. .NET applications use these automatically through the service discovery system. Non-.NET applications should use the [endpoint URL variables](#endpoint-urls) instead. + +### Resource properties + +Some integrations expose individual resource properties as environment variables. The resource name is **encoded** (hyphens replaced with underscores) and **uppercased**, with the property name appended: + +```txt +{RESOURCE_NAME}_{PROPERTY} +``` + +For example, a ClickHouse resource named `my-clickhouse` exposes: + +| Environment variable | Description | +|---|---| +| `MY_CLICKHOUSE_HOST` | The hostname | +| `MY_CLICKHOUSE_PORT` | The port number | +| `MY_CLICKHOUSE_USERNAME` | The username | +| `MY_CLICKHOUSE_PASSWORD` | The password | +| `MY_CLICKHOUSE_DATABASENAME` | The database name | + +## Resource name encoding rules + +When a resource name is used in an endpoint URL or property variable, Aspire applies the following transformations: + +1. **Non-alphanumeric characters are replaced with underscores**: Hyphens (`-`), dots (`.`), and any other characters that aren't ASCII letters or digits are replaced with `_`. +2. **Leading digits get a prefix**: If the name starts with a digit, an underscore (`_`) is prepended. +3. **The result is uppercased**: The encoded name is converted to uppercase for the final environment variable name. + +For example, a resource named `foundry-demo-proj` becomes `FOUNDRY_DEMO_PROJ` in environment variable prefixes: + +| Resource name | Encoded prefix | Example variable | +|---|---|---| +| `api` | `API` | `API_HTTP` | +| `my-api` | `MY_API` | `MY_API_HTTPS` | +| `foundry-demo-proj` | `FOUNDRY_DEMO_PROJ` | `FOUNDRY_DEMO_PROJ_URI` | + + + +## Accessing environment variables + +### C\# + +In .NET applications, Aspire client integrations handle environment variable access automatically. For manual access: + +```csharp title="C# — Program.cs" +// Connection strings +string cache = builder.Configuration.GetConnectionString("my-cache"); + +// Endpoint URLs +string apiUrl = builder.Configuration.GetValue("MY_API_HTTP"); + +// Resource properties +string host = builder.Configuration.GetValue("MY_CLICKHOUSE_HOST"); +``` + +### Python + +```python title="Python — main.py" +import os + +# Connection strings +cache_conn = os.getenv("ConnectionStrings__my-cache") + +# Endpoint URLs +api_url = os.getenv("MY_API_HTTP") + +# Resource properties +db_host = os.getenv("MY_CLICKHOUSE_HOST") +``` + +### JavaScript / TypeScript + +```javascript title="JavaScript — app.js" +// Connection strings (use bracket notation for names with hyphens) +const cacheConn = process.env["ConnectionStrings__my-cache"]; + +// Endpoint URLs +const apiUrl = process.env.MY_API_HTTP; + +// Resource properties +const dbHost = process.env.MY_CLICKHOUSE_HOST; +``` + + + +## Custom environment variables + +If you need different variable names, use `WithEnvironment` to set custom environment variables: + +```csharp title="C# — AppHost.cs" +var builder = DistributedApplication.CreateBuilder(args); + +var db = builder.AddPostgres("postgres").AddDatabase("my-db"); + +var api = builder.AddPythonApp("api", "../api", "main.py") + .WithReference(db) + .WithEnvironment("DB_HOST", db.Resource.Parent.PrimaryEndpoint.Property(EndpointProperty.Host)) + .WithEnvironment("DB_PORT", db.Resource.Parent.PrimaryEndpoint.Property(EndpointProperty.Port)); + +// After adding all resources, run the app... +builder.Build().Run(); +``` + +This approach lets you define explicit, predictable variable names without relying on the automatic naming conventions. + + + +## See also + +- [Service discovery](/fundamentals/service-discovery/) +- [Inner-loop networking overview](/fundamentals/networking-overview/) +- [Python integration](/integrations/frameworks/python/) +- [JavaScript integration](/integrations/frameworks/javascript/) +- [Executable resources](/app-host/executable-resources/) +- [Deployment manifest format](/deployment/manifest-format/) diff --git a/src/frontend/src/content/docs/fundamentals/service-discovery.mdx b/src/frontend/src/content/docs/fundamentals/service-discovery.mdx index 67e564e65..9174b02ff 100644 --- a/src/frontend/src/content/docs/fundamentals/service-discovery.mdx +++ b/src/frontend/src/content/docs/fundamentals/service-discovery.mdx @@ -24,6 +24,12 @@ var frontend = builder.AddProject("frontend") In the preceding example, the _frontend_ project references the _catalog_ project and the _basket_ project. The two `WithReference` calls instruct the Aspire project to pass service discovery information for the referenced projects (_catalog_, and _basket_) into the _frontend_ project. + + ## Named endpoints Some services expose multiple, named endpoints. Named endpoints can be resolved by specifying the endpoint name in the host portion of the HTTP request URI, following the format `scheme://_endpointName.serviceName`. For example, if a service named "basket" exposes an endpoint named "dashboard", then the URI `https+http://_dashboard.basket` can be used to specify this endpoint, for example: diff --git a/src/frontend/src/content/docs/integrations/frameworks/javascript.mdx b/src/frontend/src/content/docs/integrations/frameworks/javascript.mdx index 817015183..4b259d0ce 100644 --- a/src/frontend/src/content/docs/integrations/frameworks/javascript.mdx +++ b/src/frontend/src/content/docs/integrations/frameworks/javascript.mdx @@ -253,6 +253,29 @@ Common environment variables for JavaScript frameworks: - **VITE_PORT**: For Vite applications - **HOST**: Some frameworks also use this to bind to specific interfaces +When you use `WithReference` to connect a JavaScript app to other resources, Aspire injects environment variables with the connection details. For example: + +```csharp title="C# — AppHost.cs" +var builder = DistributedApplication.CreateBuilder(args); + +var db = builder.AddPostgres("postgres").AddDatabase("mydb"); + +var app = builder.AddJavaScriptApp("app", "./app") + .WithHttpEndpoint(port: 3000, env: "PORT") + .WithReference(db); + +// After adding all resources, run the app... +builder.Build().Run(); +``` + +Access the connection string in your JavaScript code: + +```javascript title="JavaScript — app.js" +const connectionString = process.env.ConnectionStrings__mydb; +``` + +For more details on how resource names map to environment variable names, see [Environment variables](/fundamentals/environment-variables/). + ## Customize Vite configuration For Vite applications, you can specify a custom configuration file if you need to override the default Vite configuration resolution behavior: @@ -302,6 +325,7 @@ This ensures your JavaScript applications are built consistently across environm ## See also +- [Environment variables](/fundamentals/environment-variables/) - How Aspire generates environment variable names from resources - [Node.js hosting extensions](/integrations/frameworks/nodejs-extensions/) - Community Toolkit extensions for Vite, Yarn, and pnpm - [What's new in Aspire 13](/whats-new/aspire-13/) - Learn about first-class JavaScript support - [Aspire integrations overview](/integrations/overview/) diff --git a/src/frontend/src/content/docs/integrations/frameworks/python.mdx b/src/frontend/src/content/docs/integrations/frameworks/python.mdx index 681fdfd7b..1956a54f8 100644 --- a/src/frontend/src/content/docs/integrations/frameworks/python.mdx +++ b/src/frontend/src/content/docs/integrations/frameworks/python.mdx @@ -289,7 +289,15 @@ var python = builder.AddPythonApp("python-api", "../python-app", "main.py") // After adding all resources, run the app... ``` -The connection string will be available as an environment variable in the Python application. +The connection string is available as an environment variable named `ConnectionStrings__mydb` in the Python application. Access it with: + +```python title="Python — main.py" +import os + +connection_string = os.getenv("ConnectionStrings__mydb") +``` + +For more details on how resource names map to environment variable names, see [Environment variables](/fundamentals/environment-variables/). ## Debugging @@ -330,6 +338,7 @@ The generated Dockerfile is tailored to your detected Python version and depende ## See also +- [Environment variables](/fundamentals/environment-variables/) - How Aspire generates environment variable names from resources - [Build your first Aspire app](/get-started/first-app/) - [Deploy your first Aspire app](/get-started/deploy-first-app/) - [Aspire integrations overview](/integrations/overview/)