DEV Community

Cover image for Managing Production Configurations in ASP.NET Core WebAPI Using Environment Variables
Mofajjal Rasul
Mofajjal Rasul

Posted on

Managing Production Configurations in ASP.NET Core WebAPI Using Environment Variables

When you’re building modern, scalable applications with ASP.NET Core, one of the biggest challenges is managing configurations across different environments—development, staging, and production. You want a system that’s flexible, secure, and easy to update without touching your code or triggering a redeploy. The good news? ASP.NET Core has an amazing built-in configuration system that makes all of this possible.

In this article, we’ll break down exactly how you can use environment variables to manage your configurations, how the ASPNETCORE_ENVIRONMENT variable works, and how ASP.NET Core prioritizes settings when you have multiple configuration sources. By the end, you’ll know how to keep your app’s configuration clean, secure, and production-ready.


Why Environment Variables Are a Game-Changer

First things first: why bother with environment variables? The short answer is that they’re:

  • Secure: You can keep sensitive data like API keys and connection strings out of your codebase.
  • Dynamic: No need to rebuild or redeploy your app to update configurations—just change the variable.
  • Consistent: They’re a standard way of managing settings across modern deployment platforms like Docker, Kubernetes, and cloud services.

How ASP.NET Core Handles Configurations

ASP.NET Core’s configuration system is built around flexibility. It pulls settings from multiple sources and layers them together. Here’s how it works:

  1. Default appsettings.json - This file contains your app’s baseline settings—think of it as your starting point.

  2. Environment-Specific appsettings Files - For example, if you set ASPNETCORE_ENVIRONMENT=Production, ASP.NET Core will automatically load appsettings.Production.json. This lets you define overrides for specific environments.

  3. Environment Variables - These take priority over anything in your appsettings files. You can dynamically inject them at runtime, making them perfect for production.

  4. Command-Line Arguments - If you really need something to take precedence over everything else, you can pass it as a command-line argument.


Let’s Break It Down: How Environment Variables Work

To show how environment variables override settings, let’s start with a basic example. Imagine this appsettings.json file:

{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AppSettings": {
    "ApiUrl": "https://api.default.com",
    "ApiKey": "default-api-key"
  }
}
Enter fullscreen mode Exit fullscreen mode

Setting Up an Environment-Specific File

Now, if you add an appsettings.Production.json file for production:

{
  "AppSettings": {
    "ApiUrl": "https://api.production.com"
  }
}
Enter fullscreen mode Exit fullscreen mode

When you set ASPNETCORE_ENVIRONMENT=Production, ASP.NET Core will automatically merge appsettings.Production.json into the configuration. So, ApiUrl will now be https://api.production.com, while ApiKey remains as default-api-key.

Using Environment Variables to Override Everything

Environment variables take it one step further. If you set the following environment variables:

AppSettings__ApiUrl=https://api.override.com
AppSettings__ApiKey=override-api-key
Enter fullscreen mode Exit fullscreen mode

ASP.NET Core will prioritize these values over both appsettings.json and appsettings.Production.json. The final configuration would be:

  • ApiUrl: https://api.override.com
  • ApiKey: override-api-key

Notice the pattern here: ASP.NET Core uses __ (double underscores) to represent nested JSON keys. So, AppSettings:ApiUrl in JSON becomes AppSettings__ApiUrl as an environment variable.


Priority Order: Who Wins?

If you’re wondering how ASP.NET Core decides which configuration to use when you have multiple sources, here’s the priority list, from lowest to highest:

  • Default values in code: If you hardcode defaults in your app.
  • appsettings.json: Your baseline configuration.
  • appsettings..json: Environment-specific overrides (e.g., appsettings.Production.json).
  • Environment variables: Perfect for production or dynamic settings.
  • Command-line arguments: The final word—these override everything else.

This order is critical because it ensures that you can always override configurations dynamically, without needing to touch your app’s code or rebuild it.


Using Environment Variables in Docker Compose

Let’s say you’re running your app in Docker Compose. You can easily pass environment variables in the docker-compose.yml file:

version: "3.9"
services:
  webapi:
    image: yourapp:latest
    environment:
      - ASPNETCORE_ENVIRONMENT=Production
      - AppSettings__ApiUrl=https://api.docker.com
      - AppSettings__ApiKey=docker-api-key
    ports:
      - "5000:80"
Enter fullscreen mode Exit fullscreen mode

Or, if you prefer, you can use an .env file to manage these variables:

version: "3.9"
services:
  webapi:
    image: yourapp:latest
    env_file:
      - .env
    ports:
      - "5000:80"
Enter fullscreen mode Exit fullscreen mode

Here’s what the .env file might look like:

ASPNETCORE_ENVIRONMENT=Production
AppSettings__ApiUrl=https://api.envfile.com
AppSettings__ApiKey=envfile-api-key
Enter fullscreen mode Exit fullscreen mode

Using Environment Variables in Kubernetes

In Kubernetes, ConfigMaps and Secrets are the standard way to manage environment variables.

ConfigMap for Non-Sensitive Data

Create a ConfigMap like this:

apiVersion: v1
kind: ConfigMap
metadata:
  name: appsettings-config
data:
  AppSettings__ApiUrl: https://api.k8s.com
Enter fullscreen mode Exit fullscreen mode

Secret for Sensitive Data

For things like API keys, use a Secret instead:

apiVersion: v1
kind: Secret
metadata:
  name: appsettings-secret
type: Opaque
data:
  AppSettings__ApiKey: a3BpLXZhbHVlCg== # Base64-encoded value
Enter fullscreen mode Exit fullscreen mode

Deployment Example

Then reference these in your app’s deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: webapi-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: webapi
  template:
    metadata:
      labels:
        app: webapi
    spec:
      containers:
      - name: webapi
        image: yourapp:latest
        envFrom:
        - configMapRef:
            name: appsettings-config
        - secretRef:
            name: appsettings-secret
Enter fullscreen mode Exit fullscreen mode

The Big Picture: Production-Ready Configuration

To recap:

  1. Start with appsettings.json for defaults.
  2. Add environment-specific files like appsettings.Production.json for targeted overrides.
  3. Use environment variables for dynamic settings in production.
  4. Remember the priority order: environment variables and command-line arguments always win.

This approach ensures your app is ready for production, no matter where it’s running—on-prem, in Docker, or in Kubernetes. You’ll have full control over configurations without ever touching the code.

So, next time you’re setting up a production environment, skip the manual edits and let ASP.NET Core’s configuration system do the heavy lifting. It’s simple, powerful, and just works.

Image of AssemblyAI tool

Transforming Interviews into Publishable Stories with AssemblyAI

Insightview is a modern web application that streamlines the interview workflow for journalists. By leveraging AssemblyAI's LeMUR and Universal-2 technology, it transforms raw interview recordings into structured, actionable content, dramatically reducing the time from recording to publication.

Key Features:
🎥 Audio/video file upload with real-time preview
🗣️ Advanced transcription with speaker identification
⭐ Automatic highlight extraction of key moments
✍️ AI-powered article draft generation
📤 Export interview's subtitles in VTT format

Read full post

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Explore a sea of insights with this enlightening post, highly esteemed within the nurturing DEV Community. Coders of all stripes are invited to participate and contribute to our shared knowledge.

Expressing gratitude with a simple "thank you" can make a big impact. Leave your thanks in the comments!

On DEV, exchanging ideas smooths our way and strengthens our community bonds. Found this useful? A quick note of thanks to the author can mean a lot.

Okay