ENVIRONMENT_CONFIG.md 6.8 KB

Environment Configuration Guide

Overview

The application uses hierarchical configuration with environment-specific settings. There are two ways the environment is determined:

  1. DOTNET_ENVIRONMENT (environment variable) - Controls which appsettings.{Environment}.json file is loaded
  2. Application:Environment (configuration setting) - Stored in each appsettings file for application code to read

How It Works

Step 1: Set DOTNET_ENVIRONMENT

The DOTNET_ENVIRONMENT environment variable determines which configuration file to load:

# Load appsettings.Development.json
DOTNET_ENVIRONMENT=Development

# Load appsettings.Staging.json
DOTNET_ENVIRONMENT=Staging

# Load appsettings.Production.json (default)
DOTNET_ENVIRONMENT=Production

Step 2: Configuration File Is Loaded

Based on DOTNET_ENVIRONMENT, .NET loads:

  1. appsettings.json (base configuration)
  2. appsettings.{Environment}.json (overrides base)

Step 3: Application:Environment Setting

Each environment-specific file defines its own Application:Environment value:

appsettings.Development.json:

{
  "Application": {
    "Environment": "Development"
  },
  ...
}

appsettings.Production.json:

{
  "Application": {
    "Environment": "Production"
  },
  ...
}

Usage Examples

Local Development

cd src/EmbaseConferenceScheduler.Worker

# Run with Development settings
dotnet run --environment Development

Result:

  • Loads appsettings.Development.json
  • Application:Environment = "Development"
  • Uses local database, test SFTP
  • CRON runs every 5 minutes

Docker Production

Run with Production environment:

docker run -d \
  -e DOTNET_ENVIRONMENT=Production \
  -v /data/production/articles/pdf:/production/articles/pdf:ro \
  -v embase-logs:/logs \
  --name embase-conference-scheduler \
  embase-conference-scheduler:latest

Result:

  • Loads appsettings.Production.json
  • Application:Environment = "Production"
  • Uses production database, production SFTP
  • CRON runs daily at 02:00 IST

Docker Staging

Run with Staging environment:

docker run -d \
  -e DOTNET_ENVIRONMENT=Staging \
  -v /data/production/articles/pdf:/production/articles/pdf:ro \
  -v embase-logs:/logs \
  --name embase-conference-scheduler \
  embase-conference-scheduler:latest

Result:

  • Loads appsettings.Staging.json
  • Application:Environment = "Staging"
  • Uses staging database, staging SFTP
  • CRON runs daily at 03:00 IST

Reading Environment in Code

You can inject IOptions<ApplicationSettings> to read the environment:

using EmbaseConferenceScheduler.Domain.Configuration;
using Microsoft.Extensions.Options;

public class MyService
{
    private readonly ApplicationSettings _appSettings;
    
    public MyService(IOptions<ApplicationSettings> options)
    {
        _appSettings = options.Value;
    }
    
    public void DoSomething()
    {
        if (_appSettings.Environment == "Development")
        {
            // Special dev behavior
        }
        else if (_appSettings.Environment == "Production")
        {
            // Production behavior
        }
    }
}

Configuration Priority

Settings are loaded in this order (last wins):

  1. appsettings.json (base defaults)
  2. appsettings.{Environment}.json (environment-specific)
  3. Environment variables (runtime overrides)
  4. Command-line arguments (highest priority)

Example Override

Even if appsettings.Production.json says:

{
  "ConnectionStrings": {
    "EmbaseDb": "Host=prod-db;..."
  }
}

You can override at runtime:

# docker-compose.yml
environment:
  ConnectionStrings__EmbaseDb: "Host=override-db;Port=5432;..."

Environment Settings Reference

File Application:Environment Database SFTP CRON Schedule
appsettings.json Production localhost sftp.elsevier.com Daily 02:00
appsettings.Development.json Development localhost:embase_dev localhost:2222 Every 5 min
appsettings.Staging.json Staging staging-db sftp-staging Daily 03:00
appsettings.Production.json Production prod-db sftp.elsevier.com Daily 02:00

Logging

On startup, the application logs the active environment:

[2026-03-09 10:30:15 INF] Starting Embase Conference Abstract Scheduler...
[2026-03-09 10:30:16 INF] Scheduler host built successfully.
[2026-03-09 10:30:16 INF] DOTNET_ENVIRONMENT: Production
[2026-03-09 10:30:16 INF] Application Environment (from appsettings): Production
[2026-03-09 10:30:16 INF] Configuration file loaded: appsettings.Production.json
[2026-03-09 10:30:16 INF] Waiting for Quartz trigger...

Quick Reference

Change Environment

Method How To Set
Command Line dotnet run --environment Staging
Docker Compose DOTNET_ENVIRONMENT: Staging in environment section
Docker Run docker run -e DOTNET_ENVIRONMENT=Staging ...
Windows $env:DOTNET_ENVIRONMENT="Staging"
Linux export DOTNET_ENVIRONMENT=Staging

Verify Active Environment

  1. Check startup logs for "DOTNET_ENVIRONMENT" message
  2. Check startup logs for "Application Environment (from appsettings)" message
  3. Both should match the environment you intended to use

Best Practices

DO:

  • Set DOTNET_ENVIRONMENT to control which file loads
  • Keep environment-sensitive values in environment-specific files
  • Use environment variables to override secrets at runtime
  • Verify logs on startup to confirm correct environment

DON'T:

  • Commit production secrets to source control
  • Mix environment settings (e.g., production DB in development file)
  • Rely solely on Application:Environment - use .NET's built-in IHostEnvironment

Troubleshooting

Wrong Environment Loaded

Problem: Application loads Production settings when you expected Development

Solution:

# Verify DOTNET_ENVIRONMENT is set
echo $env:DOTNET_ENVIRONMENT  # Windows
echo $DOTNET_ENVIRONMENT       # Linux

# Set it explicitly
dotnet run --environment Development

Settings Not Overriding

Problem: Changed appsettings.Development.json but changes don't apply

Possible causes:

  1. Wrong environment loaded - check DOTNET_ENVIRONMENT
  2. Environment variable override - check docker-compose.yml
  3. Cached build - run dotnet clean; dotnet build

Application:Environment Doesn't Match

Problem: Logs show:

DOTNET_ENVIRONMENT: Production
Application Environment: Development

This means:

  • You're running with DOTNET_ENVIRONMENT=Production
  • But appsettings.Production.json has wrong Application:Environment value
  • Fix the JSON file to match

For more details, see README_Architecture.md