A production-ready microservices platform built with .NET 9, featuring comprehensive observability, security, and data persistence.
- Gateway API - API gateway with JWT authentication and CORS
- Customer API - Customer management with RavenDB and event publishing
- Telemetry API - IoT data ingestion via MQTT with TimescaleDB storage
- Workflow API - Workflow orchestration service
- Files API - Blob storage and Parquet file export
- RavenDB - Document database
- TimescaleDB - Time-series PostgreSQL with 90-day retention
- RabbitMQ - Message broker for event-driven architecture
- MQTT (Mosquitto) - IoT device communication
- Azurite - Local Azure Blob Storage emulator
- Prometheus - Metrics collection and alerting
- Grafana - Metrics visualization and dashboards
- OpenTelemetry instrumentation on all APIs
- Prometheus metrics at
/metricsendpoints - Distributed tracing for HTTP requests
- Grafana dashboards (port 3000, admin/admin)
- JWT Bearer authentication
- Configurable validation (disabled for local dev)
- CORS enabled on Gateway
- Swagger UI on all APIs
- RavenDB database:
opus - TimescaleDB hypertable:
telemetry(90-day retention policy) - Azurite containers:
telemetry,observability-test
- Docker Desktop
- .NET 9.0 SDK
- Azure CLI (for blob operations)
- Start all services:
cd deploy/compose
docker compose up -d- Run automated tests:
./scripts/test-all.sh- Verify services manually:
curl http://localhost:8088/health # Gateway
curl http://localhost:8088/metrics # Prometheus metrics- Access UIs:
- Gateway Swagger: http://localhost:8088/swagger
- Files Swagger: http://localhost:8089/swagger
- RavenDB Studio: http://localhost:8080
- Prometheus: http://localhost:9090
- Grafana: http://localhost:3000 (admin/admin)
- RabbitMQ Management: http://localhost:15672 (guest/guest)
Run individual services with hot reload:
cd src/services/gateway/Opus.Gateway.Api
dotnet watch runThe repository includes a GitHub Actions workflow that automatically builds and pushes Docker images to GitHub Container Registry.
No additional secrets required! The workflow uses GITHUB_TOKEN which is automatically provided by GitHub Actions.
- On Push to Main: Builds all 5 service images and pushes to GHCR
- On Pull Request: Builds images and runs tests (no push)
- Image Tagging:
latest- Latest main branchmain-<sha>- Specific commit on mainpr-<number>- Pull request builds
After the workflow runs, images will be available at:
ghcr.io/<your-username>/opus-stack-starter-full/gateway:latest
ghcr.io/<your-username>/opus-stack-starter-full/customer:latest
ghcr.io/<your-username>/opus-stack-starter-full/telemetry:latest
ghcr.io/<your-username>/opus-stack-starter-full/workflow:latest
ghcr.io/<your-username>/opus-stack-starter-full/files:latest
By default, GHCR images are private. To make them public:
- Go to your GitHub profile → Packages
- Click on each package (opus-stack-starter-full/gateway, etc.)
- Package Settings → Change visibility → Public
GET /health- Health checkGET /gateway/ping- Simple pingGET /metrics- Prometheus metrics
GET /customers/{id}- Get customer by IDPOST /customers- Create customer (publishes event to RabbitMQ)
GET /metrics/latest/{deviceId}- Get latest 50 metrics for device- Subscribes to MQTT topic:
device/+/+
POST /workflow/start/{type}- Start workflow instance
POST /export/parquet/{container}/{name}- Generate and upload parquet file
All environment variables are in deploy/compose/.env:
- JWT: Validation disabled for local dev
- Databases: Connection strings for RavenDB, TimescaleDB
- Message Brokers: RabbitMQ, MQTT endpoints
- Storage: Azurite blob storage configuration
Build all services:
cd src
dotnet buildBuild individual service:
cd src/services/gateway/Opus.Gateway.Api
dotnet buildRun parquet export:
curl -X POST http://localhost:8089/export/parquet/test-metrics/run2Download blob:
az storage blob download \
-c telemetry \
-n run1 \
-f run1.parquet \
--connection-string "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;"opus-stack-starter-full/
├── src/
│ ├── building-blocks/
│ │ ├── Opus.Messaging/ # RabbitMQ messaging
│ │ ├── Opus.Security/ # JWT authentication
│ │ └── Opus.Storage/ # Blob storage + Parquet
│ └── services/
│ ├── gateway/Opus.Gateway.Api/
│ ├── customer/Opus.Customer.Api/
│ ├── telemetry/Opus.Telemetry.Api/
│ ├── workflow/Opus.Workflow.Api/
│ └── files/Opus.Files.Api/
├── deploy/
│ └── compose/
│ ├── docker-compose.yml
│ ├── prometheus.yml
│ └── .env
└── .github/
└── workflows/
└── ci-cd.yml
- .NET 9.0 - Modern C# with minimal APIs
- Docker Compose - Local orchestration
- OpenTelemetry - Observability standard
- RavenDB 6.0 - NoSQL document database
- TimescaleDB 2.14 - Time-series PostgreSQL
- RabbitMQ 3 - AMQP message broker
- Mosquitto 2 - MQTT broker
- Prometheus - Metrics collection
- Grafana - Visualization
- GitHub Actions - CI/CD automation
MIT