Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✅ Merge main into live #1397

Merged
merged 2 commits into from
Jul 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Python virtual environments
.venv

docs/_build/
.idea/
*.swp
Expand Down
2 changes: 2 additions & 0 deletions docfx.json
Original file line number Diff line number Diff line change
Expand Up @@ -149,10 +149,12 @@
"Docker",
"Dockerfile",
"EF Core",
"Elasticsearch",
"Entity Framework Core",
"Git",
"GitHub",
"JSON",
"Keycloak",
"Kubernetes",
"Linux",
"localhost",
Expand Down
115 changes: 115 additions & 0 deletions docs/app-host/withdockerfile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
---
title: Add Dockerfiles to your .NET app model
description: Learn how to add Dockerfiles to your .NET app model.
ms.date: 07/23/2024
---

# Add Dockerfiles to your .NET app model

With .NET Aspire it's possible to specify a _Dockerfile_ to build when the [app host](../fundamentals/app-host-overview.md) is started using either the <xref:Aspire.Hosting.ContainerResourceBuilderExtensions.AddDockerfile%2A> or <xref:Aspire.Hosting.ContainerResourceBuilderExtensions.WithDockerfile%2A> extension methods.

## Add a Dockerfile to the app model

In the following example the <xref:Aspire.Hosting.ContainerResourceBuilderExtensions.AddDockerfile%2A> extension method is used to specify a container by referencing the context path for the container build.

```csharp
var builder = DistributedApplication.CreateBuilder(args);

var container = builder.AddDockerfile(
"mycontainer", "relative/context/path");
```

Unless the context path argument is a rooted path the context path is interpreted as being relative to the app host projects directory (where the AppHost `*.csproj` folder is located).

By default the name of the _Dockerfile_ which is used is `Dockerfile` and is expected to be within the context path directory. It's possible to explicitly specify the _Dockerfile_ name either as an absolute path or a relative path to the context path.

This is useful if you wish to modify the specific _Dockerfile_ being used when running locally or when the app host is deploying.

```csharp
var builder = DistributedApplication.CreateBuilder(args);

var container = builder.ExecutionContext.IsRunMode
? builder.AddDockerfile(
"mycontainer", "relative/context/path", "Dockerfile.debug")
: builder.AddDockerfile(
"mycontainer", "relative/context/path", "Dockerfile.release");
```

## Customize existing container resources

When using <xref:Aspire.Hosting.ContainerResourceBuilderExtensions.AddDockerfile%2A> the return value is an `IResourceBuilder<ContainerResource>`. .NET Aspire includes many custom resource types that are derived from <xref:Aspire.Hosting.ApplicationModel.ContainerResource>.

Using the <xref:Aspire.Hosting.ContainerResourceBuilderExtensions.WithDockerfile%2A> extension method it's possible to continue using these strongly typed resource types and customize the underlying container that is used.

```csharp
var builder = DistributedApplication.CreateBuilder(args);

var pgsql = builder.AddPostgres("pgsql")
.WithDockerfile("path/to/context")
.WithPgAdmin();
```

## Pass build arguments

The <xref:Aspire.Hosting.ContainerResourceBuilderExtensions.WithBuildArg%2A> method can be used to pass arguments into the container image build.

```csharp
var builder = DistributedApplication.CreateBuilder(args);

var container = builder.AddDockerfile("mygoapp", "relative/context/path")
.WithBuildArg("GO_VERSION", "1.22");
```

The value parameter on the <xref:Aspire.Hosting.ContainerResourceBuilderExtensions.WithBuildArg%2A> method can be a literal value (`boolean`, `string`, `int`) or it can be a resource builder for a [parameter resource](../fundamentals/external-parameters.md). The following code replaces the `GO_VERSION` with a parameter value that can be specified at deployment time.

```csharp
var builder = DistributedApplication.CreateBuilder(args);

var goVersion = builder.AddParameter("goversion");

var container = builder.AddDockerfile("mygoapp", "relative/context/path")
.WithBuildArg("GO_VERSION", goVersion);
```

Build arguments correspond to the [`ARG` command](https://docs.docker.com/build/guide/build-args/) in _Dockerfiles_. Expanding the preceding example, this is a multi-stage _Dockerfile_ which specifies specific container image version to use as a parameter.

```dockerfile
# Stage 1: Build the Go program
ARG GO_VERSION=1.22
FROM golang:${GO_VERSION} AS builder
WORKDIR /build
COPY . .
RUN go build mygoapp.go

# Stage 2: Run the Go program
FROM mcr.microsoft.com/cbl-mariner/base/core:2.0
WORKDIR /app
COPY --from=builder /build/mygoapp .
CMD ["./mygoapp"]
```

> [!NOTE]
> Instead of hardcoding values into the container image, it's recommended to use environment variables for values that frequently change. This avoids the need to rebuild the container image whenever a change is required.

## Pass build secrets

In addition to build arguments it's possible to specify build secrets using <xref:Aspire.Hosting.ContainerResourceBuilderExtensions.WithBuildSecret%2A> which are made selectively available to individual commands in the _Dockerfile_ using the `--mount=type=secret` syntax on `RUN` commands.

```csharp
var builder = DistributedApplication.CreateBuilder(args);

var accessToken = builder.AddParameter("accesstoken", secret: true);

var container = builder.AddDockerfile("myapp", "relative/context/path")
.WithBuildSecret("ACCESS_TOKEN", accessToken);
```

For example, consider the `RUN` command in a _Dockerfile_ which exposes the specified secret to the specific command:

```dockerfile
# The helloworld command can read the secret from /run/secrets/ACCESS_TOKEN
RUN --mount=type=secret,id=ACCESS_TOKEN helloworld
```

> [!CAUTION]
> Caution should be exercised when passing secrets in build environments. This is often done when using a token to retrieve dependencies from private repositories or feeds before a build. It is important to ensure that the injected secrets are not copied into the final or intermediate images.
134 changes: 134 additions & 0 deletions docs/authentication/keycloak-component.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
---
title: .NET Aspire Keycloak component
description: This article describes the .NET Aspire Keycloak component.
ms.topic: how-to
ms.date: 07/23/2024
---

# .NET Aspire Keycloak component

In this article, you learn how to use the .NET Aspire Keycloak component. The `Aspire.Keycloak.Authentication` library registers JwtBearer and OpenId Connect authentication handlers in the DI container for connecting to a Keycloak server.

## Prerequisites

- A Keycloak server instance.
- A Keycloak realm.
- For JwtBearer authentication, a configured audience in the Keycloak realm.
- For OpenId Connect authentication, the ID of a client configured in the Keycloak realm.

## Get started

To get started with the .NET Aspire Keycloak component, install the [Aspire.Keycloak.Authentication](https://www.nuget.org/packages/Aspire.Keycloak.Authentication) NuGet package in the consuming client project.

### [.NET CLI](#tab/dotnet-cli)

```dotnetcli
dotnet add package Aspire.Keycloak.Authentication
```

### [PackageReference](#tab/package-reference)

```xml
<PackageReference Include="Aspire.Keycloak.Authentication"
Version="[SelectVersion]" />
```

---

For more information, see [dotnet add package](/dotnet/core/tools/dotnet-add-package) or [Manage package dependencies in .NET applications](/dotnet/core/tools/dependencies).

## Jwt bearer authentication usage example

In the _Program.cs_ file of your ASP.NET Core API project, call the `AddKeycloakJwtBearer` extension method to add JwtBearer authentication, using a connection name, realm and any required JWT Bearer options:

```csharp
builder.Services.AddAuthentication()
.AddKeycloakJwtBearer("keycloak", realm: "WeatherShop", options =>
{
options.Audience = "weather.api";
});
```

You can set many other options via the `Action<JwtBearerOptions> configureOptions` delegate.

## OpenId Connect authentication usage example

In the _Program.cs_ file of your Blazor project, call the `AddKeycloakOpenIdConnect` extension method to add OpenId Connect authentication, using a connection name, realm and any required OpenId Connect options:

```csharp
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddKeycloakOpenIdConnect(
"keycloak",
realm: "WeatherShop",
options =>
{
options.ClientId = "WeatherWeb";
options.ResponseType = OpenIdConnectResponseType.Code;
options.Scope.Add("weather:all");
});
```

You can set many other options via the `Action<OpenIdConnectOptions>? configureOptions` delegate.

## App host usage

To model the Keycloak resource in the app host, install the [Aspire.Hosting.Keycloak](https://www.nuget.org/packages/Aspire.Hosting.Keycloak) NuGet package in the [app host](xref:aspire/app-host) project.

### [.NET CLI](#tab/dotnet-cli)

```dotnetcli
dotnet add package Aspire.Hosting.Keycloak
```

### [PackageReference](#tab/package-reference)

```xml
<PackageReference Include="Aspire.Hosting.Keycloak"
Version="[SelectVersion]" />
```

---

Then, in the _Program.cs_ file of `AppHost`, register a Keycloak server and consume the connection using the following methods:

```csharp
var keycloak = builder.AddKeycloak("keycloak", 8080);

var apiService = builder.AddProject<Projects.Keycloak_ApiService>("apiservice")
.WithReference(keycloak);

builder.AddProject<Projects.Keycloak_Web>("webfrontend")
.WithExternalHttpEndpoints()
.WithReference(keycloak)
.WithReference(apiService);
```

> [!TIP]
> For local development use a stable port for the Keycloak resource (8080 in the example above). It can be any port, but it should be stable to avoid issues with browser cookies that will persist OIDC tokens (which include the authority URL, with port) beyond the lifetime of the _app host_.

The `WithReference` method configures a connection in the `Keycloak.ApiService` and `Keycloak.Web` projects named `keycloak`.

In the _Program.cs_ file of `Keycloak.ApiService`, the Keycloak connection can be consumed using:

```csharp
builder.Services.AddAuthentication()
.AddKeycloakJwtBearer("keycloak", realm: "WeatherShop");
```

In the _Program.cs_ file of `Keycloak.Web`, the Keycloak connection can be consumed using:

```csharp
var oidcScheme = OpenIdConnectDefaults.AuthenticationScheme;

builder.Services.AddAuthentication(oidcScheme)
.AddKeycloakOpenIdConnect(
"keycloak",
realm: "WeatherShop",
oidcScheme);
```

## See also

- [Keycloak](https://www.keycloak.org/)
- [.NET Aspire components](../fundamentals/components-overview.md)
- [.NET Aspire GitHub repo](https://github.com/dotnet/aspire)
33 changes: 33 additions & 0 deletions docs/caching/includes/garnet-app-host.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
To model the Garnet resource (`GarnetResource`) in the app host, install the [Aspire.Hosting.Garnet](https://www.nuget.org/packages/Aspire.Hosting.Garnet) NuGet package in the [app host](xref:aspire/app-host) project.

### [.NET CLI](#tab/dotnet-cli)

```dotnetcli
dotnet add package Aspire.Hosting.Garnet
```

### [PackageReference](#tab/package-reference)

```xml
<PackageReference Include="Aspire.Hosting.Garnet"
Version="[SelectVersion]" />
```

---

In your app host project, register .NET Aspire Garnet as a `GarnetResource` using the `AddGarnet` method and consume the service using the following methods:

```csharp
var builder = DistributedApplication.CreateBuilder(args);

var cache = builder.AddGarnet("cache");

builder.AddProject<Projects.ExampleProject>()
.WithReference(cache)
```

The <xref:Aspire.Hosting.ResourceBuilderExtensions.WithReference%2A> method configures a connection in the `ExampleProject` project named `cache`. In the _:::no-loc text="Program.cs":::_ file of `ExampleProject`, the Garnet connection can be consumed using:

```csharp
builder.AddGarnet("cache");
```
17 changes: 16 additions & 1 deletion docs/caching/includes/redis-app-host.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
To model the Redis resource in the app host, install the [Aspire.Hosting.Redis](https://www.nuget.org/packages/Aspire.Hosting.Redis) NuGet package in the [app host](xref:aspire/app-host) project.
To model the Redis resource (`RedisResource`) in the app host, install the [Aspire.Hosting.Redis](https://www.nuget.org/packages/Aspire.Hosting.Redis) NuGet package in the [app host](xref:aspire/app-host) project.

### [.NET CLI](#tab/dotnet-cli)

Expand All @@ -16,3 +16,18 @@ dotnet add package Aspire.Hosting.Redis
---

In your app host project, register the .NET Aspire Stack Exchange Redis as a resource using the <xref:Aspire.Hosting.RedisBuilderExtensions.AddRedis%2A> method and consume the service using the following methods:

```csharp
var builder = DistributedApplication.CreateBuilder(args);

var cache = builder.AddRedis("cache");

builder.AddProject<Projects.ExampleProject>()
.WithReference(cache)
```

The <xref:Aspire.Hosting.ResourceBuilderExtensions.WithReference%2A> method configures a connection in the `ExampleProject` project named `cache`. In the _:::no-loc text="Program.cs":::_ file of `ExampleProject`, the Redis connection can be consumed using:

```csharp
builder.AddRedis("cache");
```
33 changes: 33 additions & 0 deletions docs/caching/includes/valkey-app-host.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
To model the Valkey resource (`ValkeyResource`) in the app host, install the [Aspire.Hosting.Valkey](https://www.nuget.org/packages/Aspire.Hosting.Valkey) NuGet package in the [app host](xref:aspire/app-host) project.

### [.NET CLI](#tab/dotnet-cli)

```dotnetcli
dotnet add package Aspire.Hosting.Valkey
```

### [PackageReference](#tab/package-reference)

```xml
<PackageReference Include="Aspire.Hosting.Valkey"
Version="[SelectVersion]" />
```

---

In your app host project, register the .NET Aspire Valkey as a resource using the `AddValkey` method and consume the service using the following methods:

```csharp
var builder = DistributedApplication.CreateBuilder(args);

var cache = builder.AddValkey("cache");

builder.AddProject<Projects.ExampleProject>()
.WithReference(cache)
```

The <xref:Aspire.Hosting.ResourceBuilderExtensions.WithReference%2A> method configures a connection in the `ExampleProject` project named `cache`. In the _:::no-loc text="Program.cs":::_ file of `ExampleProject`, the Valkey connection can be consumed using:

```csharp
builder.AddValkey("cache");
```
Loading
Loading