"description":"Cómo convierte OCI manager Apps una aplicación con su base de datos y su caché en LXC nativos coordinados: plan, red privada, hook de dependencias, validación y actualizaciones transaccionales."
"description":"Una aplicación con su base de datos, su caché y otros servicios se convierte en varios LXC nativos coordinados, que se instalan y actualizan como uno solo.",
"section":"OCI manager Apps"
},
"sections":[
{
"id":"intro",
"blocks":[
{
"calloutInfo":{
"title":"Una aplicación para el usuario, varios LXC para Proxmox VE",
"body":"Una definición multicontenedor es una sola entrada del catálogo. El instalador crea un LXC nativo por servicio y mantiene explícitas sus dependencias. Immich, Nextcloud, Paperless-ngx y Tandoor se instalan de esta forma."
}
},
{
"mermaid":{
"chartCode":"flowchart LR\n C[\"Docker Compose\"] --> O[\"{{plan}}\"]\n O --> A[\"{{app}}<br/>{{appNet}}\"]\n O --> D[\"{{db}}<br/>{{private}}\"]\n O --> R[\"{{cache}}<br/>{{private}}\"]\n V1[(\"config\")] --> A\n V2[(\"database\")] --> D\n V3[(\"cache\")] --> R\n D --> A\n R --> A",
"title":"1. El plan, antes de que exista ningún contenedor",
"blocks":[
{
"p":"Mientras se interpreta la definición Compose no se crea ningún LXC. Primero se construye un plan completo con cada miembro, imagen, VMID, red, ruta, secreto, orden y comprobación de salud. Si el plan no es coherente, la instalación no empieza."
"body":"Se comprueban el inventario de Proxmox VE y el registro de instancias. No se adopta un CT existente ni se reutiliza un contrato que todavía pertenece a otra instancia."
},
{
"title":"Preparar todas las imágenes",
"body":"Todas las imágenes se resuelven, descargan y verifican antes de crear el primer contenedor."
},
{
"title":"Crear cada rootfs",
"body":"Se importan los metadatos OCI oficiales y se añaden la identidad de instancia de ProxMenux y el rol del miembro."
},
{
"title":"Red privada",
"body":"Se crean un bridge y una subred y cada miembro recibe su dirección fija; solo el miembro principal recibe además la interfaz de la LAN."
},
{
"title":"Persistencia",
"body":"Cada base de datos y configuración recibe su propio disco del contenedor; solo los datos destinados a compartirse usan directorios del host."
},
{
"title":"Entorno",
"body":"Se escriben los endpoints internos, los secretos compartidos y las variables de servicio. La aplicación llega a sus dependencias en sus direcciones privadas reservadas."
},
{
"title":"Registro",
"body":"Cada miembro registra su configuración nativa, los cambios del rootfs que las actualizaciones deben reproducir y su relación con la pila."
"body":"El estado running solo indica que existe el proceso del LXC. Cuando el servicio ofrece una comprobación mejor, se usa una comprobación exec o HTTP con un tiempo límite. Si un miembro se detiene o no supera su comprobación, la pila no se declara instalada."
}
}
]
},
{
"id":"hook",
"title":"4. El hook de dependencias",
"blocks":[
{
"p":"El hook solo se configura en el contenedor principal de una pila dependiente. Proxmox VE guarda el script como snippet y lo ejecuta como <code>hookscript</code> de ese CT. La receta de la pila no está escrita en el script: vive en un contrato privado aparte."
"p":"El script es el mismo para todas las pilas. Los VMID, los nombres, los tipos de comprobación y los tiempos límite proceden del contrato privado <code>/etc/pve/priv/proxmenux-stack-VMID.json</code> de cada pila."
"body":"Las fases post-start, pre-stop y post-stop no hacen nada. Detener el CT principal deja en marcha PostgreSQL, Redis, Valkey o el aprendizaje automático. El hook ordena el arranque; no convierte varios LXC en un único proceso."
"intro":"En <strong>Gestionar aplicaciones OCI instaladas</strong>, cualquier miembro lleva a la pila completa. El menú de una pila ofrece <strong>Actualizar cada contenedor de la aplicación</strong>, <strong>Modificar rutas extra y dispositivos</strong>, <strong>Recrear todos los contenedores con su configuración guardada</strong> y <strong>Eliminar: la aplicación y sus contenedores</strong>. Recrear reconstruye cada contenedor desde la imagen con la que se instaló, por su digest guardado y sin buscar una más nueva, con los mismos pasos que una actualización; se ofrece en las pilas que se pueden actualizar.",
"Se añaden al contenedor de la aplicación o se eliminan de él, y el contenedor se reinicia. No se reconstruye nada",
"Los datos de la aplicación, su base de datos y los demás contenedores"
],
[
"Qué ejecuta el reconocimiento (Immich)",
"El contenedor Machine learning toma la imagen y los dispositivos de la CPU o de una GPU del host. Toda la aplicación se detiene y se actualiza, como en una actualización",
"La caché de modelos, la biblioteca y la base de datos. Si algo falla, se restauran los contenedores y la opción anteriores"
"title":"Una pila sin reproducción coordinada no se actualiza",
"body":"Si la preparación de una pila no puede reproducirse, la actualización se rechaza antes de detenerla. La aplicación sigue funcionando tal como está."
}
}
]
},
{
"id":"failure",
"title":"6. Cuando algo falla",
"blocks":[
{
"p":"Durante una instalación, un error detiene y elimina los contenedores incompletos que creó esa operación, y el bridge privado si lo creó ella. Una pila no se publica como válida hasta que termina la secuencia completa."
},
{
"p":"Una actualización es transaccional: primero se preparan todas las imágenes, después se detiene la pila, se hace el backup de cada miembro y se verifica, y solo entonces se sustituye cada rootfs. Los miembros arrancan uno a uno con su comprobación de salud; si uno falla, se restauran todos desde el mismo conjunto de backups, de modo que la base de datos y la aplicación nunca corresponden a momentos distintos."
"chartCode":"flowchart TB\n P[\"{{prepare}}\"] --> S[\"{{stop}}\"]\n S --> B[\"{{backup}}\"]\n B --> R[\"{{replace}}\"]\n R --> H{\"{{healthy}}\"}\n H -- \"{{yes}}\" --> C[\"{{commit}}\"]\n H -- \"{{no}}\" --> X[\"{{rollback}}\"]",