Hosting Guide
CritterWatch supports several hosting topologies. Choose based on your team's needs and infrastructure constraints.
Standalone Server (Recommended)
The most common production topology. CritterWatch runs as its own dedicated web application, separate from the services it monitors.
Advantages:
- Clear separation of concerns
- Isolated failure domain — if CritterWatch crashes, monitored services are unaffected
- Independently scalable and deployable
- Simpler security boundary
// Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.AddCritterWatch(
builder.Configuration.GetConnectionString("critterwatch")!,
opts =>
{
opts.UseRabbitMq(new Uri(builder.Configuration.GetConnectionString("rabbitmq")!))
.AutoProvision();
opts.ListenToRabbitQueue("critterwatch").Sequential();
});
var app = builder.Build();
app.UseCritterWatch();
app.Run();The embedded Vue SPA is served from the server's root path. Navigate to https://your-critterwatch-host/ to open the console.
Embedded in an Existing Application
CritterWatch can be embedded as middleware in an existing ASP.NET Core application. Useful when you want the monitoring console co-located with another admin tool.
// CritterWatch can be embedded directly in an existing ASP.NET Core application
var builder = WebApplication.CreateBuilder(args);
// Add your application's existing services
builder.Services.AddControllers();
// Add CritterWatch on top
builder.AddCritterWatch(
builder.Configuration.GetConnectionString("critterwatch")!,
opts =>
{
opts.UseRabbitMq(new Uri("amqp://localhost")).AutoProvision();
opts.ListenToRabbitQueue("critterwatch").Sequential();
});
var app = builder.Build();
app.MapControllers();
// Mount CritterWatch with a custom SignalR hub path
app.UseCritterWatch(signalRRoute: "/critterwatch/api/messages");
app.Run();Route Conflicts
When embedding CritterWatch in an existing application, ensure there are no route conflicts with your application's existing endpoints. CritterWatch registers routes under /api/critterwatch/* by default.
.NET Aspire Orchestration
For development and staging environments, .NET Aspire provides the best developer experience. It automatically manages service connections, environment variables, and the Vue dev server.
// In your AppHost Program.cs
var builder = DistributedApplication.CreateBuilder(args);
var postgres = builder.AddPostgres("postgres");
var rabbit = builder.AddRabbitMQ("rabbit");
// Your monitored services
var tripService = builder.AddProject<Projects.TripService>("trip-service")
.WithReference(postgres)
.WithReference(rabbit);
// CritterWatch server
var critterwatch = builder.AddProject<Projects.CritterWatchBff>("critterwatch")
.WithReference(postgres)
.WithReference(rabbit)
.WaitFor(tripService);
builder.Build().Run();During Aspire-hosted development, the Vue frontend runs as a separate Vite dev server (port 5173) that proxies to the CritterWatch backend. The embedded SPA middleware is not used in this mode.
Building the NuGet Package with Embedded Frontend
When publishing the CritterWatch NuGet package (or distributing as a private package), build with the EmbedFrontend property to bundle the Vue SPA:
dotnet pack src/CritterWatch.Services -p:EmbedFrontend=trueOr for a regular build:
dotnet build src/CritterWatch.Services -p:EmbedFrontend=trueWithout -p:EmbedFrontend=true, the frontend is not embedded — it must be served by a separate dev server (the Aspire configuration handles this automatically).
Production Considerations
HTTPS
Always serve CritterWatch over HTTPS in production. CritterWatch gives operators significant control over your services — plaintext communication is a security risk.
// Enforce HTTPS redirection
app.UseHttpsRedirection();
app.UseHsts();
app.UseCritterWatch();Authentication
CritterWatch does not ship with built-in authentication. Add ASP.NET Core authentication middleware before UseCritterWatch():
app.UseAuthentication();
app.UseAuthorization();
// Protect the SignalR hub
app.MapHub<CommunicationHub>("/api/messages")
.RequireAuthorization();
app.UseCritterWatch();Network Isolation
In production, CritterWatch should not be publicly accessible. Place it behind a VPN, internal load balancer, or IP allowlist. The transport (RabbitMQ) connecting CritterWatch to your services should also be on an internal network.
Scaling
CritterWatch is designed as a single-instance application. The Marten event store and SignalR hub are not currently configured for multi-instance deployment. If high availability is required, use a process manager (systemd, Kubernetes) to restart CritterWatch automatically on failure.
Health Checks
Register ASP.NET Core health checks to monitor CritterWatch itself:
builder.Services.AddHealthChecks()
.AddNpgSql(connectionString, name: "critterwatch-db");
app.MapHealthChecks("/health");