Why does FastAPI's dependency override work locally but not in production Docker containers?
0 reputation · 19 Jul 2020, 18:33 UTC
0 reputation · 19 Jul 2020, 18:33 UTC
In a local development environment, a FastAPI dependency can be overridden using app.dependency_overrides[SomeDependency] = lambda: mock_service to inject a test double. When the same application is built as a Docker image and run in production, the override appears to be ignored and the real dependency is used instead. The service is launched with Uvicorn via a Dockerfile CMD, and configuration profiles are selected through environment variables.
What configuration or lifecycle differences prevent the dependency override from being applied in the production container? Are there patterns for conditionally applying overrides based on the deployment environment without modifying application code? How can one verify that an override is active in a running container without changing the service logic?
26525 reputation · 19 Jul 2020, 18:54 UTC
FastAPI's app.dependency_overrides is a runtime dictionary. If your overrides work locally but not in a production Docker container, the most likely cause is a process isolation mismatch. In production, you are likely using an ASGI server (like Uvicorn or Gunicorn) with multiple worker processes. Because dependency_overrides modifies the state of a specific FastAPI() instance in memory, an override applied in one process is not shared with others.
dependency_overrides is not a configuration file; it is a mutation of the app object. Any code that modifies this dictionary must execute within the same process that handles the incoming request.--workers 4, the OS forks the process. If the override logic is triggered by a specific event or a separate script that doesn't run inside every worker's lifecycle, the override will be missing.if env == 'prod': app.dependency_overrides[...] = ...) may be located in a test suite or a setup module that is not imported by the production entry point.Using dependency_overrides for production environment switching is an anti-pattern because it is designed for testing. Instead, use a Factory Pattern or Conditional Dependency based on environment variables.
from fastapi import Depends, FastAPI
import os
def get_service():
if os.getenv("APP_ENV") == "production":
return RealService()
return MockService()
app = FastAPI()
@app.get("/data")
async def read_data(service = Depends(get_service)):
return service.fetch()
To verify if an override is active without changing business logic, create a temporary diagnostic endpoint that inspects the app state:
@app.get("/debug/overrides")
async def check_overrides():
return {"overrides": list(app.dependency_overrides.keys())}
If this returns an empty list in production but shows the dependency locally, the code applying the override is not being executed in the production process.
Are you using a multi-worker configuration (e.g., --workers > 1) in your Docker CMD? If so, the solution must move from runtime overrides to a dependency factory.
Use comments to ask for clarification. Post a solution as an answer.
26,525 reputation · 19 Jul 2020, 20:53 UTC
When you run FastAPI with multiple workers (e.g., Gunicorn or Uvicorn with --workers), each worker loads its own copy of the FastAPI() object. If you set app.dependency_overrides after the workers have been forked, only the process that executed the assignment sees the change. To guarantee the override is visible to every request, place the override inside the application factory so that each worker creates its own app instance with the override already applied.
def create_app() -> FastAPI:
app = FastAPI()
if os.getenv('ENV') == 'test':
app.dependency_overrides[SomeDependency] = lambda: MockService()
return app
Then start the server with the factory, for example:
uvicorn "myapp:create_app" --factory --workers 4
You can verify that the override is active by adding a debug endpoint that returns the keys of app.dependency_overrides or by logging inside the dependency itself.