Cómo desplegar FastAPI en producción desde GitHub
Una guía práctica para convertir un repositorio de FastAPI en un servicio reproducible, observable y preparado para crecer sin ocultar sus riesgos.
El contrato de despliegue empieza en el repositorio
Un botón de “Deploy” no corrige un proyecto ambiguo. El repositorio debe declarar la versión de Python, las dependencias bloqueadas, el comando de inicio y las variables necesarias. Si la aplicación vive en app/main.py, un comando legible es:
uvicorn app.main:app --host 0.0.0.0 --port $PORT
Escuchar en 0.0.0.0 permite que el enrutador alcance el proceso. El puerto debe venir del entorno; escribir un número fijo crea diferencias entre desarrollo y producción.
Conecta únicamente el repositorio y la rama que realmente publican. La rama de producción debe exigir revisión y pruebas. Un preview de una pull request tampoco debería usar credenciales de producción ni escribir en la misma base de datos.
Separa build, migración y ejecución
Durante el build se instalan dependencias bloqueadas y se crea un artefacto inmutable. Durante la publicación se ejecuta, si hace falta, una migración controlada. Durante el runtime solo arranca la API.
No añadas alembic upgrade head al comando de todas las réplicas. Dos procesos pueden intentar modificar el mismo esquema. Además, una migración lenta impediría que el servidor web quedara saludable. Conviene lanzar una tarea única, conservar su salida y detener el cambio de tráfico si falla.
Las migraciones deben tolerar una publicación gradual. Primero añade una columna opcional, después despliega código compatible con ambos estados, realiza el relleno de datos y aplica la restricción en una versión posterior.
Health checks que no empeoran el incidente
Un endpoint como /healthz debe responder rápido y demostrar que el proceso atiende HTTP. Una comprobación de disponibilidad puede verificar la inicialización crítica antes de recibir tráfico. No consultes correo, pagos y todos los servicios externos en cada prueba de vida: una caída ajena no debería reiniciar todas las réplicas sanas.
Prueba también el apagado. El proceso debe dejar de aceptar trabajo y terminar las solicitudes activas antes del límite. Exportaciones, correos y tareas de IA largas pertenecen a un worker con estado persistente, no a una petición sin límite.
Workers, memoria y conexiones
Más workers no significa automáticamente más capacidad. La documentación oficial de FastAPI recuerda que los procesos normalmente no comparten memoria. Si cada worker carga un modelo de 700 MB, cuatro workers consumen aproximadamente cuatro copias, además del resto de la aplicación.
Cuenta también las conexiones. Cinco procesos con un pool de veinte conexiones pueden abrir cien sesiones contra una base de datos pequeña. Ajusta concurrencia, memoria y pool como un solo presupuesto y escala después de medir latencia y saturación.
Una prueba de publicación útil
- Publica una versión conocida y llama a
/healthzdesde la URL pública. - Completa una operación real contra una base de datos de prueba.
- Provoca un error esperado y encuéntralo mediante un identificador de solicitud.
- Publica una versión que no supera salud y comprueba que no recibe tráfico.
- Restaura una copia de la base de datos en otro destino y mide el tiempo.
El despliegue está listo cuando un commit revisado produce siempre el mismo artefacto, los secretos viven fuera del repositorio, una sola tarea controla el esquema, los fallos son visibles y el equipo ha practicado la recuperación.
Preguntas frecuentes
¿Qué comando debe iniciar FastAPI?
Usa un comando explícito que escuche en 0.0.0.0 y en el puerto entregado al proceso, ajustando la ruta de importación de tu aplicación.
¿Debo ejecutar migraciones al iniciar cada réplica?
No. Ejecuta la migración una sola vez como fase de publicación para evitar carreras entre réplicas y reinicios repetidos.
¿Cuántos workers necesita una API?
Mídelo con carga real y memoria disponible; cada proceso puede duplicar modelos, cachés y conexiones que mantiene en RAM.