Environment File Management
To configure the application for different environments, you must manage a .env file and set the ENVIRONMENT variable to control security enforcement and feature toggling.
The application uses the Settings class in backend/app/core/config.py to load and validate these configurations.
Configure the .env File Location
The application is configured to look for a .env file at the project root, which is one level above the backend directory.
Create a file named .env in your project root:
# Project Root
.
├── .env
└── backend/
└── app/
└── core/
└── config.py
The Settings class defines this location in its model_config:
# backend/app/core/config.py
class Settings(BaseSettings):
model_config = SettingsConfigDict(
# Use top level .env file (one level above ./backend/)
env_file="../.env",
env_ignore_empty=True,
extra="ignore",
)
Define Required Environment Variables
For the application to start, you must provide several required variables in your .env file. If these are missing, Pydantic will raise a validation error on startup.
# .env example
PROJECT_NAME="My FastAPI Project"
POSTGRES_SERVER=localhost
POSTGRES_USER=postgres
POSTGRES_PASSWORD=changethis
FIRST_SUPERUSER=admin@example.com
FIRST_SUPERUSER_PASSWORD=changethis
These correspond to the following fields in Settings:
# backend/app/core/config.py
PROJECT_NAME: str
POSTGRES_SERVER: str
POSTGRES_USER: str
FIRST_SUPERUSER: EmailStr
FIRST_SUPERUSER_PASSWORD: str
Handle Environment-Specific Overrides
The ENVIRONMENT variable determines how the application handles security and secrets. It accepts three values: local, staging, or production.
Local Development
In local mode (the default), using default secrets like "changethis" will only trigger a warning.
ENVIRONMENT=local
SECRET_KEY=changethis
Staging and Production
In staging or production, the application enforces strict security. If SECRET_KEY, POSTGRES_PASSWORD, or FIRST_SUPERUSER_PASSWORD are set to "changethis", the application will raise a ValueError and fail to start.
# backend/app/core/config.py
def _check_default_secret(self, var_name: str, value: str | None) -> None:
if value == "changethis":
message = (
f'The value of {var_name} is "changethis", '
"for security, please change it, at least for deployments."
)
if self.ENVIRONMENT == "local":
warnings.warn(message, stacklevel=1)
else:
raise ValueError(message)
Configure CORS Origins
You can manage allowed CORS origins via the BACKEND_CORS_ORIGINS variable. The parse_cors utility allows you to provide these as either a JSON-formatted list or a comma-separated string.
Using a Comma-Separated String
BACKEND_CORS_ORIGINS="http://localhost:3000,https://app.example.com"
Using a JSON List
BACKEND_CORS_ORIGINS='["http://localhost:3000", "https://app.example.com"]'
The Settings class automatically combines these with the FRONTEND_HOST to create the final list used by the FastAPI middleware:
# backend/app/core/config.py
@computed_field
@property
def all_cors_origins(self) -> list[str]:
return [str(origin).rstrip("/") for origin in self.BACKEND_CORS_ORIGINS] + [
self.FRONTEND_HOST
]
Troubleshooting
Application Fails to Start in Production
If you see a ValueError regarding "changethis", ensure you have updated your secrets in the .env file or environment variables:
ValueError: The value of SECRET_KEY is "changethis", for security, please change it, at least for deployments.
Solution: Update your .env file with secure values:
ENVIRONMENT=production
SECRET_KEY=your-actual-secure-random-secret-key
POSTGRES_PASSWORD=your-secure-db-password
FIRST_SUPERUSER_PASSWORD=your-secure-admin-password
Database Connection Issues
The SQLALCHEMY_DATABASE_URI is automatically constructed from individual POSTGRES_* variables. If the connection fails, verify these specific variables:
# backend/app/core/config.py
@computed_field
@property
def SQLALCHEMY_DATABASE_URI(self) -> PostgresDsn:
return PostgresDsn.build(
scheme="postgresql+psycopg",
username=self.POSTGRES_USER,
password=self.POSTGRES_PASSWORD,
host=self.POSTGRES_SERVER,
port=self.POSTGRES_PORT,
path=self.POSTGRES_DB,
)
Ensure POSTGRES_PORT is an integer (defaults to 5432) and POSTGRES_SERVER is a valid host.