Backend Development 6 min read

Mastering Environment Variables in FastAPI: Secure, Scalable Configurations

This guide explains why environment variables are essential for FastAPI projects and provides step‑by‑step instructions for both a simple .env + python‑dotenv setup and a modern pydantic‑settings approach, including Docker integration and security best practices.

Code Mala Tang
Code Mala Tang
Code Mala Tang
Mastering Environment Variables in FastAPI: Secure, Scalable Configurations

Environment variables are the indispensable behind‑the‑scenes hero of modern backend development. Whether building an MVP or deploying a production‑ready FastAPI app, managing configuration via environment variables ensures security, flexibility, and portability.

In this guide we explore a clear, scalable, production‑ready approach to handling environment variables in FastAPI using tools such as .env files, python‑dotenv, and the powerful pydantic‑settings.

🧠 Why use environment variables?

Hard‑coding credentials or settings into code is a huge security risk. Imagine pushing code with a database password to GitHub – disaster!

Using environment variables lets you:

Exclude sensitive data from version control.

Seamlessly switch between development, staging, and production environments.

Keep code clearer and more readable.

🛠️ Option 1: Basic setup with .env + python‑dotenv

This method is ideal for quick local development.

📦 Step 1: Install package

<code>pip install python-dotenv</code>

📄 Step 2: Create .env file in project root

<code>DEBUG=True
DATABASE_URL=postgresql://user:pass@localhost/db
SECRET_KEY=super-secret-key</code>
✅ Note: Never commit the .env file to Git! Add it to .gitignore .

🧬 Step 3: Load variables in code

<code># main.py
from dotenv import load_dotenv
import os
load_dotenv()  # Load .env into the environment
DEBUG = os.getenv("DEBUG", "False") == "True"
DATABASE_URL = os.getenv("DATABASE_URL")
SECRET_KEY = os.getenv("SECRET_KEY")</code>

You can now safely use these variables in your FastAPI app.

🧪 Option 2: Modern approach with pydantic‑settings

This method is strongly recommended for production applications and large teams, offering type safety, validation, and default fallbacks.

📦 Step 1: Install dependency

<code>pip install pydantic-settings</code>

⚙️ Step 2: Create config class

<code># config.py
from pydantic_settings import BaseSettings

class Settings(BaseSettings):
    DEBUG: bool = False
    DATABASE_URL: str
    SECRET_KEY: str

    class Config:
        env_file = ".env"

settings = Settings()</code>

⚡ Step 3: Use settings in FastAPI app

<code># main.py
from fastapi import FastAPI
from config import settings

app = FastAPI(debug=settings.DEBUG)

@app.get("/")
def read_root():
    return {
        "environment": "development" if settings.DEBUG else "production",
        "db": settings.DATABASE_URL,
    }</code>

Simple, clear and type‑safe!

🚀 Switching between environments

Assume you have separate configuration files such as:

.env.development

.env.staging

.env.production

You can dynamically load the appropriate file based on an ENV variable:

<code># config.py
import os
from pydantic_settings import BaseSettings

class Settings(BaseSettings):
    DEBUG: bool = False
    DATABASE_URL: str
    SECRET_KEY: str

    class Config:
        env_file = f".env.{os.getenv('ENV', 'development')}"
</code>

Then set your environment:

<code>ENV=production uvicorn main:app --host 0.0.0.0 --port 8000</code>

📁 Recommended project structure

<code>project/
├── app/
│   ├── main.py
│   ├── config.py
│   └── ...
├── .env.development
├── .env.production
└── requirements.txt</code>

🛡️ Security tips

✅ Add .env* to .gitignore .

✅ In production, use deployment secrets (Docker, GitHub Actions, Heroku) instead of plain .env files.

✅ Avoid logging sensitive environment variables.

🐳 Bonus: Using environment variables in Docker

If you containerize your app, you can pass environment variables via the Dockerfile or docker‑compose .env file.

Dockerfile:

<code>ENV DATABASE_URL=postgresql://prod_user:pass@prod/db</code>

docker-compose.yml:

<code>services:
  web:
    build: .
    env_file:
      - .env.production</code>

💬 Final summary

FastAPI gives us speed, and Pydantic provides type safety. Combine them with smart environment‑variable management and your backend becomes robust and secure.

Dockersecurityfastapibackend configurationEnvironment Variablespydantic-settingspython-dotenv
Code Mala Tang
Written by

Code Mala Tang

Read source code together, write articles together, and enjoy spicy hot pot together.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.