- Overview
- BaseAppSettings
- Extending AppSettings
- Environment Variables
- Secret Management
- Dependency Injection
- Examples
The cloops.microservices SDK provides a simple and flexible configuration system based on environment variables. Configuration is managed through the BaseAppSettings class, which is automatically registered in the dependency injection container.
BaseAppSettings is the base configuration class that reads values from environment variables. It includes the following properties:
Debug- Enable verbose debugging (default:False)NatsURL- NATS server URL (default:tls://nats.ccnp.cloops.in:4222)NatsCreds- NATS credentials contentAssemblyName- Application assembly name (auto-detected)OtelEndpoint- OpenTelemetry endpoint URLOtelHeaders- OpenTelemetry headersCluster- Target cluster name (default:ccnp)ConnectionString- SQL database connection stringEnableMigrations- Enable/disable startup database migrations when amigrationsfolder is present (default:True)EnableNatsConsumers- Enable/disable NATS consumers (default:False)EnableRestEndpoints- Enable/disable lightweight REST endpoints (default:True)RestPort- Port used by the lightweight REST endpoint server (default:8080)RestApiSecret- Shared secret for REST endpoints markedRestAuth.RequiredTigerBeetleAddresses- Comma-separated TigerBeetle replica addressesTigerBeetleClusterId- TigerBeetle cluster ID (default:0)EnableSnowflakeId- Enable/disable Snowflake ID generation via IdGen (default:False)SnowflakeGeneratorId- Unique, stable per-node generator id for IdGen (required whenEnableSnowflakeIdisTrue)
All properties use init accessors and read from environment variables with sensible defaults.
You can extend BaseAppSettings to add your own configuration properties:
namespace yourapp.services;
public class AppSettings : BaseAppSettings
{
public string ApiKey { get; init; } = Environment.GetEnvironmentVariable("API_KEY") ?? "";
public int MaxRetries { get; init; } = int.Parse(
Environment.GetEnvironmentVariable("MAX_RETRIES") ?? "3"
);
public bool FeatureEnabled { get; init; } = Convert.ToBoolean(
Environment.GetEnvironmentVariable("FEATURE_ENABLED") ?? "False"
);
}Make sure the AppSettings you just created is in .*.services namespace so that it is auto registered in DI.
var app = new App();
app.appSettings = new AppSettings(); // Use your custom class
app.builder.Services.AddSingleton<AppSettings>(app.appSettings);Configuration values are loaded from environment variables. Set them before starting your application. Below is a comprehensive reference of all environment variables used by the SDK.
| Variable Name | Category | Description | Default Value | Required |
|---|---|---|---|---|
DEBUG |
Microservice | Turns on verbose logging and additional diagnostics when set to True |
False |
No |
NATS_URL |
NATS | Specifies the NATS server URL. For running on prod CCNP, set to tls://nats-headless.ccnp.cloops.in:4222 for faster within cluster operations |
tls://nats.ccnp.cloops.in:4222 |
No |
NATS_CREDS |
NATS | Inline content of the NATS credentials file used for authentication | None | No |
NATS_SUBSCRIPTION_QUEUE_SIZE |
NATS | Maximum limit of messages queued up for each subscription. Use this to control backpressure | 20000 |
No |
NATS_CONSUMER_MAX_DOP |
NATS | Maximum degree of parallelism for all consumers. These many messages can be processed in parallel from the message queue. This puts upper limit on rps (request per second) indirectly (e.g. if your avg latency is 200ms then max_dop × 5 is your max throughput). Increase this in order to support higher rps. Consider giving higher core / memory count as well | 128 |
No |
NATS_ACCOUNT_SIGNING_SEED |
NATS (Minting) | Signing account seed. |
None | No |
NATS_ACCOUNT_PUBLIC_KEY |
NATS (Minting) | Main account public key. |
None | No |
DOTNET_ENVIRONMENT |
Microservice | Controls the .NET runtime environment. Set to Development, or any non-Production value, to render logs in a human-friendly console format. Production uses compact JSON logs |
Production |
No |
CCNPOTELENDPOINT |
Microservice | OTEL collector endpoint for exporting telemetry to CCNP | None | No |
CCNPOTELHEADERS |
Microservice | Additional OTEL headers required when sending telemetry to CCNP | None | No |
CLUSTER |
Microservice | Target cluster where the service runs | ccnp |
No |
CNSTR |
Microservice | SQL database connection string | None | No |
ENABLE_MIGRATIONS |
Microservice | Controls whether startup database migrations run when a migrations folder exists next to the app binary |
True |
No |
ENABLE_NATS_CONSUMERS |
Microservice | Controls whether NATS consumers start with the service | False |
No |
ENABLE_REST_ENDPOINTS |
Microservice | Controls whether the lightweight REST server starts. The SDK provides /healthz and /readyz when enabled |
True |
No |
REST_PORT |
Microservice | Port used by the lightweight REST server | 8080 |
No |
REST_API_SECRET |
Microservice | Shared secret required by REST endpoints marked RestAuth.Required. Send it as Authorization: Bearer <secret> or X-CLOOPS-REST-SECRET: <secret> |
None | Only for auth-required REST endpoints |
TB_ADDRESSES |
TigerBeetle | Comma-separated TigerBeetle replica addresses. When provided, the SDK registers TigerBeetle.Client in dependency injection |
None | No |
TB_CLUSTER_ID |
TigerBeetle | TigerBeetle cluster ID used when creating the client | 0 |
No |
ENABLE_SNOWFLAKE_ID |
Snowflake | When True, registers the IdGen Snowflake ID generator in dependency injection. Requires SNOWFLAKE_GENERATOR_ID to be set to a unique, stable per-node value |
False |
No |
SNOWFLAKE_GENERATOR_ID |
Snowflake | Integer generator (node) id for IdGen. Must be unique per replica and stable across restarts (e.g. a Kubernetes StatefulSet pod ordinal). The app errors out at startup if ENABLE_SNOWFLAKE_ID is True and this is missing/invalid |
None | Yes, when ENABLE_SNOWFLAKE_ID=True |
Set environment variables before starting your application:
export DEBUG=True
export NATS_URL=tls://nats.example.com:4222
export NATS_CREDS="your-credentials-here"
export CNSTR="Server=localhost;Database=mydb;..."
export ENABLE_MIGRATIONS=True
export TB_ADDRESSES="127.0.0.1:3000"
export TB_CLUSTER_ID=0
export CLUSTER=production
export DOTNET_ENVIRONMENT=Development
export ENABLE_NATS_CONSUMERS=True
export ENABLE_REST_ENDPOINTS=True
export REST_PORT=8080
export REST_API_SECRET="your-rest-secret"
export ENABLE_SNOWFLAKE_ID=True
export SNOWFLAKE_GENERATOR_ID=3TigerBeetle is optional. If TB_ADDRESSES is empty, no TigerBeetle client is registered. If it is set, cloops.microservices parses the comma-separated addresses and registers a singleton TigerBeetle.Client using TB_CLUSTER_ID.
Use TigerBeetle for ledger and accounting workloads such as account balances, credits and debits, money movement, transfers, pending transfers, and idempotent financial transaction processing. See TigerBeetle for usage examples and links to the upstream .NET client documentation.
How to get it:
- On nats-box
- Run
cd /data/nsc/nkeys/keys/A - Run
find . -type f -name "*.nk" -o -name "*.seed" - Run
cat <account-signing-public-key>.nkto get the account signing seed- Important: Remember to pick public key of signing account, not main account
How to get it:
- Run this on nats-box to get the account public key:
nsc list keys --account=<account-name>- Important: Remember to pick the main account, not signing key
We strongly recommend using a secret management service like Doppler to securely manage your environment variables, especially in production environments.
-
Install Doppler CLI:
brew install doppler # macOS # or curl -Ls --tlsv1.2 --proto "=https" https://cli.doppler.com/install.sh | sh
-
Login and setup:
create a file doppler.yaml
setup:
- project: your-project
config: devTo login to doppler, just export an environment variable DOPPLER_TOKEN with your doppler token.
and run below command -
doppler setup-
Run your application with Doppler:
doppler run -- dotnet run
Doppler automatically injects environment variables from your configured project and config, keeping secrets out of your codebase and deployment manifests.
If using doppler on kubernetes or other production environments, check out official doppler integration guide.
- Azure Key Vault - For Azure-hosted applications
- AWS Secrets Manager - For AWS-hosted applications
- HashiCorp Vault - For self-hosted secret management
- Kubernetes Secrets - For containerized deployments
BaseAppSettings (or your custom AppSettings) is automatically registered as a singleton in the DI container during application initialization. You can inject it into any service through constructor injection.
namespace your.namespace.services;
public class MyService
{
private readonly AppSettings _settings;
public MyService(AppSettings settings)
{
_settings = settings;
}
public void DoSomething()
{
if (_settings.Debug)
{
Console.WriteLine("Debug mode enabled");
}
}
}Next Steps: