← volver al blog
SERVIDORES2026-05-24 · 8 min

Cómo desplegar FastAPI con Nginx, dominio propio y SSL en Ubuntu

El stack completo para llevar una API FastAPI a producción: Uvicorn como servicio systemd, Nginx como reverse proxy, dominio propio y SSL con certbot. Con los errores que más atrasan.

FastAPI corre sobre Uvicorn, un servidor ASGI. En producción no se expone Uvicorn directamente: se pone Nginx delante como reverse proxy. Certbot gestiona el certificado SSL y lo integra al vhost de Nginx automáticamente.

El orden importa: instalar la app, crear un servicio systemd para Uvicorn, configurar Nginx, apuntar el DNS del dominio al servidor, y recién entonces emitir el certificado. Si el DNS no apunta al servidor antes de llamar a certbot, el proceso falla.

Por qué Nginx delante de Uvicorn

Uvicorn puede escuchar en un puerto directamente, pero no está diseñado para quedar expuesto al exterior sin mediación. Nginx termina TLS, maneja conexiones lentas del cliente sin bloquear workers de Uvicorn, y permite múltiples apps en el mismo servidor en distintos dominios. La alternativa de exponer Uvicorn en el 443 directo implica gestionar SSL en la app y perder la capa de buffer.

1. Uvicorn como servicio systemd

Sin systemd, si el proceso muere o el servidor reinicia, la API queda caída. Crear /etc/systemd/system/miapi.service:

[Unit]
Description=FastAPI miapi
After=network.target

[Service]
User=deploy
WorkingDirectory=/home/deploy/miapi
ExecStart=/home/deploy/miapi/venv/bin/uvicorn app:app --host 127.0.0.1 --port 8000
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

El --host 127.0.0.1 es importante: Uvicorn solo escucha en loopback. Si se pone 0.0.0.0 y el firewall tiene el puerto 8000 abierto, la API queda expuesta sin Nginx ni SSL. Activar: systemctl daemon-reload && systemctl enable miapi && systemctl start miapi

2. Nginx como reverse proxy

Crear /etc/nginx/sites-available/miapi. Los headers X-Forwarded-* son necesarios para que FastAPI sepa que el request llegó por HTTPS y desde qué IP real. Sin X-Forwarded-Proto, la app puede generar URLs con http:// aunque el cliente llegó por https://.

server {
    listen 80;
    server_name api.tudominio.com;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
ln -s /etc/nginx/sites-available/miapi /etc/nginx/sites-enabled/
nginx -t
systemctl reload nginx

3. DNS y SSL con Certbot

En el panel de DNS del dominio, crear un registro A apuntando al servidor. Verificar propagación antes de continuar: dig api.tudominio.com +short. No llamar a certbot hasta que el dominio resuelva a la IP correcta — si no apunta, el challenge de Let's Encrypt falla.

certbot --nginx -d api.tudominio.com

Certbot modifica el vhost automáticamente para agregar el bloque HTTPS y la redirección de HTTP a HTTPS. Verificar renovación automática: certbot renew --dry-run.

Errores comunes

Uvicorn en 0.0.0.0 con el puerto 8000 abierto en el firewall: la API queda expuesta sin pasar por Nginx ni SSL. Usar 127.0.0.1 en el service y cerrar el puerto: ufw deny 8000.

Certbot falla con "Could not bind to IPv4 or IPv6": el puerto 80 está ocupado. Verificar con ss -tlnp | grep :80.

FastAPI devuelve URLs con http:// aunque el cliente llegó por HTTPS: faltan los headers X-Forwarded-Proto en el vhost de Nginx. El servicio systemd no arranca: revisar con journalctl -u miapi -n 50. Causas comunes: ruta del venv incorrecta, WorkingDirectory que no existe, usuario sin permisos.

Escrito por el equipo de Lanzamiento Digital · 2026-05-24
seguir leyendo

¿Tu proyecto encaja?

Hablemos. Treinta minutos, sin compromiso, sin presentación.

Respuesta en menos de 24 horas