Skip to content

Hosting Guide

CritterWatch supports several hosting topologies. Choose based on your team's needs and infrastructure constraints.

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
csharp
// 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.

csharp
// 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.

cs
// 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();

snippet source | anchor

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:

bash
dotnet pack src/CritterWatch.Services -p:EmbedFrontend=true

Or for a regular build:

bash
dotnet build src/CritterWatch.Services -p:EmbedFrontend=true

Without -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.

csharp
// 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():

csharp
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:

csharp
builder.Services.AddHealthChecks()
    .AddNpgSql(connectionString, name: "critterwatch-db");

app.MapHealthChecks("/health");

Released under the MIT License.