Skip to content
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
58 changes: 58 additions & 0 deletions DevOidcToolkit.Documentation/docs/health-checks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Health Checks

Dev OIDC Toolkit exposes health check endpoints that can be used by container orchestrators (such as Docker, Kubernetes,
or Docker Compose) to determine when the service is live and ready to accept traffic.

## Endpoints

| Endpoint | Description |
|---|---|
| `GET /healthz/live` | Liveness probe — returns `200 Healthy` when the application process is running. |
| `GET /healthz/ready` | Readiness probe — returns `200 Healthy` when the application is ready to serve requests, including verifying database connectivity when SQLite is configured. |

Both endpoints return a plain-text body of `Healthy` and an HTTP `200` status code when healthy, or `503 Unhealthy`
when a check fails.

### Readiness and database checks

When the application is configured to use a SQLite database (via `Database.SqliteFile`), the `/healthz/ready` endpoint
also verifies that the database is reachable. The `/healthz/live` endpoint never checks the database — it only
reports whether the process itself is running.

When using the default in-memory database, both endpoints behave identically.

## Docker HEALTHCHECK

The official Docker image already includes a `HEALTHCHECK` instruction that uses `curl` to poll `/healthz/live` every
30 seconds:

```dockerfile
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:8080/healthz/live || exit 1
```

No extra configuration is required to enable this — it works out of the box.

## Docker Compose example

You can use the readiness endpoint to make dependent services wait until Dev OIDC Toolkit is healthy before starting:

```yaml
services:
dev-oidc-toolkit:
image: ghcr.io/businesssimulations/dev-oidc-toolkit
ports:
- "8080:8080"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/healthz/ready"]
interval: 10s
timeout: 3s
retries: 5
start_period: 5s

my-app:
image: my-app
depends_on:
dev-oidc-toolkit:
condition: service_healthy
```
1 change: 1 addition & 0 deletions DevOidcToolkit.Documentation/docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ OpenID Connect identity provider for development and testing.
- [Tutorial](tutorial.md)
- [Configuration](configuration.md)
- [Runtime Management](runtime-management.md)
- [Health Checks](health-checks.md)
1 change: 1 addition & 0 deletions DevOidcToolkit/DevOidcToolkit.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="10.0.5" />
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="10.0.2" />
<PackageReference Include="OpenIddict.AspNetCore" Version="7.2.0" />
<PackageReference Include="OpenIddict.EntityFrameworkCore" Version="7.2.0" />
Expand Down
13 changes: 13 additions & 0 deletions DevOidcToolkit/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,13 @@
.DisableTransportSecurityRequirement();
});

var healthChecksBuilder = builder.Services.AddHealthChecks();

if (config.Database.SqliteFile is not null)
{
healthChecksBuilder.AddDbContextCheck<DevOidcToolkitContext>(tags: ["ready"]);
}

builder.Services.AddControllersWithViews().AddRazorRuntimeCompilation();
builder.Services.AddRazorPages().AddRazorRuntimeCompilation();

Expand Down Expand Up @@ -298,6 +305,12 @@

}

app.MapHealthChecks("/healthz/live", new Microsoft.AspNetCore.Diagnostics.HealthChecks.HealthCheckOptions
{
Predicate = check => !check.Tags.Contains("ready")
});
app.MapHealthChecks("/healthz/ready");

app.MapControllers();
app.MapRazorPages();

Expand Down
5 changes: 5 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,13 @@ FROM mcr.microsoft.com/dotnet/aspnet:10.0
WORKDIR /app
COPY --from=build /app/dist .

RUN apt-get update && apt-get install -y --no-install-recommends curl && rm -rf /var/lib/apt/lists/*

ENTRYPOINT ["dotnet", "dev-oidc-toolkit.dll"]

ENV DevOidcToolkit__Port=8080
ENV DevOidcToolkit__Address=0.0.0.0
EXPOSE 8080

HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:${DevOidcToolkit__Port}/healthz/live || exit 1
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ identity provider such as Keycloak as part of your testing pipeline.
- List configured clients
- Different levels of logging to help with debugging
- Built in documentation
- Health check endpoints (`/healthz/live` and `/healthz/ready`) for container orchestration
- Distributed as a self-contained binaries
- Distributed as Docker images

Expand Down
Loading