Ir al contenido

Réplica de emergencia: cómo tener tu servidor de casa respaldado en un VPS

Rogelio Guerra Riverón
Autor
Rogelio Guerra Riverón
Construyendo mi propia infraestructura web desde cero. Aquí documento cada paso: servidores, redes, contenedores y lo que vaya surgiendo.

Tener un servidor en casa tiene un punto débil evidente: si se va la luz, el router falla, o el disco muere, tu web desaparece. La solución es tener una réplica en la nube lista para activarse en minutos.

La arquitectura
#

[Italia - servidor casa]  →  rsync cada 6h  →  [Clouding VPS]
  servicios activos                              réplica en espera
  TTL DNS: 5 min                                Uptime Kuma vigilando

El servidor principal (Italia) empuja contenido al VPS cada 6 horas. Si Italia cae, cambio el DNS y en 5 minutos el VPS sirve el sitio.

¿Por qué push y no pull?
#

El servidor de casa está detrás de un router doméstico (Digi). El router solo tiene abiertos los puertos 80 y 443. El VPS no puede conectarse por SSH al servidor de casa directamente.

La solución: Italia empuja al VPS (tiene SSH saliente libre), el VPS solo recibe.

Preparación del VPS
#

El VPS (Clouding, Debian 12, 2 CPUs, 4GB RAM, 30GB disco) ya tenía Docker instalado. Primero, seguridad:

# UFW: solo lo necesario
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable

# Fail2ban SSH
sudo apt-get install -y fail2ban
# /etc/fail2ban/jail.local
[DEFAULT]
bantime  = 7d
findtime = 1h
maxretry = 3
ignoreip = 127.0.0.1/8 79.116.47.67

[sshd]
enabled = true
# SSH: solo clave pública
sudo sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
sudo systemctl reload sshd

Traefik como proxy inverso
#

Mismo Traefik v2.11 que en Italia, con Let’s Encrypt automático:

services:
  traefik:
    image: traefik:v2.11
    command:
      - --providers.docker=true
      - --entrypoints.web.address=:80
      - --entrypoints.websecure.address=:443
      - --certificatesresolvers.letsencrypt.acme.email=serviciosrogeliowar@gmail.com
      - --certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json
    ports:
      - "80:80"
      - "443:443"

Uptime Kuma: monitorización externa
#

El VPS vigila a Italia desde fuera. Si Italia no responde, aviso inmediato por email:

  uptime-kuma:
    image: louislam/uptime-kuma:1
    volumes:
      - ./data:/app/data
    labels:
      - traefik.enable=true
      - traefik.http.routers.uptime.rule=Host(`uptime.serviciosrogeliowar.com`)
      - traefik.http.routers.uptime.entrypoints=websecure
      - traefik.http.routers.uptime.tls.certresolver=letsencrypt

Réplicas en espera
#

Los servicios de web y blog están corriendo en el VPS pero con traefik.enable=false — Traefik los ignora, no son accesibles desde internet. Solo se activan en emergencia:

  web-replica:
    image: nginx:alpine
    labels:
      - traefik.enable=false  # ← cambiar a true en emergencia

Script rsync desde Italia
#

#!/bin/bash
# /home/tellme/CLAUDE/sync-to-clouding.sh
CLOUDING="rogeliowar@85.208.20.73"
SSH_KEY="/home/tellme/.ssh/id_rsa"

rsync -az --delete \
  -e "ssh -i $SSH_KEY -o StrictHostKeyChecking=no" \
  /home/tellme/CLAUDE/blog/public/ \
  ${CLOUDING}:/home/rogeliowar/CLAUDE/blog/public/

rsync -az --delete \
  -e "ssh -i $SSH_KEY -o StrictHostKeyChecking=no" \
  /home/tellme/CLAUDE/web/html/ \
  ${CLOUDING}:/home/rogeliowar/CLAUDE/web/html/

Crontab en Italia:

0 */6 * * * /home/tellme/CLAUDE/sync-to-clouding.sh

Procedimiento de conmutación en emergencia
#

Cuando Italia cae:

  1. Editar en el VPS: cambiar traefik.enable=false a traefik.enable=true en web y blog
  2. docker compose up -d en cada directorio
  3. En el panel DNS, cambiar la A record de serviciosrogeliowar.com de 79.116.47.67 a 85.208.20.73
  4. Con TTL de 5 minutos, en menos de 10 minutos el sitio vuelve

Cuando Italia se recupera, proceso inverso: restaurar DNS, volver a traefik.enable=false en Clouding.

Resultado
#

  • Uptime Kuma vigilando desde fuera en uptime.serviciosrogeliowar.com
  • Rsync automático cada 6 horas — máximo 6 horas de contenido perdido en un fallo
  • Tiempo de recuperación (RTO): ~5 minutos
  • Pérdida máxima de datos (RPO): ~6 horas
  • Coste adicional: solo el VPS de Clouding (ya lo tenía)

Para un servidor doméstico, esta arquitectura es más que suficiente.