Despliega tu Portafolio Web Localmente en Minutos con Vagrant, Nginx y sslip.io

Rossana SuarezRossana Suarez
8 min read

Configurar un entorno de desarrollo local es complicado. Desde lidiar con configuraciones complejas hasta enfrentarse a certificados que el navegador rechaza, la mayoría de nosotros ha pasado por ello. Pero, ¿y si te dijera que puedes hacer todo mucho más fácil?

En este post, te mostraré cómo desplegar tu portafolio web localmente, sin complicaciones y en solo unos minutos, utilizando Vagrant, Nginx y sslip.io. Olvídate de las configuraciones interminables y empieza a trabajar de forma rápida y eficiente.

Arquitectura Local para Portafolio Web con Vagrant + Nginx

Descripción del flujo:

  1. Vagrant gestionará la creación de la máquina virtual, con un entorno basado en Ubuntu.

  2. Nginx servirá el portafolio web estático. Este se colocará en el directorio /var/www/portfolio y será accesible mediante el subdominio proporcionado por sslip.io (ej. 192.168.56.10.sslip.io).

  3. El proceso de aprovisionamiento automatizado mediante Vagrant garantizará que el entorno de desarrollo se configure rápidamente.


El Portafolio web

Este portafolio DevOps está construido utilizando HTML5, CSS3 y JavaScript (vanilla), y está diseñado para mostrar tus habilidades en la implementación de un entorno de desarrollo local. Usando Vagrant, puedes levantar una máquina virtual que ejecuta Nginx para servir tu portafolio web estático de manera eficiente. Con sslip.io, asignas un dominio dinámico a tu entorno local. Este enfoque simplifica la configuración y te permite enfocarte en lo que realmente importa: ¡tu portafolio!

Imagen


¿Qué es Nginx y cómo funciona?

Nginx es un servidor web de alto rendimiento que también puede funcionar como proxy inverso, balanceador de carga, servidor de correo y caché HTTP. Su arquitectura basada en eventos lo hace especialmente eficiente en el manejo de múltiples conexiones simultáneas, lo que lo convierte en una opción popular para servir aplicaciones web modernas.

Una de sus principales ventajas es su eficiencia al manejar tráfico concurrente. A diferencia de servidores tradicionales como Apache, Nginx usa un enfoque asincrónico para manejar las conexiones. Esto significa que, en lugar de abrir un nuevo hilo para cada solicitud, Nginx usa un solo hilo para manejar miles de conexiones, lo que mejora el rendimiento y la escalabilidad.

¿Qué es sslip.io?

sslip.io es un servicio gratuito que permite asignar un dominio dinámico a una dirección IP local. Esto es útil para desarrolladores que quieren exponer su entorno local a Internet sin tener que configurar un servidor DNS completo. Con sslip.io, simplemente añades una cadena de texto en tu dirección IP local (como .sslip.io) y el dominio se resuelve automáticamente a la dirección IP que especificas.

Además, sslip.io incluye certificados SSL válidos para cada subdominio generado, lo que te permite probar aplicaciones locales de forma segura sin tener que lidiar con certificados autofirmados. En resumen, sslip.io resuelve las direcciones locales de manera eficiente y segura, haciendo que el desarrollo sea mucho más rápido.

Estos servicios geniales resuelven automáticamente cualquier subdominio a la IP que especifiques:

# Ejemplos de resolución automática
192.168.1.100.sslip.io → 192.168.1.100
localhost.sslip.io → 127.0.0.1
10.0.0.5.nip.io → 10.0.0.5

Lo mejor: incluyen certificados SSL válidos sin configuración adicional.


Configurando el entorno con Vagrant

1. Instalar Vagrant y VirtualBox

2. Verificar la instalación

Una vez instalados Vagrant y VirtualBox, puedes verificar que todo esté funcionando correctamente ejecutando:

vagrant --version

Deberías ver la versión instalada de Vagrant en la salida. Si también tienes VirtualBox instalado, puedes verificarlo ejecutando:

vboxmanage --version

3. Crear y configurar la máquina virtual

Ahora que tienes Vagrant y VirtualBox instalados, puedes crear y configurar tu máquina virtual para el portafolio web.


Configuración del Vagrantfile

Primero, creamos nuestro Vagrantfile:

# -*- mode: ruby -*-
# vi: set ft=ruby :

# 🚀 HTTP Local con sslip.io + Nginx + Vagrant
# 📝 Blog: Desarrollo local
# 🎯 Objetivo: Demostrar cómo usar sslip.io para HTTP local sin complicaciones
# 🔗 Acceso: http://192.168.56.10.sslip.io

Vagrant.configure("2") do |config|
  # 📦 Box base: Ubuntu 24.04 LTS compatible con mac soporta amd64/arm64
  config.vm.box = "bento/ubuntu-24.04"
  config.vm.box_check_update = true
  config.vm.hostname = "portafolio-ssl-local"

  # 🌐 Configuración de red
  # IP privada para acceso directo desde el host
  config.vm.network "private_network", ip: "192.168.56.10"
  config.vm.network "forwarded_port", guest: 80, host: 8080, 
    auto_correct: true, id: "http"

  # 💻 Configuración del proveedor VirtualBox
  config.vm.provider "virtualbox" do |vb|
    vb.name = "devops-local"
    vb.memory = "1024"  
    vb.cpus = 2
  end

  # 🚀 Aprovisionamiento principal
  config.vm.provision "shell", path: "provision.sh", privileged: true

  # 📋 Mensaje de bienvenida post-instalación
  config.vm.provision "shell", inline: <<-SHELL
    echo ""
    echo "🎉 ¡Configuración completada exitosamente!"
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    echo "💼 Portafolio Web disponible en:"
    echo "   🔗 http://192.168.56.10.sslip.io"
    echo ""
    echo ""
    echo "📝 HTTP Local con sslip.io"
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    echo ""
  SHELL
end
💡
Podes revisar el catalogo de Boxes de Vagrant disponible, recuerda revisar proveedor y arquitectura ya sea arm64 o amd64 https://portal.cloud.hashicorp.com/vagrant/discover

Script de aprovisionamiento

Creamos provision.sh para automatizar toda la configuración:

#!/bin/bash

# Simple Local Development with sslip.io + Nginx + Vagrant
# HTTP-only setup for fast and simple local development
# Objective: Deploy web portfolio with sslip.io domain (HTTP only)

set -euo pipefail  # Exit on any error

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# Function to show progress
show_progress() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

# Function to show success
show_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

# Function to show warnings
show_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

# Function to show errors
show_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# Welcome banner
echo -e "${GREEN}"
echo "=================================================================="
echo "                                                                  "
echo "          Simple Local Development with sslip.io                 "
echo "                                                                  "
echo "    HTTP + Nginx + Vagrant = Quick Development Setup             "
echo "                                                                  "
echo "=================================================================="
echo -e "${NC}"

# Verify if it's Ubuntu
if ! grep -q "Ubuntu" /etc/os-release; then
    show_error "This script is designed for Ubuntu. Exiting..."
    exit 1
fi

show_progress "Updating Ubuntu system"
export DEBIAN_FRONTEND=noninteractive
apt-get update -qq
show_success "System updated successfully"

show_progress "Installing essential dependencies"
apt-get install -y -qq \
    nginx \
    curl \
    wget \
    git \
    unzip \
    htop \
    tree \
    net-tools
show_success "Dependencies installed"

show_progress "Setting up web directory"
WEB_ROOT="/var/www/portfolio"
mkdir -p "$WEB_ROOT"
chown -R www-data:www-data "$WEB_ROOT"
chmod -R 755 "$WEB_ROOT"


# Descarga y descomprime el portafolio web desde GitHub
download_and_extract_portfolio() {
    local ZIP_URL="https://github.com/roxsross/devops-static-web/raw/portafolio-web/portafolio-web.zip"
    local TMP_ZIP="/tmp/portfolio.zip"

    show_progress "Descargando portafolio web desde GitHub..."
    if curl -L --fail -o "$TMP_ZIP" "$ZIP_URL"; then
        show_success "ZIP descargado correctamente."
        show_progress "Descomprimiendo portafolio en $WEB_ROOT..."
        if unzip -o "$TMP_ZIP" -d "$WEB_ROOT"; then
            show_success "Portafolio descomprimido en $WEB_ROOT."
            local SUBDIR=$(find "$WEB_ROOT" -mindepth 1 -maxdepth 1 -type d | head -n1)
            if [ -d "$SUBDIR" ] && [ "$SUBDIR" != "$WEB_ROOT" ]; then
                mv "$SUBDIR"/* "$WEB_ROOT"/
                rmdir "$SUBDIR"
            fi
        else
            show_error "Error al descomprimir el portafolio. Se dejará el directorio vacío."
            rm -rf "$WEB_ROOT"/*
        fi
        rm -f "$TMP_ZIP"
    else
        show_error "No se pudo descargar el portafolio. Se creará un index.html de emergencia."
        echo "<html><body><h1>Error: No se pudo descargar el portafolio web.</h1></body></html>" > "$WEB_ROOT/index.html"
    fi
}

download_and_extract_portfolio

chown -R www-data:www-data "$WEB_ROOT"
find "$WEB_ROOT" -type f -exec chmod 644 {} \;
find "$WEB_ROOT" -type d -exec chmod 755 {} \;

show_progress "Configuring Nginx"

cat > /etc/nginx/sites-available/portfolio << 'EOF'
server {
    listen 80;
    server_name *.sslip.io sslip.io *.192.168.56.10.sslip.io 192.168.56.10.sslip.io;

    root /var/www/portfolio;
    index index.html index.htm;

    # Basic security headers
    add_header X-Frame-Options DENY always;
    add_header X-Content-Type-Options nosniff always;
    add_header X-XSS-Protection "1; mode=block" always;

    # Gzip compression
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_types
        text/plain
        text/css
        text/xml
        text/javascript
        application/javascript
        application/xml+rss
        application/json;

    location / {
        try_files $uri $uri/ =404;
    }

    # Static files caching
    location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2|ttf|svg)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }

    # Security
    location ~ /\. {
        deny all;
    }
}
EOF


ln -sf /etc/nginx/sites-available/portfolio /etc/nginx/sites-enabled/
rm -f /etc/nginx/sites-enabled/default


if nginx -t; then
    show_success "Nginx configuration is valid"
else
    show_error "Nginx configuration has errors"
    exit 1
fi


systemctl restart nginx
systemctl enable nginx

show_progress "Setting up firewall rules"
ufw allow 22/tcp
ufw allow 80/tcp
ufw --force enable

VM_IP="192.168.56.10"
SSLIP_DOMAIN="${VM_IP}.sslip.io"

show_progress "Verifying installation"

sleep 3

# Test HTTP
if curl -s -o /dev/null -w "%{http_code}" "http://${SSLIP_DOMAIN}" | grep -q "200"; then
    show_success "HTTP site is responding correctly"
else
    show_warning "HTTP site might not be responding correctly"
fi

echo ""
echo -e "${GREEN}"
echo "=================================================================="
echo "                                                                  "
echo "             🚀 DEPLOY LISTO! 🚀                                  "
echo "                                                                  "
echo "  🌐 Sitio de desarrollo simple listo                             "
echo "  🔗 HTTP + dominio sslip.io configurado                          "
echo "                                                                  "
echo "=================================================================="
echo -e "${NC}"

echo -e "${BLUE}"
echo "📋 Access Guide:"
echo ""
echo "🌐 Site URL: http://${SSLIP_DOMAIN}"
echo "📝 VM IP: $VM_IP"
echo "🔗 sslip.io domain: $SSLIP_DOMAIN"
echo ""
echo "💡 Features:"
echo "• Simple HTTP setup"
echo "• No SSL complexity"
echo "• sslip.io automatic domain mapping"
echo "• Ready for immediate development"
echo -e "${NC}"

show_success "Simple development environment ready!"

Ejemplo práctico: Desplegando el Portafolio

Para hacer esto más divertido, vamos a desplegar el portafolio devops

Desplegando el entorno

# Clonar o crear los archivos
mkdir vagrant-https-demo
cd vagrant-https-demo

# Crear archivos Vagrantfile y provision.sh
# (copiar contenido de arriba)

# Levantar la VM
vagrant up

# Verificar estado
vagrant status

Verificación y pruebas

Una vez desplegado, puedes probar:

# Desde tu máquina host - Acceder al juego
open http://192.168.56.10.sslip.io

Ventajas de este enfoque

Para DevOps:

  • Infraestructura como código con Vagrant

  • Aprovisionamiento automático repetible

  • Entorno aislado que no afecta tu máquina

  • Fácil destrucción y recreación (vagrant destroy && vagrant up)


Limpieza y comandos útiles

bash# Ver logs de Nginx
vagrant ssh -c "sudo tail -f /var/log/nginx/error.log"

# Reiniciar servicios
vagrant ssh -c "sudo systemctl restart nginx"

# Destruir entorno
vagrant destroy -f

Conclusión

Configurar un entorno de desarrollo local para tu portafolio web no tiene por qué ser complicado. Con Vagrant, Nginx y sslip.io, puedes levantar un servidor local funcional en cuestión de minutos, sin preocuparte por configuraciones complejas. Este flujo te permite concentrarte en lo que realmente importa: ¡tu proyecto!

Recuerda que la automatización y la reutilización de entornos es clave para mantener tu desarrollo ágil y eficiente. Con herramientas como Vagrant y Nginx, puedes replicar fácilmente tu configuración en cualquier máquina y compartir tu trabajo con otros sin problemas.

Si quieres seguir aprendiendo y profundizando en DevOps, te invito a unirte a mi Reto 90 Días de DevOps con Roxs, donde exploraremos aún más herramientas y prácticas que te ayudarán a llevar tus habilidades al siguiente nivel. ¡Nos vemos en el camino hacia un futuro DevOps más eficiente!


🤘 ¡Nos vemos en el próximo experimento DevOps!

0
Subscribe to my newsletter

Read articles from Rossana Suarez directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Rossana Suarez
Rossana Suarez

Soy Roxs 👩‍💻| Software Developer | DevOps | DevSecOps | en @295DevOps 🖼 Content Creator. No se puede crecer si no estas dispuesto a saltar a la zona de peligro 🔥