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.
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.
Code Mala Tang
Read source code together, write articles together, and enjoy spicy hot pot together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.