Pourquoi self-héberger FastAPI sur un VPS ?
FastAPI tire toute sa performance du modèle ASGI asynchrone : connexions WebSocket persistantes, streaming de réponses et appels concurrents vers d'autres services. Les plateformes serverless coupent souvent les connexions longues et facturent chaque requête, ce qui pénalise une API à fort débit ou temps réel. Sur un VPS, vous lancez Uvicorn piloté par Gunicorn avec autant de workers que de cœurs, vous gardez les connexions ouvertes aussi longtemps que nécessaire et vous placez Nginx en frontal pour le TLS et le buffering. Vous contrôlez aussi le pool de connexions vers PostgreSQL et le cache Redis, deux leviers essentiels pour tenir des milliers de requêtes par seconde.
Bénéfices concrets d'un FastAPI auto-hébergé
- WebSockets et Server-Sent Events sans coupure de connexion ni timeout imposé.
- Réglage fin des workers Uvicorn/Gunicorn selon le nombre de cœurs du VPS.
- Latence faible et prévisible, sans démarrage à froid (cold start) du serverless.
- Documentation Swagger et ReDoc servies en interne, accessibles ou protégées à votre guise.
- Intégration directe avec un pool asynchrone PostgreSQL (asyncpg) et Redis.
- Coût fixe quel que soit le nombre d'appels API, idéal pour un backend de production.
Prérequis matériels et logiciels
Une API FastAPI est légère : 1 vCPU et 1 Go de RAM suffisent pour démarrer, mais visez 2 vCPU et 2 Go dès que vous ajoutez une base de données et un cache sur le même VPS. Installez Python 3.11+ ou utilisez Docker avec une image python:3.11-slim. Prévoyez Uvicorn avec le worker uvicorn.workers.UvicornWorker, Gunicorn comme gestionnaire de processus, et Nginx pour le reverse proxy. Un domaine pointé vers le VPS est requis pour le certificat TLS. Ubuntu 22.04/24.04 LTS est la base recommandée.
Déployer FastAPI étape par étape
Initialiser le VPS et l'application
Connectez-vous en SSH, installez Docker, clonez votre dépôt et créez un .env avec les variables d'environnement (URL de base de données, clés d'API, origine CORS). Vérifiez que votre point d'entrée expose bien app = FastAPI().
Conteneuriser avec Uvicorn et Gunicorn
Dans le Dockerfile, installez les dépendances puis lancez gunicorn main:app -k uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000 --workers 4. Le nombre de workers idéal est généralement (2 × cœurs) + 1.
Orchestrer les services
Dans docker-compose.yml, déclarez le service api, un service db PostgreSQL et un service redis. Utilisez depends_on et un healthcheck pour que l'API attende que la base soit prête avant de démarrer.
Placer Nginx en reverse proxy
Configurez un bloc serveur avec proxy_pass http://api:8000 et, pour les WebSockets, ajoutez proxy_set_header Upgrade $http_upgrade et proxy_set_header Connection "upgrade". Désactivez le buffering pour le streaming si nécessaire.
Sécuriser avec un certificat TLS
Obtenez un certificat Let's Encrypt via Certbot ou un conteneur companion, forcez le HTTPS et redirigez le HTTP. Pensez à restreindre l'accès à /docs et /openapi.json en production si l'API n'est pas publique.
Lancer et tester
Démarrez avec docker compose up -d, vérifiez la santé via le endpoint /health que vous aurez ajouté, et testez la documentation interactive. Surveillez les logs Uvicorn pour ajuster le nombre de workers sous charge réelle.
Pour les tâches longues (envoi d'emails, traitement d'images, appels externes lents), ne bloquez pas l'event loop : déportez-les vers un worker en arrière-plan avec BackgroundTasks pour les cas simples, ou vers Celery/ARQ avec Redis pour les traitements lourds. Une API qui répond vite et délègue le travail asynchrone reste réactive même sous forte concurrence.