Skip to content

Commit 6e3a0cd

Browse files
Add container-ready API host (Elastic.Documentation.Api.App) (#2690)
* Add codex-api deploy workflow * Add container-ready API host project (Elastic.Documentation.Api.App) New standalone ASP.NET Core host for the Docs API, designed for container-based deployments (ECS, EKS, Kubernetes, etc.). Co-authored-by: Cursor <cursoragent@cursor.com> * Remove codex related stuff again * Change assembly name to docs-builder-api --------- Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent c9bf4db commit 6e3a0cd

8 files changed

Lines changed: 190 additions & 0 deletions

File tree

build/Targets.fs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ let private publishContainers _ =
133133
exec { run "dotnet" (args @ registry) }
134134
createImage "src/tooling/docs-builder/docs-builder.csproj" "docs-builder"
135135
createImage "src/api/Elastic.Documentation.Mcp.Remote/Elastic.Documentation.Mcp.Remote.csproj" "docs-builder-mcp"
136+
createImage "src/api/Elastic.Documentation.Api.App/Elastic.Documentation.Api.App.csproj" "docs-builder-api"
136137

137138
let private runTests (testSuite: TestSuite) _ =
138139
let testFilter =
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
FROM public.ecr.aws/amazonlinux/amazonlinux:2023 AS base
2+
3+
ARG TARGETARCH
4+
ARG TARGETOS
5+
6+
WORKDIR /app
7+
8+
RUN rpm --import https://packages.microsoft.com/keys/microsoft.asc
9+
10+
RUN dnf update -y
11+
RUN dnf install -y npm
12+
RUN dnf install -y git
13+
RUN dnf install -y clang
14+
15+
## temporary see: https://github.com/amazonlinux/amazon-linux-2023/issues/1025
16+
RUN dnf install -y tar
17+
RUN dnf install -y findutils
18+
RUN curl -L https://dot.net/v1/dotnet-install.sh -o dotnet-install.sh
19+
RUN chmod +x ./dotnet-install.sh
20+
RUN ./dotnet-install.sh
21+
ENV PATH="$PATH:/root/.dotnet"
22+
ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1
23+
# /end temporary
24+
25+
COPY . .
26+
27+
ENV DOTNET_NOLOGO=true \
28+
DOTNET_CLI_TELEMETRY_OPTOUT=true
29+
30+
RUN arch=$TARGETARCH \
31+
&& if [ "$arch" = "amd64" ]; then arch="x64"; fi \
32+
&& echo $TARGETOS-$arch > /tmp/rid
33+
34+
RUN dotnet publish src/api/Elastic.Documentation.Api.App -r linux-x64 -c Release
35+
36+
# Runtime stage
37+
FROM public.ecr.aws/amazonlinux/amazonlinux:2023-minimal AS runtime
38+
WORKDIR /app
39+
COPY --from=base /app/.artifacts/publish/Elastic.Documentation.Api.App/release_linux-x64/ /app/
40+
RUN chmod +x /app/docs-builder-api
41+
EXPOSE 8080
42+
ENV ASPNETCORE_URLS=http://+:8080
43+
ENTRYPOINT ["/app/docs-builder-api"]
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<Project Sdk="Microsoft.NET.Sdk.Web">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net10.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
<InvariantGlobalization>true</InvariantGlobalization>
9+
10+
<AssemblyName>docs-builder-api</AssemblyName>
11+
12+
<IsPublishable>true</IsPublishable>
13+
<PublishAot>true</PublishAot>
14+
<PublishTrimmed>true</PublishTrimmed>
15+
<EnableSdkContainerSupport>true</EnableSdkContainerSupport>
16+
<TrimmerSingleWarn>false</TrimmerSingleWarn>
17+
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
18+
19+
<RootNamespace>Elastic.Documentation.Api.App</RootNamespace>
20+
</PropertyGroup>
21+
22+
<ItemGroup>
23+
<ProjectReference Include="..\..\Elastic.Documentation.ServiceDefaults\Elastic.Documentation.ServiceDefaults.csproj" />
24+
<ProjectReference Include="..\Elastic.Documentation.Api.Core\Elastic.Documentation.Api.Core.csproj"/>
25+
<ProjectReference Include="..\Elastic.Documentation.Api.Infrastructure\Elastic.Documentation.Api.Infrastructure.csproj"/>
26+
</ItemGroup>
27+
28+
<ItemGroup>
29+
<PackageReference Include="Elastic.OpenTelemetry" />
30+
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" />
31+
</ItemGroup>
32+
33+
</Project>
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// Licensed to Elasticsearch B.V under one or more agreements.
2+
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
3+
// See the LICENSE file in the project root for more information
4+
5+
using Elastic.Documentation.Api.Infrastructure;
6+
using Elastic.Documentation.Api.Infrastructure.OpenTelemetry;
7+
using Elastic.Documentation.Configuration.Assembler;
8+
using Elastic.Documentation.ServiceDefaults;
9+
10+
try
11+
{
12+
var builder = WebApplication.CreateSlimBuilder(args);
13+
_ = builder.AddDocumentationServiceDefaults(ref args, (s, p) =>
14+
{
15+
_ = s.AddSingleton(AssemblyConfiguration.Create(p));
16+
});
17+
18+
_ = builder.AddDocsApiOpenTelemetry();
19+
20+
// Configure Kestrel to listen on port 8080 (standard container port)
21+
_ = builder.WebHost.ConfigureKestrel(serverOptions =>
22+
{
23+
serverOptions.ListenAnyIP(8080);
24+
});
25+
26+
var environment = Environment.GetEnvironmentVariable("ENVIRONMENT");
27+
Console.WriteLine($"Docs Environment: {environment}");
28+
29+
builder.Services.AddElasticDocsApiUsecases(environment);
30+
var app = builder.Build();
31+
32+
if (app.Environment.IsDevelopment())
33+
_ = app.UseDeveloperExceptionPage();
34+
35+
// Health check endpoint for load balancer target groups
36+
_ = app.MapGet("/health", () => Results.Ok(new { status = "healthy" }));
37+
38+
var v1 = app.MapGroup("/docs/_api/v1");
39+
40+
var mapOtlpEndpoints = !string.IsNullOrWhiteSpace(builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"]);
41+
v1.MapElasticDocsApiEndpoints(mapOtlpEndpoints);
42+
Console.WriteLine("API endpoints mapped");
43+
44+
Console.WriteLine("Application startup completed successfully");
45+
app.Run();
46+
}
47+
catch (Exception ex)
48+
{
49+
Console.WriteLine($"FATAL ERROR during startup: {ex}");
50+
Console.WriteLine($"Exception type: {ex.GetType().Name}");
51+
Console.WriteLine($"Stack trace: {ex.StackTrace}");
52+
throw;
53+
}
54+
55+
// Make the Program class accessible for integration testing
56+
#pragma warning disable ASP0027
57+
public partial class Program { }
58+
#pragma warning restore ASP0027
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"$schema": "https://json.schemastore.org/launchsettings.json",
3+
"profiles": {
4+
"http": {
5+
"commandName": "Project",
6+
"dotnetRunMessages": true,
7+
"launchBrowser": true,
8+
"applicationUrl": "http://localhost:5020",
9+
"environmentVariables": {
10+
"ASPNETCORE_ENVIRONMENT": "Development"
11+
}
12+
},
13+
"https": {
14+
"commandName": "Project",
15+
"dotnetRunMessages": true,
16+
"launchBrowser": true,
17+
"applicationUrl": "https://localhost:7192;http://localhost:5020",
18+
"environmentVariables": {
19+
"ASPNETCORE_ENVIRONMENT": "Development"
20+
}
21+
}
22+
}
23+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Information",
5+
"Microsoft.AspNetCore": "Warning"
6+
}
7+
}
8+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Debug",
5+
"Microsoft.AspNetCore": "Warning"
6+
}
7+
},
8+
"Elastic": {
9+
"OpenTelemetry": {
10+
"LogLevel": "Debug",
11+
"LogTargets": "stdout",
12+
"SkipInstrumentationAssemblyScanning": true
13+
}
14+
}
15+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Information",
5+
"Microsoft.AspNetCore": "Warning"
6+
}
7+
},
8+
"AllowedHosts": "*"
9+
}

0 commit comments

Comments
 (0)