Juan Diego Andrés PRADA··RAMÍREZ Entrar
Lección 5 de 7

Despliegue: servidores, Nginx, dominios y SSL

¿Qué es?

Desplegar es poner tu aplicación a correr en una máquina accesible desde internet, con un nombre legible (un dominio) y cifrado (SSL/HTTPS). Para lograrlo combinamos cuatro piezas: un servidor (una máquina virtual en la nube, lo que llaman VPS), un proxy inverso (Nginx, que recibe el tráfico de internet y lo pasa a tu contenedor), un dominio (que apunta a la IP del servidor) y un certificado SSL (que habilita el candado de HTTPS).

¿Cómo funciona?

Cuando alguien escribe https://mi-api.com en su navegador, ocurre esto en orden:

  1. El DNS traduce mi-api.com a la IP de tu servidor.
  2. La petición llega al servidor por el puerto 443 (HTTPS), donde escucha Nginx.
  3. Nginx termina el cifrado SSL y reenvía la petición a tu contenedor Docker, que escucha internamente en el puerto 8000.
  4. La API responde, Nginx vuelve a cifrar la respuesta y la devuelve al navegador.

Nginx actúa de portero: tu contenedor nunca queda expuesto directamente a internet. El certificado SSL lo emite gratis Let's Encrypt, y una herramienta llamada Certbot lo solicita y lo renueva automáticamente.

¿Para qué sirve?

Sirve para que tu herramienta deje de vivir solo en tu portátil y cualquiera pueda usarla, de forma segura y con una URL profesional. Es la culminación del despliegue: aquí toman forma todas las piezas anteriores. El servidor descarga la imagen que tu pipeline de CI/CD publicó, la corre con Docker Compose, y Nginx la expone con tu dominio y candado verde.

Pieza del despliegue que construye este módulo

Configuramos el servidor de producción completo: instalamos Docker, traemos la imagen del registro, la levantamos, ponemos Nginx como proxy inverso y emitimos el certificado SSL. Además, automatizamos el despliegue desde GitHub Actions vía SSH.

Paso 1: prepara el servidor (VPS Ubuntu)

# Conéctate por SSH (reemplaza con la IP de tu servidor)
ssh root@TU_IP_DEL_SERVIDOR

# Actualiza e instala Docker y Compose
apt update && apt upgrade -y
curl -fsSL https://get.docker.com | sh
apt install -y docker-compose-plugin nginx certbot python3-certbot-nginx

# Crea un usuario sin privilegios para desplegar (no uses root para todo)
adduser deploy && usermod -aG docker deploy

Paso 2: trae y levanta la imagen

# Inicia sesión en el registro y descarga la imagen que publicó CI/CD
docker login ghcr.io -u TU_USUARIO
docker pull ghcr.io/tu-usuario/mi-api:latest
# docker-compose.prod.yml (en el servidor, carpeta /home/deploy/mi-api)
services:
 api:
 image: ghcr.io/tu-usuario/mi-api:latest
 ports:
 - "127.0.0.1:8000:8000" # solo accesible localmente; Nginx será la puerta
 restart: unless-stopped
docker compose -f docker-compose.prod.yml up -d

Fíjate en 127.0.0.1:8000:8000. Sin ese 127.0.0.1, el puerto 8000 quedaría abierto a todo internet, saltándose Nginx y el SSL. Es un error de seguridad grave y muy común.

Paso 3: Nginx como proxy inverso

# /etc/nginx/sites-available/mi-api
server {
 listen 80;
 server_name mi-api.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/mi-api /etc/nginx/sites-enabled/
nginx -t # verifica que la configuración no tenga errores
systemctl reload nginx

Paso 4: dominio y SSL

Primero, en el panel de tu proveedor de dominio, crea un registro A que apunte mi-api.com a la IP de tu servidor. Luego:

certbot --nginx -d mi-api.com # emite el certificado y reconfigura Nginx a HTTPS

Certbot edita tu configuración para redirigir HTTP a HTTPS y programa la renovación automática. Verifícala con certbot renew --dry-run.

Comprueba que la renovación automática quedó activa: systemctl status certbot.timer. Los certificados de Let's Encrypt duran 90 días; sin la renovación, tu sitio se caería al expirar.

Paso 5: despliegue automático desde CI/CD

Añade este job al final de tu cd.yml para que, tras publicar la imagen, el servidor la actualice solo:

 desplegar:
 needs: construir-y-publicar
 runs-on: ubuntu-latest
 steps:
 - name: Desplegar por SSH
 uses: appleboy/ssh-action@v1
 with:
 host: ${{ secrets.SERVER_HOST }}
 username: deploy
 key: ${{ secrets.SSH_PRIVATE_KEY }}
 script: |
 cd /home/deploy/mi-api
 docker compose -f docker-compose.prod.yml pull
 docker compose -f docker-compose.prod.yml up -d
 docker image prune -f

Tech English: reverse proxy = proxy inverso; VPS = servidor virtual privado; to provision = aprovisionar/preparar un servidor; DNS record = registro DNS; to issue a certificate = emitir un certificado.

Ejercicios

  1. Despliegue end-to-end. Lleva la API a un VPS real (o uno local con IP), con Nginx y SSL, accesible en https://tu-dominio. Documenta cada comando en un DESPLIEGUE.md. Se evalúa que la URL responda con candado válido y que curl https://tu-dominio/saludo devuelva el JSON.

  2. Despliegue por push. Configura el job de despliegue por SSH con secretos. Haz un cambio trivial, súbelo a main y demuestra que el servidor sirve la nueva versión sin que tú entres por SSH manualmente. Se evalúa que el despliegue ocurra completamente automático tras el push.

Tu progreso se guarda en este navegador. Inicia sesión para guardarlo en tu cuenta y verlo desde cualquier dispositivo.