Web App Starter Guide

Build a full-stack web application with OAuth authentication, Tuxedo ORM, Bowtie schema sync, and responsive UI using Noundry libraries. Get from zero to production in minutes.

Quick Start

# Clone the starter template
$ git clone https://github.com/noundry/NoundryStarter MyWebApp

# Navigate to the web project
$ cd MyWebApp/src/NoundryStarter.Web

# Restore and run
$ dotnet restore
$ dotnet run

Your web app will be available at https://localhost:5001.

What's Included

Authentication & Authorization

  • Noundry.Authnz OAuth 2.0
  • Role-based access control
  • OAuth providers (Google, GitHub, Microsoft)
  • Login, register, and profile pages

Database

  • Noundry.Tuxedo ORM (Dapper-based)
  • Bowtie attribute-based schema sync
  • PostgreSQL support
  • Cufflink seed data and sample entities

UI Components

  • Noundry.UI component library
  • Tailwind CSS integration
  • Responsive design
  • Dark mode support

Developer Experience

  • Hot reload support
  • Structured logging configured
  • Docker support
  • Environment-based config

Step-by-Step Guide

Step 1: Clone the Starter

Clone the Noundry Web App Starter from GitHub. All Noundry packages come pre-configured.

$ git clone https://github.com/noundry/NoundryStarter MyWebApp

Step 2: Restore Dependencies

Navigate to the web project and restore NuGet packages.

$ cd MyWebApp/src/NoundryStarter.Web
$ dotnet restore

Step 3: Configure Database

Set your PostgreSQL connection string in .env. Bowtie automatically syncs your schema on startup.

# .env file
DATABASE_CONNECTION_STRING="Host=localhost;Database=MyWebAppDb;Username=postgres;Password=secret"

Step 4: Configure Authentication

Set up OAuth providers by adding your client ID and secret.

// appsettings.json
{
 "Authentication": {
 "Google": {
 "ClientId": "your-client-id",
 "ClientSecret": "your-client-secret"
 }
 }
}

Step 5: Run and Develop

Start the application with hot reload for rapid development.

$ dotnet watch run

Project Structure

MyWebApp/
 Pages/ # Razor Pages
 Account/ # Login, Register, Profile
 Admin/ # Admin dashboard
 Index.cshtml # Home page
 Models/ # Entity models
 Data/ # Tuxedo repositories, queries
 Services/ # Business logic
 wwwroot/ # Static assets, CSS
 Program.cs # Application entry point
 appsettings.json # Configuration
 Dockerfile # Container support

Using Noundry Components

The template comes pre-configured with Noundry component libraries. Here are examples of using them in your Razor Pages.

Program.cs Setup

var builder = WebApplication.CreateBuilder(args);

// Add Noundry services
builder.Services.AddAuthnz(builder.Configuration);
builder.Services.AddTuxedo(builder.Configuration
 .GetConnectionString("DefaultConnection"));

// Add Razor Pages with Noundry tag helpers
builder.Services.AddRazorPages();

var app = builder.Build();

app.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages();

app.Run();

Database Model with Bowtie Attributes

// Models/Customer.cs
[Table("customers")]
public class Customer
{
 [ExplicitKey]
 [DefaultValue("gen_random_uuid()")]
 [Column("id", "uuid")]
 public Guid Id { get; set; }

 [Column("first_name", "varchar(100)")]
 public required string FirstName { get; set; }

 [Column("email", "varchar(255)")]
 [Index(IsUnique = true)]
 public required string Email { get; set; }

 [Column("is_active", "boolean")]
 [DefaultValue("true")]
 public bool IsActive { get; set; } = true;
}

Environment Configuration with DotEnvX

# .env file (development)
DATABASE_CONNECTION_STRING="Host=localhost;Database=MyWebAppDb;Username=postgres;Password=secret"
GOOGLE_CLIENT_ID="your-client-id"
GOOGLE_CLIENT_SECRET="your-client-secret"
GITHUB_CLIENT_ID="your-github-client-id"
GITHUB_CLIENT_SECRET="your-github-client-secret"

Adding New Pages

The template uses Razor Pages with Tailwind CSS. Add new pages to the Pages directory.

// Pages/Customers/Index.cshtml.cs
public class IndexModel : PageModel
{
 private readonly IDbConnection _db;

 public IndexModel(IDbConnection db) => _db = db;

 public IReadOnlyList<Customer> Customers { get; set; } = [];

 public async Task OnGetAsync()
 {
 Customers = (await _db.GetAllAsync<Customer>())
 .ToList();
 }
}

Perfect For

  • SaaS applications
  • Internal tools and dashboards
  • Customer-facing web portals
  • E-commerce platforms
  • Content management systems

Noundry Packages Included

<!-- Key packages in the template -->
<PackageReference Include="Noundry.UI" />
<PackageReference Include="Noundry.Authnz" />
<PackageReference Include="Noundry.Tuxedo" />
<PackageReference Include="Noundry.Tailbreeze" />
<PackageReference Include="Noundry.TagHelpers" />
<PackageReference Include="Noundry.DotEnvX" />

Noundry.UI

Pre-built Razor components for forms, tables, modals, alerts, and more.

Noundry.Authnz

OAuth 2.0 authentication with social login (Google, GitHub, Microsoft) and role management.

Noundry.Tuxedo

Lightweight ORM with Dapper-compatible API for database access.

Noundry.Tailbreeze

Tailwind CSS integration with dark mode and build pipeline.

Noundry.TagHelpers

Custom tag helpers for Razor Pages and MVC views.

Noundry.DotEnvX

Environment variable management with encryption support.

Customization Tips

Database Configuration

The template uses PostgreSQL with Noundry.Tuxedo ORM. Bowtie automatically syncs your schema from model attributes on startup — no manual migration commands needed.

Add OAuth Providers

The template supports Google and GitHub by default. Add Microsoft, Facebook, or custom OpenID Connect providers in Program.cs.

Customize the UI Theme

Modify tailwind.config.js to change colors, fonts, and breakpoints. Noundry.Tailbreeze handles the CSS build pipeline.

Add Background Services

Register hosted services in Program.cs for background processing, scheduled tasks, or message queue consumers.

Deployment

Use Noundry Spinup to provision a security-hardened VM on any cloud, then deploy your app with Docker.

1. Provision a VM with Spinup

# Install Spinup
$ dotnet tool install -g Noundry.Spinup

# Set your cloud credentials (example: AWS)
$ export AWS_ACCESS_KEY_ID=your-key
$ export AWS_SECRET_ACCESS_KEY=your-secret

# Provision a VM (AWS, Azure, GCP, or DigitalOcean)
$ spinup provision --cloud aws --region us-east-1 --resource vm --name mywebapp -y

# Or use DigitalOcean
$ export DIGITALOCEAN_TOKEN=your-api-token
$ spinup provision --cloud digitalocean --region nyc3 --resource vm --name mywebapp -y

Spinup automatically hardens the VM with UFW firewall, fail2ban, SSH key-only auth, and your IP whitelisted.

2. Build and Deploy

# Build for production
$ dotnet publish -c Release -o ./publish

# Or use Docker
$ docker build -t mywebapp .

3. SSH and Run

# SSH into your VM (key auto-generated by Spinup)
$ ssh -i ~/.spinup/workspaces/mywebapp/mywebapp_ssh_key.pem ubuntu@<public-ip>

# Deploy with Docker on the VM
$ docker run -d -p 80:80 --env-file .env mywebapp

Related Resources