Alojar apps en casa: una Raspberry Pi 5 con Kubernetes
Todo lo que ves en raspimc funciona en una Raspberry Pi 5 con k3s. Qué piezas la componen, cómo llega una petición desde internet hasta una app y qué limitaciones tiene montarlo en casa.
El hub de casa, el inicio de sesión, las bases de datos y esta misma web funcionan en un ordenador del tamaño de una tarjeta de crédito que está en una estantería. No hay servidores alquilados. Este artículo cuenta qué hay dentro, por qué se eligió cada pieza y, sobre todo, qué no se puede esperar de un montaje así.
El hardware
- Una Raspberry Pi 5 con 16 GB de memoria y cuatro núcleos.
- El sistema, en una tarjeta de memoria. Los datos, en discos externos por USB.
- Una conexión a internet doméstica, con una dirección IP que cambia de vez en cuando.
En el momento de escribir esto hay casi cien contenedores en marcha. No todos son del hub: en la misma máquina conviven otras herramientas de uso personal. La memoria es el recurso que manda. La Raspberry Pi tiene procesador de sobra para servir páginas a unas pocas decenas de personas; lo que se agota es la RAM.
Por qué Kubernetes para algo tan pequeño
La objeción razonable es que Kubernetes es demasiada herramienta para una sola máquina. Lo es la versión completa. Aquí se usa k3s, una distribución ligera pensada para equipos modestos, que ocupa poca memoria y se instala con una orden.
Lo que se obtiene a cambio compensa incluso con un único nodo:
- Todo está descrito en ficheros. Cada app es un conjunto de manifiestos guardados en un repositorio. Reconstruir el servidor desde cero es aplicar esos ficheros.
- Las apps se reinician solas si fallan, y se actualizan sin corte: arranca la versión nueva, se comprueba que responde y entonces se retira la antigua.
- Entornos separados. El hub tiene una copia de pruebas y otra de producción en la misma máquina, aisladas entre sí. Todo cambio pasa primero por pruebas.
El camino de una petición
Cuando abres el hub en el móvil, ocurre esto:
- DNS y proxy. El dominio apunta a una red de distribución que recibe la conexión, filtra tráfico malicioso y la reenvía a casa. Como la IP doméstica cambia, un pequeño servicio avisa de la nueva dirección cada vez que ocurre.
- El router reenvía los puertos web a la Raspberry Pi.
- El proxy de entrada del clúster (Traefik) recibe la petición, termina la conexión cifrada con un certificado de Let's Encrypt que se renueva solo, y decide a qué app va según la ruta.
- Comprobación de sesión. Antes de dejar pasar, pregunta a un servicio intermedio si hay una sesión válida. Si no la hay, redirige al inicio de sesión.
- La app. La parte visual es una web estática servida por nginx; los datos los pide a una API escrita en Node.js, que vuelve a comprobar por su cuenta quién hace la petición.
- La base de datos, PostgreSQL, donde se guarda todo.
Las apps del hub son siete webs pequeñas y siete APIs en lugar de un único programa grande. Así se puede actualizar el calendario sin tocar la lista de la compra, y un fallo en una no tumba las demás.
Decisiones que impuso la memoria
Una base de datos compartida
Al principio cada app tenía su propio PostgreSQL. Era limpio, pero cada instancia consume memoria aunque esté parada, y con varias apps eso no escalaba en una Raspberry Pi. Ahora hay una sola instancia por entorno, y dentro de ella cada app tiene su propia base de datos y su propio usuario.
Al hacer ese cambio apareció un detalle que conviene conocer: PostgreSQL permite por defecto que cualquier usuario se conecte a cualquier base de datos de la instancia. No puede leer las tablas ajenas, pero la puerta está abierta. Hay que retirar ese permiso de forma explícita en cada base de datos para que el aislamiento sea real.
Límites por contenedor
Cada app declara cuánta memoria necesita y cuál es su máximo. Un servicio que se descontrola se reinicia solo, en lugar de dejar sin memoria a los demás.
Cómo se publica un cambio
- El cambio se hace en una rama de desarrollo.
- Se construye una imagen del contenedor para la arquitectura de la Raspberry Pi (ARM de 64 bits) y se guarda en un registro propio.
- Se despliega en el entorno de pruebas y se comprueba, con pruebas automáticas y a mano.
- Cuando está validado, pasa a la rama principal y se despliega en producción.
Lo que cambia con frecuencia y es solo texto (por ejemplo, las instrucciones del asistente) no va dentro de la imagen, sino en un fichero de configuración que se puede actualizar sin reconstruir nada.
Copias de seguridad
Cada noche se vuelca la base de datos entera, se cifra y se guarda. Se conservan las de los últimos siete días, y una copia cifrada sale fuera de casa. El porqué del cifrado y cómo se hace está en copias de seguridad cifradas antes de subirlas a la nube.
Lo que no te da un servidor en casa
Conviene ser claro con esto, porque es lo que se suele callar:
- No hay redundancia. Es una sola máquina. Si se estropea, se va la luz o se cae la conexión, el servicio se para hasta que alguien lo arregle.
- La tarjeta de memoria es el punto débil. No están pensadas para escribir sin parar. Por eso los datos van en discos aparte y las copias son diarias.
- Una IP doméstica. Sirve para alojar webs, pero no para enviar correo: los grandes proveedores rechazan el que sale de conexiones residenciales. Los correos del hub se envían a través de un servicio externo.
- El mantenimiento es tuyo. Actualizaciones de seguridad, renovación de certificados, vigilancia del espacio en disco. Nadie lo hace por ti.
Entonces, ¿merece la pena?
Para un proyecto personal con pocos usuarios, sí. El coste mensual es la electricidad de un aparato que consume poco y el dominio. Se aprende muchísimo, porque no hay ninguna capa que otro gestione por ti. Y los datos están físicamente donde puedes verlos.
Para algo de lo que dependa mucha gente o que no pueda pararse, no. Y decirlo abiertamente forma parte de hacerlo bien.