Introducción: Encajando la última pieza del rompecabezas

¡Hola! Finalmente, estamos en el último episodio de esta larga serie. En los primeros 4 episodios, comenzamos con la teoría del sistema de despliegue automático, implementamos la lógica básica del servidor de webhook de FastAPI y establecimos un entorno operativo confiable mediante un servicio de Systemd.

Puedes consultar las publicaciones anteriores en esta serie a través de los siguientes enlaces.

① ¿Por qué implementarlo uno mismo?

② Diseño de la arquitectura completa y del proceso

③ Configuración del entorno del servidor de staging y construcción básica del servidor de webhook de FastAPI

④ Detalles del manejador de despliegue y registro del servicio de Systemd

Sin embargo, aún queda un paso. Actualmente, nuestro servidor de webhook de FastAPI solo funciona en el puerto 8000 y no utiliza HTTPS, lo que lo hace vulnerable a problemas de seguridad. Además, GitHub recomienda encarecidamente el uso de un dominio público y conexiones HTTPS.

En este quinto episodio, finalizaremos el sistema encajando las últimas piezas del rompecabezas. Configuraremos Nginx como un proxy inverso para exponer el servidor FastAPI de manera segura al exterior, aplicaremos HTTPS gratuito a través de Let's Encrypt, y finalmente, integrar GitHub Webhook para completar el sistema de despliegue automático.

Un momento, ¿por qué Nginx y no Apache2? Apache2 y Nginx son excelentes servidores web que dominan el mercado de programas de servidor. Sin embargo, los marcos web asíncronos como FastAPI muestran una mejor compatibilidad con Nginx. Nginx está diseñado con un enfoque basado en eventos asíncronos, lo que permite aprovechar al máximo el rendimiento asíncrono de FastAPI en un entorno de altas conexiones simultáneas. Por esta razón, la comunidad de FastAPI recomienda encarecidamente Nginx como el servidor web para entornos de producción, y este artículo se centra en Nginx.

Instalación de Nginx y configuración del proxy inverso

¿Por qué deberíamos usar Nginx?

  1. Proxy inverso: Servidores de aplicaciones como FastAPI no están destinados a recibir tráfico externo directamente. Nginx actúa como un proxy inverso que recibe las solicitudes de webhook y las transmite de manera segura al servidor de FastAPI.

  2. Seguridad: Nginx ofrece varias configuraciones de seguridad y funciones de defensa contra ataques DDoS.

  3. Aplicación de HTTPS: La gestión y aplicación de certificados HTTPS son funciones que desempeña un servidor web como Nginx.

Instalación y configuración de Nginx

Conéctate al servidor de staging a través de SSH e instala Nginx. Presuponemos que los lectores que están leyendo este artículo ya tienen cierta experiencia y conocimiento sobre Nginx, así que omitiremos una explicación detallada sobre cómo instalar, la estructura de archivos o los principios de funcionamiento de Nginx.

sudo apt update
sudo apt install -y nginx
sudo systemctl enable nginx # Iniciar automáticamente al reiniciar
sudo systemctl start nginx # Iniciar nginx
sudo systemctl status nginx # Verificar estado activo

Ahora escribiremos el archivo de configuración de Nginx para pasar las solicitudes a nuestro servidor de webhook de FastAPI. Supongamos que usamos el dominio deployer.example.com. Aquí hay un ejemplo de configuración.

#/etc/nginx/sites-available/deployer.example.com

# Redirección 308 de HTTP a HTTPS
server {
    listen 80;
    server_name deployer.example.com;
    return 308 https://$host$request_uri;
}

# Procesamiento de solicitudes HTTPS
server {
    listen 443 ssl;
    server_name deployer.example.com;

    # Configuración de la ruta del certificado SSL
    ssl_certificate /etc/letsencrypt/live/deployer.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/deployer.example.com/privkey.pem;
    ssl_session_cache shared:SSL:1m;
    ssl_session_timeout 5m;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_protocols TLSv1.2 TLSv1.3;

    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;
        proxy_redirect off;
    }
}

  • Configuración del puerto 80 HTTP: El bloque listen 80 que tiene server_name igual a deployer.example.com redirige permanentemente todas las solicitudes HTTP entrantes a HTTPS a través de return 308 https://$host$request_uri;.

  • Configuración del puerto 443 HTTPS: El bloque listen 443 ssl; procesa las solicitudes HTTPS.

  • ssl_certificate & ssl_certificate_key: Asumiendo que ya se ha emitido a través de Let's Encrypt, este bloque especifica la ruta del certificado SSL otorgado y del archivo de clave. Esta ruta es generada automáticamente por certbot al emitir el certificado.

  • Bloque location /: Configura el proxy inverso para transmitir las solicitudes convertidas a HTTPS a nuestro servidor FastAPI (http://127.0.0.1:8000).

Al reiniciar Nginx con este archivo de configuración, todas las solicitudes de webhook se manejarán de manera segura a través de HTTPS.

# Crear un enlace simbólico al archivo de configuración en el directorio sites-enabled
sudo ln -s /etc/nginx/sites-available/deployer.example.com /etc/nginx/sites-enabled/

# Verificar errores de sintaxis en el archivo de configuración de Nginx.
sudo nginx -t

# Reiniciar Nginx para aplicar los cambios.
sudo systemctl restart nginx

Aplicación de HTTPS (Let's Encrypt + Certbot)

GitHub Webhook recomienda encarecidamente comunicaciones HTTPS por razones de seguridad. Let's Encrypt es una autoridad de certificación sin fines de lucro que permite a cualquiera obtener certificados SSL/TLS de forma gratuita, y Certbot es una excelente herramienta que automatiza la emisión y renovación de certificados. Aquí omitiremos cómo instalarlas.

Una vez completado con éxito, accede desde tu navegador a https://deployer.example.com para ver la documentación de la API de FastAPI (.../docs) o el endpoint /. Si ves el mensaje ¡Servidor de webhook en funcionamiento!, significa que la configuración de Nginx y HTTPS se ha completado exitosamente.

Integración final de GitHub Webhook y pruebas

Ahora todo está listo. Conectemos el sistema de despliegue automático que hemos desarrollado al repositorio de GitHub.

  1. Acceso al repositorio de GitHub: Navega al repositorio de GitHub del proyecto al que aplicarás el despliegue automático.

  2. Configuración de Webhooks: En el menú superior, haz clic en Settings -> en el menú de la izquierda, haz clic en Webhooks.

  3. Agregar Webhook: Haz clic en el botón Add webhook y completa la siguiente información.

    • Payload URL: Ingresa la dirección del servidor webhook con Nginx y HTTPS aplicados. (Ej: https://deployer.example.com/webhook)

    • Content type: Selecciona application/json.

    • Secret: Copia y pega con precisión el valor de GITHUB_WEBHOOK_SECRET que configuraste en el archivo ~/projects/webhook_server/.env en el tercer episodio.

    • ¿Qué eventos te gustaría que activaran este webhook?: Selecciona Just the push event.

    • Active: Asegúrate de que la casilla de verificación esté activada.

  4. Guardar: Haz clic en el botón Add webhook para guardar el webhook.

Captura de pantalla de la configuración de GitHub Webhook

Si el webhook se ha registrado correctamente, aparecerá una marca de verificación verde en la sección Recent Deliveries, confirmando que la solicitud de prueba se ha enviado con éxito.

Ahora realicemos la prueba final.

  1. Modificar código localmente: Realiza algunos cambios en el código del proyecto y haz un commit y push en Git.

  2. Verificación del estado:

    • Verifica en la página de configuración de GitHub Webhook en Recent Deliveries si el webhook del último push fue exitoso (marca de verificación verde).

    • Conéctate al servidor de staging a través de SSH y utiliza el comando sudo journalctl -u github-webhook-deployer.service -f para verificar los registros en tiempo real. Si ves mensajes como Git pull successful, Deployment task finished, has tenido éxito.

    • Verifica el estado del contenedor Docker desplegado para asegurarte de que el código más reciente se haya aplicado.

Conclusión: ¡Sistema de despliegue automático completado!

¡Felicidades! Has construido con éxito un pipeline completo de CI/CD que abarca desde un entorno de desarrollo local hasta GitHub y un servidor de staging auto-implementado.

A través de esta serie, hemos logrado lo siguiente:

  • Hemos entendido por qué es importante construir un sistema de despliegue automático basado en webhooks por nosotros mismos.

  • Hemos diseñado e implementado la arquitectura del servidor de webhook usando FastAPI.

  • Hemos aprendido cómo operar un servicio de manera confiable utilizando Systemd.

  • Hemos reforzado la seguridad mediante la configuración de Nginx y HTTPS.

  • Finalmente, hemos automatizado todo el proceso integrándolo con GitHub.

Ahora, cada vez que presiones el botón de push, tu servidor implementará automáticamente el código más reciente, sin que tengas que intervenir. Basándote en este sistema, experimenta añadiendo lógicas de despliegue más complejas o integrando funciones de notificación a tu manera.

¡Gracias por acompañarnos en este largo viaje!