Skip to content

Lux1L/evently

 
 

Repository files navigation

.NET PostgreSQL Redis RabbitMQ KeyCloak Docker OpenAPI

Evently API

Tip

📘 This project documentation is also available in Spanish.

Table of Contents

  1. Overview
  2. Technologies
  3. Features
  4. Getting Started
  5. Environment Setup
  6. Testing
  7. API Documentation

🎯 Overview

Evently API is an event management system built with .NET 10 using a Modular Monolith architecture and Event-Driven Design. It features secure OpenID Connect authentication via Keycloak, ensures reliable messaging through Outbox/Inbox patterns, and provides deep insights with OpenTelemetry. The infrastructure is fully containerized with Docker, leveraging PostgreSQL for persistence, Redis for distributed caching, and RabbitMQ as the message broker.

app diagram

This project was built following Milan Jovanović's course Modular Monolith, using the latest ASP.NET Core features and best practices.

🔧 Technologies

  • .NET 10 – Modern framework for building scalable web APIs
  • PostgreSQL – Open-source relational database
  • Redis – In-memory data store used as a distributed cache
  • KeyCloak – Open-source identity and access management
  • RabbitMQ – Reliable and mature message broker for asynchronous communication between microservices
  • MassTransit – Distributed application framework for .NET that simplifies working with message buses
  • Yarp – A toolkit for building high-performance HTTP proxy servers using .NET infrastructure
  • Dapper – High-performance micro-ORM for .NET used for efficient, raw SQL-based data access
  • Entity Framework Core – ORM for data access for .NET
  • Docker – Containerization and local infrastructure
  • Swagger (Swashbuckle) – OpenAPI interactive documentation
  • FluentValidation – Model validation framework
  • Quartz.NET – Background jobs and scheduling
  • OpenTelemetry – Distributed tracing and observability
  • Seq – Optional centralized log aggregation
  • Jaeger – Open-source, end-to-end distributed tracing system
  • xUnit – Unit testing framework
  • Testcontainers – Integration testing with containers
  • SonarAnalyzer – Static code analysis

✨ Features

⚙️ Infrastructure & Integration

  • PostgreSQL with EF Core, Dapper, and snake_case naming conventions
  • Background jobs with Quartz
  • Redis as a distributed cache and high-performance key-value store
  • RabbitMQ for asynchronous messaging and service-to-service communication
  • YARP (Yet Another Reverse Proxy) for routing and API Gateway functionality
  • Interactive API docs with Swagger

🔐 Security

  • OpenID Connect (OIDC) identity provider integration with Keycloak
  • Claims-based identity transformed from OIDC profile scopes
  • Role-based Access Control (RBAC) through custom policies and roles

📈 Observability

  • OpenTelemetry-based distributed tracing
  • Health checks support
  • Logging with Seq
  • Distributed tracing with Jaeger

🧪 Testing Stack

  • Unit testing with xUnit
  • Architectural testing with NetArchTest
  • Integration testing with Testcontainers, PostgreSQL, Redis, KeyCloak and RabbitMq

📦 Deployment & DevOps

  • Local development support with Docker Compose
  • Centralized package versioning with MSBuild
  • Dockerized production image support

🚀 Getting Started

📋 Prerequisites

Make sure you have .NET CLI installed on your system. You can check if it's available by running:

dotnet --version

This should print the installed version of the .NET CLI. If it's not installed, download it from the official .NET site.

To verify which SDK versions are installed:

dotnet --list-sdks

Important

The minimum .NET SDK version required is 10.0.0

Additionally, the project uses Docker for running supporting services (e.g., PostgreSQL, Redis, RabbitMQ, Seq). You’ll need:

  • Docker: Recommended to install Docker Desktop.
  • Docker Compose: Typically included with Docker Desktop.

To check that Docker is installed and running:

docker --version
docker compose version

If these commands fail or return errors, refer to the Docker installation guide.


📥 Installation

To get started, clone the repository and set up the environment configuration:

  1. Clone the repository:
git clone https://github.com/jaimejaramilloperez/evently.git
  1. Navigate to the project directory:
cd evently
  1. Generate and trust the HTTPS development certificate:
dotnet dev-certs https -ep ./src/Evently.Api/certificate.pfx -p Test1234!
dotnet dev-certs https --trust
  1. Copy the environment template and configure it:
cp .env.template .env
# Edit the .env file as needed

After installation, you're ready to run the app either locally or using Docker. See the Local Development or Docker sections for details.

💻 Environment SetUp

Set up your environment to run the Evently API either locally or with Docker, depending on your workflow.

Note

The configuration values shown (e.g., passwords, ports, keys, connection strings) are provided for demonstration purposes only. You are free to modify them as needed — especially for production environments.

Tip

If the APIs runs inside a Docker container, localhost refers to the container itself. In that case, replace localhost with the service name defined in your Docker network (e.g., evently.seq and evently.jaeger).


🧑‍💻 Local Development

You can run the API locally using the .NET CLI and supporting services (PostgreSQL, Redis, RabbitMQ, Seq, etc.) via Docker Compose.

Important

Sensitive values should be stored securely using user secrets

  1. Review and update the following configuration files as needed:
  1. Configure environment variables (.env file):
# postgresql
POSTGRES_DB="evently"
POSTGRES_USER="evently"
POSTGRES_PASSWORD="123456"

# redis
REDIS_PASSWORD="123456"

# pgadmin
PGADMIN_EMAIL="user@mail.com"
PGADMIN_PASSWORD="123456"

# seq
SEQ_SERVER_URL="http://evently.seq:5341"
SEQ_PASSWORD="12345678"

# keycloak
KEYCLOAK_USERNAME="admin"
KEYCLOAK_PASSWORD="admin"

# OpenTelemetry
OTEL_EXPORTER_OTLP_ENDPOINT="http://evently.jaeger:4317"
OTEL_EXPORTER_OTLP_PROTOCOL="grpc"

# RabbitMq
RABBITMQ_USER="guest"
RABBITMQ_PASSWORD="guest"
  1. Start docker services:
docker compose up -d
  1. Run the APIs and the gateway:
dotnet run --project src/Api/Evently.Api
dotnet run --project src/Api/Evently.Ticketing.Api
dotnet run --project src/Api/Evently.Gateway
# or with HTTPS
dotnet run --launch-profile https --project src/Api/Evently.Api
dotnet run --launch-profile https --project src/Api/Evently.Ticketing.Api
dotnet run --launch-profile https --project src/Api/Evently.Gateway

🐳 Docker for Development

This mode runs both the application and services in Docker containers using a development image.

  1. Review and update the .env file:
# docker
COMPOSE_PROJECT_NAME="evently"
DOCKER_REGISTRY=""
DOCKER_IMAGE_TAG="dev"
DOCKER_BUILD_TARGET="dev"

# dotnet
BUILD_CONFIGURATION="Debug"
ENVIRONMENT="Development"
HTTP_PORT="5000"
HTTPS_PORT="5001"
CERTIFICATE_PATH="/https/certificate.pfx"
CERTIFICATE_PASSWORD="Test1234!"

# evently api
DATABASE_CONNECTION_STRING="Host=evently.database;Port=5432;Database=evently;Username=evently;Password=123456;"
CACHE_CONNECTION_STRING="evently.cache:6379,password=123456"

AUTHENTICATION_AUDIENCE="account"
AUTHENTICATION_VALID_ISSUERS_1="http://evently.identity:8080/realms/evently"
AUTHENTICATION_VALID_ISSUERS_2="http://host.docker.internal:18000/realms/evently"
AUTHENTICATION_METADATA_ADDRESS="http://evently.identity:8080/realms/evently/.well-known/openid-configuration"
AUTHENTICATION_REQUIRE_HTTPS_METADATA="false"
KEYCLOAK_HEALTH_Url="http://evently.identity:9000/health"

USERS_KEYCLOAK_ADMIN_URL="http://evently.identity:8080/admin/realms/evently/"
USERS_KEYCLOAK_TOKEN_URL="http://evently.identity:8080/realms/evently/protocol/openid-connect/token"
USERS_KEYCLOAK_CONFIDENTIAL_CLIENT_ID="evently-confidential-client"
USERS_KEYCLOAK_CONFIDENTIAL_CLIENT_SECRET="eHPYDdH5j8eutm54aApbgb4khT3vQXPM"
USERS_KEYCLOAK_PUBLIC_CLIENT_ID="evently-public-client"

# evently ticketing api
TICKETING_HTTP_PORT="5100"
TICKETING_HTTPS_PORT="5101"
TICKETING_CERTIFICATE_PATH="/https/certificate.pfx"
TICKETING_CERTIFICATE_PASSWORD="Test1234!"

# Gateway
GATEWAY_HTTP_PORT="3000"
GATEWAY_HTTPS_PORT="3001"
GATEWAY_CERTIFICATE_PATH="/https/certificate.pfx"
GATEWAY_CERTIFICATE_PASSWORD="Test1234!"

# postgresql
POSTGRES_DB="evently"
POSTGRES_USER="evently"
POSTGRES_PASSWORD="123456"

# redis
REDIS_PASSWORD="123456"

# pgadmin
PGADMIN_EMAIL="user@mail.com"
PGADMIN_PASSWORD="123456"

# seq
SEQ_SERVER_URL="http://evently.seq:5341"
SEQ_PASSWORD="12345678"

# keycloak
KEYCLOAK_USERNAME="admin"
KEYCLOAK_PASSWORD="admin"

# OpenTelemetry
OTEL_EXPORTER_OTLP_ENDPOINT="http://evently.jaeger:4317"
OTEL_EXPORTER_OTLP_PROTOCOL="grpc"

# RabbitMq
RABBITMQ_USER="guest"
RABBITMQ_PASSWORD="guest"
  1. Start the containers:
docker compose -f ./docker-compose-debug.yml up -d

🐞 Debugging in container

Important

Debugging inside containers requires the vsdbg debugger. If it’s not already installed, refer to the official setup guide for instructions on how to install it manually.

If you're using Visual Studio Code, you can debug the application running inside a container with the Containers .NET Attach option. This option attaches the debugger to a running container — no extra configuration required beyond starting the containers as shown above in the step 2 of docker for development.


📦 Docker for Production

To build and run the API in production mode using a minimal Docker image:

  1. Update the .env file with the required following values:
DOCKER_BUILD_TARGET="prod"
BUILD_CONFIGURATION="Release"
ENVIRONMENT="Production"
  1. Run the docker-compose-debug.yml file with docker again or build the images manually
docker buildx build \
  --platform linux/amd64 \
  -f src/Api/Evently.Api/Dockerfile \
  --target prod \
  -t evently.api:latest .
docker buildx build \
  --platform linux/amd64 \
  -f src/Api/Evently.Ticketing.Api/Dockerfile \
  --target prod \
  -t evently.ticketing.api:latest .
docker buildx build \
  --platform linux/amd64 \
  -f src/Api/Evently.Gateway/Dockerfile \
  --target prod \
  -t evently.gateway:latest .

🧪 Testing

This project includes unit, integration and architectural tests.

Note

Tests are located in the root /test directory and the inside each module.

Testing Technologies:

  • xUnit: Test framework.
  • NetArchTest.Rules: Architectural tests.
  • Testcontainers: Integration testing with ephemeral container instances.
  • Microsoft.AspNetCore.Mvc.Testing: End-to-end and functional tests.

Running all tests

dotnet test

📘 Api Documentation

Evently API provides interactive documentation via Swagger with support for versioned endpoints and JWT authentication.

Once the APIs are running:

Api

  • OpenAPI spec (JSON): https://localhost:5001/openapi/v1.json
  • Swagger UI: https://localhost:5001/swagger

Ticketing Api

  • OpenAPI spec (JSON): https://localhost:5101/openapi/v1.json
  • Swagger UI: https://localhost:5101/swagger

Note

Replace 5001 and 5101 with your actual HTTPS ports if different.

About

This repository follows Milan Jovanović's course Modular Monolith using the latest ASP.NET Core features and best practices.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • C# 99.2%
  • Dockerfile 0.8%