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 vigilandoEl 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 sshdTraefik 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=letsencryptRé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 emergenciaScript 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.shProcedimiento de conmutación en emergencia#
Cuando Italia cae:
- Editar en el VPS: cambiar
traefik.enable=falseatraefik.enable=trueen web y blog docker compose up -den cada directorio- En el panel DNS, cambiar la A record de
serviciosrogeliowar.comde79.116.47.67a85.208.20.73 - 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.