-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
36 changed files
with
1,590 additions
and
395 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,35 @@ | ||
var builder = DistributedApplication.CreateBuilder(args); | ||
|
||
var useLocalModelParam = builder.AddParameter("use-local-model"); | ||
var endpointParam = builder.AddParameter("endpoint"); | ||
var deploymentNameParam = builder.AddParameter("deployment-name"); | ||
var apiKeyParam = builder.AddParameter("api-key", secret: true); | ||
|
||
var apiService = builder.AddProject<Projects.aspire_project_ApiService>("apiservice"); | ||
|
||
builder.AddProject<Projects.aspire_project_Web>("webfrontend") | ||
.WithExternalHttpEndpoints() | ||
.WithReference(apiService); | ||
builder.AddProject<Projects.aspire_project_Web>("webfrontend").WithExternalHttpEndpoints().WithReference(apiService); | ||
|
||
var dependify = builder.AddDependify().ServeFrom("../../../"); | ||
|
||
if (useLocalModelParam.Resource.Value.ToString().Equals("true", StringComparison.OrdinalIgnoreCase)) | ||
{ | ||
var modelName = "phi3:mini"; | ||
var ollama = builder.AddOllama("ollama").WithDataVolume().AddModel(modelName).WithOpenWebUI(); | ||
|
||
builder.AddDependify("dependify1", port: 10000).WithDockerfile("..", "./aspire-project.AppHost/dependify.dockerfile"); | ||
dependify.WithOpenAI(ollama, modelName); | ||
} | ||
else | ||
{ | ||
// Configure the AppHost with the following command: | ||
// dotnet user-secrets set "Parameters:api-key" "<api-key>" | ||
// dotnet user-secrets set "Parameters:deployment-name" "gpt-4o-mini" | ||
// dotnet user-secrets set "Parameters:endpoint" "<endpoint>" | ||
|
||
builder.AddDependify("dependify2", port: 10001).ServeFrom("../../aspire-project/"); | ||
dependify.WithAzureOpenAI( | ||
endpointParam.Resource.Value.ToString(), | ||
deploymentNameParam.Resource.Value.ToString(), | ||
apiKeyParam.Resource.Value.ToString() | ||
); | ||
} | ||
|
||
builder.Build().Run(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# AppHost | ||
|
||
```csharp | ||
builder.AddDependify("dependify2", port: 10001).ServeFrom("../../aspire-project/"); | ||
``` | ||
|
||
Control what is gets copied to workspace with dockerfile | ||
|
||
```csharp | ||
builder.AddDependify("dependify1", port: 10000).WithDockerfile("..", "./aspire-project.AppHost/dependify.dockerfile"); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 11 additions & 0 deletions
11
src/Dependify.Aspire.Hosting.Ollama/Dependify.Aspire.Hosting.Ollama.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<PropertyGroup> | ||
<IsPackable>true</IsPackable> | ||
<PackageTags>aspire hosting ollama llm ai</PackageTags> | ||
<Description>Ollama support for .NET Aspire.</Description> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<PackageReference Include="Aspire.Hosting" /> | ||
<PackageReference Include="OllamaSharp" /> | ||
</ItemGroup> | ||
</Project> |
175 changes: 175 additions & 0 deletions
175
src/Dependify.Aspire.Hosting.Ollama/OllamaBuilderExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
namespace Aspire.Hosting; | ||
|
||
using Aspire.Hosting.Lifecycle; | ||
using Aspire.Hosting.ApplicationModel; | ||
using Aspire.Hosting.Ollama; | ||
|
||
/// <summary> | ||
/// Provides extension methods for adding Ollama to the application model. | ||
/// </summary> | ||
public static class OllamaBuilderExtensions | ||
{ | ||
/// <summary> | ||
/// Adds an Ollama resource to the application. A container is used for local development. | ||
/// </summary> | ||
/// <example> | ||
/// Use in application host | ||
/// <code lang="csharp"> | ||
/// var builder = DistributedApplication.CreateBuilder(args); | ||
/// | ||
/// var ollama = builder.AddOllama("ollama"); | ||
/// var api = builder.AddProject<Projects.Api>("api") | ||
/// .WithReference(ollama); | ||
/// | ||
/// builder.Build().Run(); | ||
/// </code> | ||
/// </example> | ||
/// <remarks> | ||
/// This version the package defaults to the 0.3.4 tag of the ollama/ollama container image. | ||
/// The .NET client library uses the http port by default to communicate and this resource exposes that endpoint. | ||
/// </remarks> | ||
/// <param name="builder">The <see cref="IDistributedApplicationBuilder"/>.</param> | ||
/// <param name="name">The name of the resource. This name will be used as the connection string name when referenced in a dependency</param> | ||
/// <param name="enableGpu">Whether to enable GPU support.</param> | ||
/// <param name="port">The host port of the http endpoint of Ollama resource.</param> | ||
/// <returns>A reference to the <see cref="IResourceBuilder{OllamaResource}"/>.</returns> | ||
public static IResourceBuilder<OllamaResource> AddOllama( | ||
this IDistributedApplicationBuilder builder, | ||
string name, | ||
bool enableGpu = false, | ||
int? port = null | ||
) | ||
{ | ||
builder.Services.TryAddLifecycleHook<OllamaLifecycleHook>(); | ||
|
||
var ollama = new OllamaResource(name); | ||
|
||
var resource = builder | ||
.AddResource(ollama) | ||
.WithImage(OllamaContainerImageTags.Image, OllamaContainerImageTags.Tag) | ||
.WithImageRegistry(OllamaContainerImageTags.Registry) | ||
.WithHttpEndpoint(port: port, targetPort: 11434, OllamaResource.PrimaryEndpointName) | ||
.ExcludeFromManifest() | ||
.PublishAsContainer(); | ||
|
||
if (enableGpu) | ||
{ | ||
resource = resource.WithContainerRuntimeArgs("--gpus=all"); | ||
} | ||
|
||
return resource; | ||
} | ||
|
||
/// <summary> | ||
/// Adds a model to the Ollama resource. | ||
/// </summary> | ||
/// <example> | ||
/// Use in application host | ||
/// <code lang="csharp"> | ||
/// var builder = DistributedApplication.CreateBuilder(args); | ||
/// | ||
/// var ollama = builder.AddOllama("ollama"); | ||
/// .AddModel("phi3") | ||
/// .WithDataVolume("ollama"); | ||
/// | ||
/// var api = builder.AddProject<Projects.Api>("api") | ||
/// .WithReference(ollama); | ||
/// | ||
/// builder.Build().Run(); | ||
/// </code> | ||
/// </example> | ||
/// <param name="builder">The Ollama resource builder.</param> | ||
/// <param name="modelName">The name of the model.</param> | ||
/// <remarks>This method will attempt to pull/download the model into the Ollama instance.</remarks> | ||
/// <returns>A reference to the <see cref="IResourceBuilder{T}"/>.</returns> | ||
public static IResourceBuilder<OllamaResource> AddModel( | ||
this IResourceBuilder<OllamaResource> builder, | ||
string modelName | ||
) | ||
{ | ||
builder.Resource.AddModel(modelName); | ||
return builder; | ||
} | ||
|
||
/// <summary> | ||
/// Adds a named volume for the data folder to a Ollama container resource. | ||
/// </summary> | ||
/// <param name="builder">The resource builder.</param> | ||
/// <param name="name">The name of the volume. Defaults to an auto-generated name based on the resource name.</param> | ||
/// <param name="isReadOnly">A flag that indicates if this is a read-only volume.</param> | ||
/// <returns>The <see cref="IResourceBuilder{T}"/>.</returns> | ||
public static IResourceBuilder<OllamaResource> WithDataVolume( | ||
this IResourceBuilder<OllamaResource> builder, | ||
string? name = null, | ||
bool isReadOnly = false | ||
) => builder.WithVolume(name ?? "ollama-aspire-data", "/root/.ollama", isReadOnly); | ||
|
||
/// <summary> | ||
/// Adds a bind mount for the data folder to an Ollama container resource. | ||
/// </summary> | ||
/// <param name="builder">The resource builder.</param> | ||
/// <param name="source">The source directory on the host to mount into the container.</param> | ||
/// <param name="isReadOnly">A flag that indicates if this is a read-only mount.</param> | ||
/// <returns>The <see cref="IResourceBuilder{T}"/>.</returns> | ||
public static IResourceBuilder<OllamaResource> WithDataBindMount( | ||
this IResourceBuilder<OllamaResource> builder, | ||
string source, | ||
bool isReadOnly = false | ||
) => builder.WithBindMount(source, "/root/.ollama", isReadOnly); | ||
|
||
/// <summary> | ||
/// Adds an administration web UI Ollama to the application model using Attu. This version the package defaults to the main tag of the Open WebUI container image | ||
/// </summary> | ||
/// <example> | ||
/// Use in application host with an Ollama resource | ||
/// <code lang="csharp"> | ||
/// var builder = DistributedApplication.CreateBuilder(args); | ||
/// | ||
/// var ollama = builder.AddOllama("ollama") | ||
/// .WithOpenWebUI(); | ||
/// var api = builder.AddProject<Projects.Api>("api") | ||
/// .WithReference(ollama); | ||
/// | ||
/// builder.Build().Run(); | ||
/// </code> | ||
/// </example> | ||
/// <param name="builder">The Ollama resource builder.</param> | ||
/// <param name="configureContainer">Configuration callback for Open WebUI container resource.</param> | ||
/// <param name="containerName">The name of the container (Optional).</param> | ||
/// <returns>A reference to the <see cref="IResourceBuilder{T}"/>.</returns> | ||
/// <remarks>See https://openwebui.com for more information about Open WebUI</remarks> | ||
public static IResourceBuilder<T> WithOpenWebUI<T>( | ||
this IResourceBuilder<T> builder, | ||
Action<IResourceBuilder<OpenWebUIResource>>? configureContainer = null, | ||
string? containerName = null | ||
) | ||
where T : OllamaResource | ||
{ | ||
containerName ??= $"{builder.Resource.Name}-openwebui"; | ||
|
||
var openWebUI = new OpenWebUIResource(containerName); | ||
var resourceBuilder = builder | ||
.ApplicationBuilder.AddResource(openWebUI) | ||
.WithImage(OllamaContainerImageTags.OpenWebUIImage, OllamaContainerImageTags.OpenWebUITag) | ||
.WithImageRegistry(OllamaContainerImageTags.OpenWebUIRegistry) | ||
.WithHttpEndpoint(targetPort: 8080, name: "http") | ||
.WithVolume("open-webui", "/app/backend/data") | ||
.WithEnvironment(context => ConfigureOpenWebUIContainer(context, builder.Resource)) | ||
.ExcludeFromManifest(); | ||
|
||
configureContainer?.Invoke(resourceBuilder); | ||
|
||
return builder; | ||
} | ||
|
||
private static void ConfigureOpenWebUIContainer(EnvironmentCallbackContext context, OllamaResource resource) | ||
{ | ||
context.EnvironmentVariables.Add("ENABLE_SIGNUP", "false"); | ||
context.EnvironmentVariables.Add("ENABLE_COMMUNITY_SHARING", "false"); // by default don't enable sharing | ||
context.EnvironmentVariables.Add("WEBUI_AUTH", "false"); // https://docs.openwebui.com/#quick-start-with-docker--recommended | ||
context.EnvironmentVariables.Add( | ||
"OLLAMA_BASE_URL", | ||
$"{resource.PrimaryEndpoint.Scheme}://{resource.PrimaryEndpoint.ContainerHost}:{resource.PrimaryEndpoint.Port}" | ||
); | ||
} | ||
} |
Oops, something went wrong.