Self-hosting sin miedo: cómo Cloudflare sostiene mi Mac mini casero

Self-hosting sin miedo: cómo Cloudflare sostiene mi Mac mini casero

Esta web no vive en ningún hosting. Vive en un Mac mini que tengo en casa, debajo de la mesa, sirviendo con Apache no solo sergiocomeron.com, sino también el aula de Moodle, el Jitsi y algún proyecto más.

Autoalojar tiene algo adictivo: control total, cero facturas mensuales de hosting, y cacharrear con tu propia infraestructura. Pero tiene un talón de Aquiles que un hosting tradicional no sufre: si se va la luz en casa, o se cae internet, la web se cae conmigo. Cuando lo comparé con otra web que tenía alojada en un servicio de hosting, ahí salía perdiendo.

Así que en vez de rendirme, me puse a resolver los problemas del autoalojado casero uno por uno. Y resulta que casi todos los resuelve la misma pieza: Cloudflare. Esto es lo que uso de verdad.

El problema de fondo: una casa no es un datacenter

Servir desde casa tiene tres pegas serias:

  1. IP dinámica: mi operador me cambia la IP pública cada cierto tiempo. Si el DNS apunta a una IP que ya no es la mía, la web desaparece.
  2. Abrir puertos: para que internet llegue a mi Apache, en teoría tengo que abrir puertos en el router y exponer mi red doméstica al mundo. Poco apetecible.
  3. Caídas: cortes de luz, reinicios, el router que se cuelga. En casa pasa.

Vamos con cómo cae cada una.

DNS + proxy: la nube naranja

Lo primero es poner el dominio en Cloudflare y activar el proxy (el famoso icono de nube naranja). Con eso, cuando alguien entra en sergiocomeron.com no habla con mi casa directamente: habla con Cloudflare, y Cloudflare habla conmigo.

Ventajas inmediatas y gratis:

  • SSL/HTTPS sin tener que renovar certificados a mano.
  • Mi IP de casa queda oculta: nadie ve la IP real de mi router.
  • Mitigación de ataques y un CDN global que cachea contenido estático cerca del visitante.

El “antes” de mi setup vivía aquí: tenía un pequeño script (cloudflare-ddns.sh) que cada cinco minutos comprobaba mi IP pública y, si había cambiado, actualizaba el registro A en Cloudflare por API. Un DDNS casero. Funcionaba, pero seguía dependiendo de abrir puertos. El siguiente paso lo hizo innecesario.

Cloudflare Tunnel: cero puertos abiertos

Aquí está el cambio que más tranquilo me dejó. Cloudflare Tunnel le da la vuelta al modelo: en lugar de abrir puertos para que internet entre en mi casa, instalo un pequeño demonio (cloudflared) que abre una conexión saliente hacia Cloudflare y la mantiene. Todo el tráfico entra por ese túnel.

Consecuencias:

  • No abro ni un solo puerto en el router. Mi red doméstica deja de estar expuesta.
  • Mi IP de casa ya ni aparece en el DNS: los registros son CNAME al túnel, no un A a mi IP. El DDNS sobra.
  • Lo configuro en un config.yml declarando qué subdominio va a qué servicio local:
1ingress:
2  - hostname: sergiocomeron.com
3    service: http://localhost:80
4  - hostname: meet.sergiocomeron.com
5    service: http://localhost:80
6  - hostname: aula.sergiocomeron.com
7    service: http://localhost:80
8  - service: http_status:404

Cada hostname apunta a mi Apache en localhost:80. Cloudflare se encarga del resto. Pasar de “DDNS + puertos abiertos” a “un túnel de salida y nada expuesto” es, de lejos, lo mejor que le he hecho a este montaje.

Always Online: la red de seguridad

Queda el talón de Aquiles: ¿y si se va la luz? El Mac mini se apaga, el túnel cae, y mi origen deja de responder. En un hosting esto no pasa; en mi salón, sí.

Para eso existe Always Online. Cloudflare guarda una copia cacheada de las páginas de tu sitio y, si tu origen no responde, sirve esa copia en lugar de mostrar un error. El visitante ve la web (una versión estática, eso sí) aunque mi Mac mini esté apagado.

Y aquí tengo suerte: esta web es casi todo contenido estático. La portada, el blog y la mayoría de mis herramientas funcionan directamente en el navegador, sin servidor. Lo único realmente dinámico son cosas puntuales como el formulario de contacto. Así que esa copia estática es, en la práctica, casi la web entera: lo que pierdo mientras el origen está caído es mínimo. Para un sitio así, Always Online no es un apaño, es una solución de verdad.

Seré honesto: no la he tenido que estrenar en un apagón real —y ojalá siga así—. Pero es exactamente la pieza que le faltaba al autoalojado casero para que un corte de luz no signifique “web caída”. La activé el día que me di cuenta de que ese era mi mayor punto débil frente a un hosting. Es mi seguro, y es gratis.

Cache Rules: rendimiento (y una lección reciente)

Cloudflare cachea contenido por defecto, lo cual está muy bien para imágenes, CSS y JS. Pero el caché no siempre es tu amigo, y lo aprendí hace nada.

Monté analíticas para saber cuántas veces se descargan los episodios de mi podcast, contando las peticiones a los .mp3 en los logs de Apache. Los números salían bajísimos. ¿El motivo? Cloudflare estaba cacheando los audios y sirviéndolos desde su edge, así que la mayoría de las descargas nunca llegaban a mi servidor… ni a mis logs.

La solución fueron las Cache Rules: una regla que le dice a Cloudflare “para las rutas de los audios del podcast, no caches, ve siempre al origen” (bypass). Desde entonces cada descarga pasa por Apache y el contador es real. Moraleja: el caché es potentísimo, pero hay que saber dónde no quererlo.

La IP real de quien te visita

Meter Cloudflare por delante tiene un efecto colateral que descoloca al principio: tus logs se llenan de IPs de Cloudflare, no de las de tus visitantes. Es lógico, porque quien habla con mi Apache es Cloudflare, no el navegador del usuario.

La solución es el módulo mod_remoteip de Apache más una cabecera que Cloudflare añade a cada petición, CF-Connecting-IP, con la IP original. Con esto Apache “recupera” la IP real del visitante y la escribe en los logs:

1RemoteIPHeader CF-Connecting-IP
2RemoteIPTrustedProxy 127.0.0.1 ::1

Sin esto, cualquier analítica que saques de los logs —visitas, países, las propias descargas del podcast de antes— estaría midiendo a Cloudflare en lugar de a la gente. Un detalle pequeño con un impacto enorme en los datos.

Saber cuándo algo falla

Cloudflare mantiene la web en pie y Always Online cubre las caídas, pero “sin miedo” de verdad es enterarme antes que nadie de que algo va mal. Para eso tengo un puñado de scripts que corren por cron y vigilan cosas distintas: que la web responda, el estado de Cloudflare, la carga del Mac mini, intentos de acceso sospechosos, el espacio en disco…

Si algo se sale de lo normal, me llega un aviso a Telegram al instante. Y para revisar el histórico monté un pequeño panel propio donde veo visitas, eventos y alertas de un vistazo. No es de Cloudflare —es casero— pero es la otra mitad de la tranquilidad: el día que algo falle, me entero yo primero, no mis visitantes.

Y si todo falla: backups

La última red. Cada mañana, un script copia lo que importa —las bases de datos, la configuración de Apache, los ficheros de las webs— y lo sube a almacenamiento en la nube (un bucket en otra región), además de guardar una copia local reciente. Todo comprimido y con rotación automática.

Autoalojar en casa no está reñido con ser responsable: si el Mac mini muriera del todo, volver a levantarlo es cuestión de restaurar unos cuantos .tar.gz. Eso es lo que de verdad te quita el miedo.

El dominio y el correo: lo único que pago

Aquí toca ser sincero con lo del “gratis”. Todo lo anterior —proxy, Tunnel, Always Online, Cache Rules, DNS— está en el plan Free de Cloudflare. No pago un euro por ello.

Lo único que pago es el dominio en sí. Y lo registré precisamente en Cloudflare Registrar, que lo vende a precio de coste (sin el sobreprecio de otros registradores). Pero no lo hice por la web: lo contraté porque quería correo personalizado con iCloud+ (la función Custom Email Domain de Apple), y para eso necesitas un dominio propio. Configurando los registros MX de iCloud en el DNS de Cloudflare, tengo correo @sergiocomeron.com gestionado por Apple. El dominio me sirve para las dos cosas.

Lo que no uso (todavía)

Cloudflare es muchísimo más que un CDN, pero casi todo su catálogo está pensado para montar tu aplicación sobre su infraestructura, justo lo contrario de lo que hago yo (tener mi propio servidor). Para que te hagas una idea de lo que hay:

  • Workers: ejecutar tu código repartido por el edge de Cloudflare en todo el mundo, sin servidor propio. Una especie de “serverless” pegado a la red.
  • R2: almacenamiento de objetos estilo Amazon S3 (imágenes, vídeos, ficheros grandes), con la gracia de que no cobra por la salida de datos.
  • D1: una base de datos SQL (SQLite) que vive en el edge, pensada para usarse desde los Workers.
  • Pages: hosting de webs estáticas con despliegue automático desde Git. De hecho este blog vivió ahí una temporada, antes de traérmelo al Mac mini.
  • Zero Trust / Access: poner identidad y login por delante de servicios internos, para exponerlos solo a quien tú decidas y sin montar una VPN.

Nada de esto me hace falta teniendo un servidor en casa donde corro lo que quiero. Y parte de hacer esto bien es no añadir piezas que no resuelven un problema que tengas de verdad.

En resumen

El autoalojado casero parecía condenado a ser frágil, y resulta que con una capa gratuita encima deja de serlo:

  • Tunnel → cero puertos abiertos, IP de casa invisible.
  • Always Online → la web aguanta aunque se vaya la luz.
  • Cache Rules → rendimiento donde lo quieres, y datos reales donde lo necesitas.
  • DNS + proxy + SSL → todo resuelto y gratis.
  • Solo pago el dominio, que además me da el correo.

Si tienes un viejo ordenador cogiendo polvo, hoy es perfectamente viable convertirlo en tu servidor sin exponer tu casa ni temer el primer apagón. Yo llevo así una temporada y no pienso volver.