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
#

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

El servidor de casa empuja contenido al VPS cada 6 horas. Si el servidor 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: el servidor de casa empuja al VPS (tiene SSH saliente libre), el VPS solo recibe.

Preparación del VPS
#

El VPS (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 <IP_PUBLICA_CASA>

[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 el servidor de casa, 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=tu@email.com
      - --certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json
    ports:
      - "80:80"
      - "443:443"

Uptime Kuma: monitorización externa
#

Uptime Kuma vigila al servidor de casa desde fuera. Si 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 el servidor de casa
#

#!/bin/bash
# ~/infra/sync-to-vps.sh
VPS="usuario@<IP_PUBLICA_VPS>"
SSH_KEY="~/.ssh/id_ed25519"

rsync -az --delete \
  -e "ssh -i $SSH_KEY -o StrictHostKeyChecking=no" \
  ~/infra/blog/public/ \
  ${VPS}:~/infra/blog/public/

rsync -az --delete \
  -e "ssh -i $SSH_KEY -o StrictHostKeyChecking=no" \
  ~/infra/web/html/ \
  ${VPS}:~/infra/web/html/

Crontab en el servidor de casa:

0 */6 * * * ~/infra/sync-to-vps.sh

Procedimiento de conmutación en emergencia
#

Cuando el servidor de casa 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 tu dominio de la IP del servidor de casa a la IP del VPS
  4. Con TTL de 5 minutos, en menos de 10 minutos el sitio vuelve

Cuando el servidor de casa se recupera, proceso inverso: restaurar DNS, volver a traefik.enable=false en el VPS.

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 (ya lo tenía)

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


Equipamiento recomendado
#

Enlaces de afiliado. Sin coste extra para ti.