Music Albums REST API in .NET 10 / C#, with Dapper and PostgreSQL. Locally orchestrated by .NET Aspire; containerized with Docker, published to the GitHub Container Registry (GHCR), and deployed to Azure Container Apps through Bicep's Infrastructure as Code (IaC) and a multi-stage Azure Pipelines CI/CD — with app and infrastructure deploys gated by manual approval; a scheduled GitHub Actions workflow prunes old GHCR images. Quality is enforced through unit and integration tests, code coverage, and SonarQube quality gates (Cloud + self-hosted Server). Development follows GitHub Flow — all changes go through PRs (direct push to main is not allowed), CI required, squash merge enforced.
This project is a monolith with a pragmatic Layered Architecture, organized by technical concerns:
MusicAlbums.Api(Presentation): MVC Controllers, auth handlers, request/response mapping, health checks, and OpenAPI / Scalar configuration.MusicAlbums.Application(Business & Data): Core business logic (Services), data access (Repositories&Database), domain models, and input validation (Validators).MusicAlbums.Contracts(HTTP Contracts): Request and Response DTOs that define the API's public interface.MusicAlbums.ServiceDefaults(Shared Infrastructure): Cross-cutting runtime concerns — OpenTelemetry instrumentation, service discovery, HTTP client resilience. Referenced by both the API and the Identity API viabuilder.AddServiceDefaults(), and runs in both local and cloud — only the telemetry exporter changes (OTLP to the Aspire dashboard locally, Azure Monitor to Application Insights in production).
One additional project handles local orchestration only:
MusicAlbums.AppHost— .NET Aspire orchestrator. Declares the local dev topology (PostgreSQL, the API, the Identity API helper) and is invoked byaspire start. Local development only — not built into the Docker image, not deployed to the cloud.
- 🔗 Music Albums API — Scalar
- 🔗 Identity API — Scalar (helper for generating JWTs)
Development environment. Demo may scale to zero when idle — the first request can take a few seconds.
The API reference UI was initially built on Swagger UI (Swashbuckle) and later migrated to Scalar on top of .NET 10's built-in
Microsoft.AspNetCore.OpenApi(OpenAPI 3.1).
- Contributing - Git workflow, branch naming, PR requirements, deploy flow
- Aspire Local Dev - database, dashboard workflow, and startup commands
- API Testing Guide - copy-pastable requests for all endpoints
- Infrastructure - Bicep modules and Azure resources
- CI/CD - Azure Pipelines, service connections, variable groups, GitHub Actions
- Integration Tests - Aspire AppHost containerized integration tests: how they work and how to run them
- Identity API - JWT token generator (helper tool)
- Standalone Postgres - legacy
docker-composePostgres, kept for non-Aspire workflows - Linux Native Docker Setup - optimized native Docker Engine setup + Portainer UI for Ubuntu/Linux developers
- Windows Container Runtime Setup - Podman Desktop or Podman CLI + Portainer UI for Windows developers
Aspire is the local orchestrator. It brings up the API, the Identity API helper, and a persistent PostgreSQL container in one go — from the CLI (aspire start) or via F5 in your IDE.
See Aspire Local Dev for first-time setup, the daily workflow, supported IDEs, and the OpenTelemetry observability setup.
| Dev | Prod |
|---|---|
![]() |
![]() |
Two Azure Pipelines drive the cloud: .azure-pipelines/main-ci-cd.yml for the main API and infrastructure, and .azure-pipelines/optional-identity-api.yml for the Identity API helper.
The Identity API is a JWT token generator for testing. It is deployed into the same resource group as the main API and shares its Container Apps Environment, but its infrastructure is managed by its own pipeline so it can be deployed/destroyed independently.
See Infrastructure for the deployment model and dev vs prod differences, and CI/CD for pipeline parameters, service connections, and variable groups.
/_health/live- liveness probe (process is up; no dependency checks)/_health/ready- readiness probe (checks database connectivity)





