FastAPI Advanced: Security, Async and Production
Deploying and Operating
In this lesson you will
- Describe how an ASGI app is served in production
- Package the app in a container and configure it through the environment
- Apply a production checklist covering security, logging and monitoring
Introduction
Running uvicorn main:app --reload on your laptop is development. A production deployment needs more: a stable server process, HTTPS, configuration through the environment, logs, monitoring and a way to update safely. The details depend on your host. This lesson gives the concepts and a checklist. The Dockerfile below was not built or run in this course's tests. The application commands were tested with Uvicorn.
What runs your app
A FastAPI app is an ASGI application. A server such as Uvicorn speaks HTTP and calls your app. In production you typically have:
Internet -> reverse proxy / load balancer (HTTPS) -> Uvicorn process(es) -> your app -> database- The reverse proxy (for example Nginx, Caddy, a cloud load balancer) terminates HTTPS, adds timeouts and limits and forwards requests.
- Uvicorn runs one or more worker processes. A common rule is one process per available CPU core as a starting point, then measure. Options and process managers change between versions, so check the current deployment page of the FastAPI documentation.
Start the app without reload, and bind to all interfaces only when behind a proxy or container:
Terminal
uvicorn app.main:app --host 0.0.0.0 --port 8000I ran this style of command (on another port) and confirmed that /health returned {"status":"ok"}, that /docs returned 200 and that creating and listing a book through the running server worked, with the lifespan creating the database file.
Containers
A container packages the app and its dependencies. A typical Dockerfile (not tested here):
Dockerfile
FROM python:3.13-slim
WORKDIR /code
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app ./app
RUN useradd --create-home appuser
USER appuser
EXPOSE 8000
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]Notes:
- Pin dependency versions in
requirements.txt(pip freezeor a lock file) so builds are repeatable. - Run as a non-root user.
- Keep secrets out of the image. Pass them as environment variables at run time.
- Use a .dockerignore to exclude your virtual environment,
.envand the local database. - A container's file system is temporary, so use a managed database or a mounted volume for data. SQLite files are usually unsuitable for multiple instances.
Quick quiz
Where should production secrets such as a signing key be supplied?
Health checks and updates
- Keep a
/healthendpoint. Orchestrators and load balancers use it to restart or route around unhealthy instances. A deeper readiness check can test the database connection. - Roll out gradually and keep the previous version available so you can roll back.
- Run database migrations as a controlled step.
- Handle graceful shutdown, so in-flight requests can finish.
Logging and monitoring
- Log to standard output in a consistent, structured format, and let the platform collect logs.
- Include a request ID (the earlier middleware) so one request can be traced.
- Do not log passwords, tokens or personal data.
- Track errors, latency and request rates, and alert on problems.
- Keep an eye on dependency security advisories and update regularly.
Production checklist
- HTTPS only, with a valid certificate.
--reloadoff, debug features off.- Secrets from the environment, no defaults for secrets.
- CORS restricted to known origins.
- Authentication and per-resource authorisation tested.
- Rate limiting at the proxy or gateway.
- Request size limits and timeouts.
- Interactive docs protected or disabled if the API is private.
- A managed, backed-up database.
- Logs, metrics and alerts.
- Automated tests running before every deployment.
- A rollback plan.
Hosting options
Many platforms run Python containers or processes, including cloud container services and platform-as-a-service providers. Free tiers exist but have limits, such as sleeping apps and usage caps, so read the terms. Choose by your needs and budget.
Try it yourself
Write a requirements.txt with pinned versions from your virtual environment. Write the Dockerfile above for your project and, if you have Docker installed, build and run it. Check /health and review the checklist for items you have missed.
Summary
- Production runs an ASGI server such as Uvicorn behind a reverse proxy that handles HTTPS, timeouts and limits.
- Containers need pinned dependencies, a non-root user and secrets supplied at run time.
- Use health checks, structured logs without secrets, monitoring, backups and a checklist before going live.
Lesson complete
+20 XP
Nice work. Keep going while it is fresh.
Sources and further reading