Skip to content

Commit e075356

Browse files
committed
Add YARP support for static file serving and reverse proxy; update Docker and Docker Compose configurations
1 parent d6dba7f commit e075356

File tree

6 files changed

+41
-98
lines changed

6 files changed

+41
-98
lines changed

AIChat.AppHost/AIChat.AppHost.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
<PackageReference Include="Aspire.Hosting.PostgreSQL" Version="9.5.0" />
1919
<PackageReference Include="Aspire.Hosting.Redis" Version="9.5.0" />
2020
<PackageReference Include="Aspire.Hosting.NodeJs" Version="9.5.0" />
21+
<PackageReference Include="Aspire.Hosting.Yarp" Version="9.5.0-preview.1.25474.7" />
2122
<PackageReference Include="CommunityToolkit.Aspire.Hosting.NodeJS.Extensions" Version="9.4.0" />
2223
<PackageReference Include="CommunityToolkit.Aspire.Hosting.Ollama" Version="9.4.0" />
2324
</ItemGroup>

AIChat.AppHost/Program.cs

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,27 @@
4747
.WithReference(cache)
4848
.WaitFor(cache);
4949

50-
builder.AddNpmApp("chatui", "../chatui")
51-
.WithNpmPackageInstallation()
52-
.WithHttpEndpoint(env: "PORT")
53-
.WithReverseProxy(chatapi.GetEndpoint("http"))
50+
if (builder.ExecutionContext.IsRunMode)
51+
{
52+
builder.AddNpmApp("chatui-fe", "../chatui")
53+
.WithNpmPackageInstallation()
54+
.WithHttpEndpoint(env: "PORT")
55+
.WithEnvironment("BACKEND_URL", chatapi.GetEndpoint("http"))
56+
.WithOtlpExporter()
57+
.WithEnvironment("BROWSER", "none");
58+
}
59+
60+
// We use YARP as the static file server and reverse proxy. This is used to test
61+
// the application in a containerized environment.
62+
builder.AddYarp("chatui")
63+
.WithStaticFiles()
5464
.WithExternalHttpEndpoints()
55-
.WithOtlpExporter()
56-
.WithEnvironment("BROWSER", "none");
65+
.WithDockerfile("../chatui")
66+
.WithConfiguration(c =>
67+
{
68+
c.AddRoute("/api/{**catch-all}", chatapi.GetEndpoint("http"));
69+
})
70+
.WithExplicitStart();
5771

5872
builder.Build().Run();
5973

AIChat.AppHost/ProxyExtensions.cs

Lines changed: 0 additions & 25 deletions
This file was deleted.

AIChat.AppHost/docker-infra/docker-compose.yaml

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ services:
1010
- "aspire"
1111
restart: "always"
1212
pg:
13-
image: "docker.io/library/postgres:17.5"
13+
image: "docker.io/library/postgres:17.6"
1414
environment:
1515
POSTGRES_HOST_AUTH_METHOD: "scram-sha-256"
1616
POSTGRES_INITDB_ARGS: "--auth-host=scram-sha-256 --auth-local=scram-sha-256"
@@ -26,7 +26,7 @@ services:
2626
networks:
2727
- "aspire"
2828
cache:
29-
image: "docker.io/library/redis:7.4"
29+
image: "docker.io/library/redis:8.2"
3030
command:
3131
- "-c"
3232
- "redis-server --requirepass $$REDIS_PASSWORD"
@@ -46,7 +46,7 @@ services:
4646
OTEL_DOTNET_EXPERIMENTAL_OTLP_RETRY: "in_memory"
4747
ASPNETCORE_FORWARDEDHEADERS_ENABLED: "true"
4848
HTTP_PORTS: "${CHATAPI_PORT}"
49-
ConnectionStrings__llm: "AccessKey=${LLM_OPENAI_API_KEY};Model=gpt-4.1;Endpoint=https://api.openai.com/v1;Provider=OpenAI"
49+
ConnectionStrings__llm: "Endpoint=https://api.openai.com/v1;Key=${OAI_OPENAI_APIKEY};Model=gpt-4.1;Provider=OpenAI"
5050
ConnectionStrings__conversations: "Host=pg;Port=5432;Username=postgres;Password=${PG_PASSWORD};Database=conversations"
5151
ConnectionStrings__cache: "cache:6379,password=${CACHE_PASSWORD}"
5252
OTEL_EXPORTER_OTLP_ENDPOINT: "http://env-dashboard:18889"
@@ -63,17 +63,22 @@ services:
6363
- "aspire"
6464
chatui:
6565
image: "${CHATUI_IMAGE}"
66+
command:
67+
- "/app/yarp.dll"
68+
entrypoint:
69+
- "dotnet"
6670
environment:
67-
NODE_ENV: "production"
68-
PORT: "80"
69-
BACKEND_URL: "chatapi:${CHATAPI_PORT}"
70-
SPAN: "chatui"
71-
BROWSER: "none"
71+
ASPNETCORE_ENVIRONMENT: "Production"
72+
YARP_ENABLE_STATIC_FILES: "true"
73+
REVERSEPROXY__ROUTES__route0__MATCH__PATH: "/api/{**catch-all}"
74+
REVERSEPROXY__ROUTES__route0__CLUSTERID: "cluster_chatapi"
75+
REVERSEPROXY__CLUSTERS__cluster_chatapi__DESTINATIONS__destination1__ADDRESS: "http://_http.chatapi"
76+
services__chatapi__http__0: "http://chatapi:${CHATAPI_PORT}"
7277
OTEL_EXPORTER_OTLP_ENDPOINT: "http://env-dashboard:18889"
7378
OTEL_EXPORTER_OTLP_PROTOCOL: "grpc"
7479
OTEL_SERVICE_NAME: "chatui"
7580
ports:
76-
- "80"
81+
- "5000"
7782
networks:
7883
- "aspire"
7984
networks:

chatui/Caddyfile

Lines changed: 0 additions & 41 deletions
This file was deleted.

chatui/Dockerfile

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,11 @@
1-
# Build Stage: Build the React app
1+
# Stage 1: Build React app
22
FROM node:22 AS builder
33
WORKDIR /app
4-
COPY package.json package-lock.json ./
5-
RUN npm install
64
COPY . .
5+
RUN npm install
76
RUN npm run build
87

9-
# Production Stage: Serve the app with Caddy
10-
FROM caddy:2.9-alpine
11-
WORKDIR /usr/share/caddy
12-
13-
# Copy built static files including index.html, etc.
14-
COPY --from=builder /app/build/ .
15-
16-
# Copy the Caddyfile with reverse proxy config
17-
COPY Caddyfile /etc/caddy/Caddyfile
18-
19-
EXPOSE 80
20-
21-
# Run Caddy
22-
CMD ["caddy", "run", "--config", "/etc/caddy/Caddyfile", "--adapter", "caddyfile"]
8+
# Stage 2: Copy static files to YARP container
9+
FROM mcr.microsoft.com/dotnet/nightly/yarp:2.3.0-preview.4 AS yarp
10+
WORKDIR /app
11+
COPY --from=builder /app/build ./wwwroot

0 commit comments

Comments
 (0)