diff --git a/DevOidcToolkit.Documentation/docs/health-checks.md b/DevOidcToolkit.Documentation/docs/health-checks.md
new file mode 100644
index 0000000..3d4745e
--- /dev/null
+++ b/DevOidcToolkit.Documentation/docs/health-checks.md
@@ -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
+```
diff --git a/DevOidcToolkit.Documentation/docs/index.md b/DevOidcToolkit.Documentation/docs/index.md
index 5a7f7e4..cf46416 100644
--- a/DevOidcToolkit.Documentation/docs/index.md
+++ b/DevOidcToolkit.Documentation/docs/index.md
@@ -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)
diff --git a/DevOidcToolkit/DevOidcToolkit.csproj b/DevOidcToolkit/DevOidcToolkit.csproj
index 64d5b58..8e0bc80 100644
--- a/DevOidcToolkit/DevOidcToolkit.csproj
+++ b/DevOidcToolkit/DevOidcToolkit.csproj
@@ -24,6 +24,7 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
all
+
diff --git a/DevOidcToolkit/Program.cs b/DevOidcToolkit/Program.cs
index bfd46b9..9a55f05 100644
--- a/DevOidcToolkit/Program.cs
+++ b/DevOidcToolkit/Program.cs
@@ -115,6 +115,13 @@
.DisableTransportSecurityRequirement();
});
+var healthChecksBuilder = builder.Services.AddHealthChecks();
+
+if (config.Database.SqliteFile is not null)
+{
+ healthChecksBuilder.AddDbContextCheck(tags: ["ready"]);
+}
+
builder.Services.AddControllersWithViews().AddRazorRuntimeCompilation();
builder.Services.AddRazorPages().AddRazorRuntimeCompilation();
@@ -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();
diff --git a/Dockerfile b/Dockerfile
index a420df8..29854bd 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -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
diff --git a/README.md b/README.md
index eaf93b3..0326ff0 100644
--- a/README.md
+++ b/README.md
@@ -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