docs: promote /web from develop for backup-restore, Log2RAM and Network Flow guides

Brings 69 files from develop under /web/:
- Full Backup & Restore section (11 pages EN + ES: overview, how-it-works, destinations,
  creating backups, scheduled jobs, restoring, cross-kernel hydration)
- Log2RAM dedicated block in post-install/optional with commands + upstream link
- Network Flow diagram documented on monitor/dashboard/network
- Rewritten category descriptions in post-install/customizable
- Fixed automated.json thresholds + link to Log2RAM section
- Updated screenshots (network-flow-overview, storage-top-row, vms modals)

No code, config or AppImage binaries touched — /web/ scope only. Merging deploys
the documentation site to the current beta release notes.
This commit is contained in:
MacRimi
2026-07-04 22:10:49 +02:00
parent a92420d654
commit 720f3fdbd2
69 changed files with 7246 additions and 48 deletions
+14 -2
View File
@@ -168,7 +168,19 @@
"aboutContributors": "Contribuidores",
"aboutContributing": "Contribuir",
"aboutCodeOfConduct": "Código de conducta",
"externalRepositories": "Repositorios externos"
"externalRepositories": "Repositorios externos",
"backupRestore": "Backup & Restore",
"backupRestoreOverview": "Descripción general",
"backupRestoreHowItWorks": "Cómo funciona",
"backupRestoreDestinations": "Destinos",
"backupRestoreDestOverview": "Descripción general",
"backupRestoreDestLocal": "Archivo local",
"backupRestoreDestPbs": "Proxmox Backup Server",
"backupRestoreDestBorg": "Borg",
"backupRestoreCreating": "Crear copias",
"backupRestoreJobs": "Trabajos programados",
"backupRestoreRestoring": "Restauración",
"backupRestoreCrossKernel": "Restauración cross-kernel"
}
},
"hero": {
@@ -213,4 +225,4 @@
"ogTail": "Suscríbete vía RSS o vuelve a comprobarlo para nuevas versiones."
}
}
}
}
@@ -0,0 +1,220 @@
{
"meta": {
"title": "Crear copias — flujo interactivo de copia | ProxMenux",
"description": "El flujo interactivo de copia en ProxMenux. Dos puntos de entrada (menú TUI de Scripts y UI Web del Monitor), tres destinos, dos modos de perfil, un paso común de staging y un diálogo de confirmación. Documenta la matriz de seis opciones, los perfiles Default y Custom, y qué ve el usuario entre seleccionar una copia y ver el archivo aterrizando en el destino.",
"ogTitle": "ProxMenux Backup — crear copias",
"ogDescription": "El flujo interactivo de copia con tres destinos, dos perfiles y un paso común de staging.",
"twitterTitle": "Crear copias | ProxMenux",
"twitterDescription": "Flujo interactivo de copia con tres destinos y dos modos de perfil."
},
"header": {
"title": "Crear copias",
"description": "El flujo interactivo de copia: elegir un destino y un perfil, revisar el resumen de confirmación, y ver el archivo aterrizando. Dos puntos de entrada comparten el mismo backend y producen archivos idénticos.",
"section": "Backup & Restore"
},
"intro": {
"title": "Dos puntos de entrada, funcionalidad idéntica",
"body": "El TUI de Scripts y la UI Web del Monitor exponen <strong>exactamente la misma funcionalidad</strong>. Cada copia — manual o programada — pasa por la misma matriz de elección (tres destinos × dos perfiles) e invoca la misma función backend por celda (<code>_bk_pbs</code>, <code>_bk_borg</code> o <code>_bk_local</code>). Los archivos producidos desde uno u otro punto de entrada son indistinguibles. Cuál usar es una cuestión de preferencia: el TUI es amigable por SSH y admite scripting; el Monitor ofrece click-y-elegir y convive con las vistas de notificaciones y de tail del log."
},
"entryPoints": {
"heading": "Los dos puntos de entrada",
"rows": [
{
"entry": "ProxMenux Scripts (TUI)",
"path": "menu → Utilities → Host Config Backup",
"detail": "Flujo basado en diálogos, amigable por SSH. El menú principal presenta las seis opciones directamente. Usa <code>backup_menu</code> en <code>backup_host.sh</code>."
},
{
"entry": "ProxMenux Monitor (UI Web)",
"path": "Pestaña Backups → Create backup",
"detail": "Flujo en estilo asistente. Las mismas seis opciones presentadas como formulario de dos pasos (destino → perfil). Se invocan las mismas funciones backend por la API Flask."
}
]
},
"modes": {
"heading": "Copias manuales vs programadas",
"body": "Las copias se pueden producir en dos modos: <strong>manuales</strong> (el flujo interactivo que documenta esta página — el usuario elige un destino y un perfil desde un menú y ve el archivo aterrizando) o <strong>programadas</strong> (un trabajo desatendido que se ejecuta en un timer estilo cron y aplica la retención configurada en el trabajo). Ambos modos soportan los mismos tres destinos y los mismos dos perfiles, y ambos están disponibles desde los dos puntos de entrada — el menú TUI de Scripts y la pestaña Backups del Monitor. Los trabajos programados usan las mismas funciones backend que el flujo manual a través de <code>run_scheduled_backup.sh</code>; los archivos producidos son indistinguibles.",
"seeAlso": "La página de trabajos programados cubre el flujo completo, incluyendo cómo crear un trabajo, adjuntarlo a un timer vzdump de PVE existente, y configurar los valores de retención.",
"monitorAlt": "Pestaña Backups del Monitor de ProxMenux mostrando el diálogo New scheduled backup con los campos de destino, perfil, horario y retención.",
"monitorCaption": "Copia programada — Monitor de ProxMenux. El mismo diálogo estilo asistente que crea una copia manual lleva los campos de horario y retención al final para la ruta desatendida."
},
"matrix": {
"heading": "La matriz de seis opciones",
"intro": "La elección determina qué backend se ejecuta y qué estrategia de selección de rutas se aplica. Consulta las páginas específicas de cada destino para los detalles de configuración de cada celda.",
"rows": [
{
"combo": "1",
"destination": "PBS",
"profile": "Default",
"action": "Sube el perfil por defecto más los extras persistentes a un repositorio PBS configurado."
},
{
"combo": "2",
"destination": "Borg",
"profile": "Default",
"action": "Crea un archivo con el perfil por defecto más los extras persistentes en el repositorio Borg seleccionado."
},
{
"combo": "3",
"destination": "Local",
"profile": "Default",
"action": "Escribe un archivo <code>.tar.zst</code> con el perfil por defecto más los extras persistentes en el destino local configurado."
},
{
"combo": "4",
"destination": "PBS",
"profile": "Custom",
"action": "Abre el path picker antes de la subida a PBS; el usuario marca rutas y puede añadir nuevas."
},
{
"combo": "5",
"destination": "Borg",
"profile": "Custom",
"action": "Abre el path picker antes de crear el archivo Borg."
},
{
"combo": "6",
"destination": "Local",
"profile": "Custom",
"action": "Abre el path picker antes de escribir el <code>.tar.zst</code> local."
}
]
},
"profiles": {
"heading": "Perfil Default vs Custom",
"defaultTitle": "Perfil Default",
"defaultBody": "El perfil por defecto es la lista curada de <code>hb_default_profile_paths</code> (documentada en <em>Cómo funciona</em> bajo <em>Categorías de rutas</em>) más cada entrada del fichero de extras persistentes <code>/usr/local/share/proxmenux/backup-extra-paths.txt</code>. El usuario confirma el destino y las opciones de cifrado y la copia continúa sin más selección de rutas.",
"customTitle": "Perfil Custom",
"customBody": "El perfil Custom abre un checklist mostrando cada ruta del perfil por defecto (sin marcar) y cada extra persistente (premarcado, prefijado con <code>[+]</code>). El usuario marca el conjunto para esa ejecución y puede pulsar <em>Add custom path</em> para añadir una nueva ruta absoluta. Cualquier ruta añadida en línea se persiste en <code>backup-extra-paths.txt</code> para que futuras copias la recojan automáticamente sin volver a añadirla. Quitar la marca a un extra persistente lo desmarca para esa ejecución pero no lo elimina del fichero — la eliminación es una acción <em>Manage custom paths</em> separada, fuera del flujo de copia.",
"customPickerAlt": "Checklist del perfil Custom mostrando las rutas del perfil por defecto (sin marcar) y los extras persistentes (premarcados con prefijo [+]), más botones para añadir una ruta nueva o confirmar la selección.",
"customPickerCaption": "Perfil Custom — el path picker. Las rutas del perfil por defecto aparecen sin marcar; los extras persistentes aparecen premarcados con prefijo [+]. El usuario marca el conjunto para esa ejecución.",
"manageCustomAlt": "Menú Manage custom paths mostrando la lista de extras persistentes y opciones para añadirlos, eliminarlos o editarlos.",
"manageCustomCaption": "Manage custom paths — el punto de entrada donde se añaden o eliminan los extras persistentes. Cada ruta listada aquí se incluye automáticamente en las copias en modo Default sin necesidad de abrir el picker Custom."
},
"commonPipeline": {
"heading": "Qué se ejecuta con independencia del destino",
"intro": "Después de resolver el perfil, cada backend ejecuta el mismo pipeline de staging antes de divergir a su propio camino de subida. <code>hb_prepare_staging</code> ensambla el árbol del archivo en <code>/tmp/proxmenux-DESTINATION-stage.XXXXXX</code> y pobla cada uno de los tres bloques.",
"steps": [
{
"step": "1",
"name": "Ensamblado del rootfs",
"detail": "Ejecuta <code>rsync -a</code> por cada ruta seleccionada hacia <code>staging_root/rootfs/</code>. Excluye subrutas volátiles (historial de bash, cachés, papelera) de <code>/root/</code>. Las rutas ausentes en el origen se registran en <code>metadata/missing_paths.txt</code> sin detener la copia."
},
{
"step": "2",
"name": "Generación del manifiesto",
"detail": "<code>build_manifest.sh</code> orquesta los seis colectores y escribe <code>manifest.json</code> en la raíz del staging. Si un colector falla, la sección afectada hace fallback a un default vacío documentado; el manifiesto sigue siendo válido."
},
{
"step": "3",
"name": "Inventario de paquetes",
"detail": "<code>apt-mark showmanual</code> se captura tal cual en <code>metadata/packages.manual.list</code>. El estado de componentes ya está dentro del rootfs restaurado (<code>components_status.json</code>) porque <code>/usr/local/share/proxmenux/</code> forma parte del perfil por defecto."
},
{
"step": "4",
"name": "Info de la ejecución",
"detail": "<code>metadata/run_info.env</code> registra la identidad de la ejecución de copia — hostname, timestamp, versión del kernel — usada por el chequeo de compatibilidad de la restauración para determinar la dirección cross-kernel."
},
{
"step": "5",
"name": "Notificación (start)",
"detail": "Se dispara <code>hb_notify_lifecycle \"start\"</code>. Si las notificaciones están configuradas en el Monitor, se emite un evento usuario-facing <em>Host backup started</em>. Silencioso si no hay canales configurados."
}
]
},
"included": {
"heading": "Qué entra y qué se excluye",
"intro": "Cada ruta del perfil resuelto (default + extras persistentes + selección en modo Custom) se copia con <code>rsync -aAXH --numeric-ids</code>. Una lista de exclusiones compartida aplica a cada ruta, y dos directorios llevan exclusiones específicas adicionales.",
"globalTitle": "Exclusiones globales (aplican a cada ruta)",
"globalItems": [
"<code>images/</code> — dumps de imágenes.",
"<code>dump/</code> — salidas de vzdump.",
"<code>tmp/</code> — ficheros temporales.",
"<code>*.log</code> — ficheros de log."
],
"rootTitle": "Exclusiones de <code>/root/</code>",
"rootBody": "<code>/root/</code> forma parte del perfil por defecto para que los scripts y config del usuario entren en el archivo. Se descartan los subpaths volátiles:",
"rootItems": [
"<code>.bash_history</code>",
"<code>.cache/</code>",
"<code>tmp/</code>",
"<code>.local/share/Trash/</code>"
],
"proxmenuxTitle": "Exclusiones de <code>/usr/local/share/proxmenux/</code>",
"proxmenuxBody": "Este directorio contiene sólo estado de usuario — <code>components_status.json</code>, preferencias, caché post-install. El código que el destino ya tendrá de su propia instalación de ProxMenux se excluye para que una restauración no sobrescriba los binarios actuales del destino con versiones más antiguas:",
"proxmenuxItems": [
"<code>restore-pending/</code>, <code>scripts/</code>, <code>web/</code>",
"<code>monitor-app/</code>, <code>monitor-app.*/</code>, <code>AppImage/</code>",
"<code>images/</code>, <code>json/</code>",
"<code>utils.sh</code>, <code>helpers_cache.json</code>",
"<code>ProxMenux-Monitor.AppImage*</code>, <code>install_proxmenux*.sh</code>"
],
"notInProfileTitle": "Rutas fuera del perfil",
"notInProfileBody": "Todo lo que no esté listado en <code>hb_default_profile_paths</code> y no se haya añadido como ruta custom o extra persistente no forma parte de la copia. Ejemplos notables:",
"notInProfileItems": [
"<strong>Discos de VMs y LXCs</strong> — los gestiona <code>vzdump</code>, no esta funcionalidad. Los ficheros de configuración de los invitados bajo <code>/etc/pve/nodes/*/qemu-server/*.conf</code> y <code>lxc/*.conf</code> sí se capturan (viven bajo <code>/etc/pve</code>) para que la restauración reproduzca el inventario; los discos se re-adjuntan desde una copia existente de vzdump/PBS.",
"<strong><code>/boot</code> y <code>/boot/efi</code></strong> — los binarios del kernel, el initramfs y la partición ESP UEFI los regenera el propio destino con <code>update-initramfs</code>, <code>update-grub</code> o <code>proxmox-boot-tool refresh</code> tras la restauración. El bootloader nunca se copia verbatim.",
"<strong>Filesystems runtime del kernel y sistema</strong> — <code>/proc</code>, <code>/sys</code>, <code>/dev</code> y <code>/run</code> son pseudo-filesystems que produce el kernel y udev; no se persisten en ningún sitio.",
"<strong>Binarios de paquetes bajo <code>/usr/bin</code>, <code>/usr/lib</code>, <code>/lib</code>, <code>/sbin</code></strong> — los reinstala el APT del destino a partir de <code>packages.manual.list</code>.",
"<strong><code>/var/log/</code>, <code>/var/tmp/</code>, <code>/var/cache/</code></strong> — estado runtime por host, no se restaura.",
"<strong><code>/home/USUARIO</code></strong> — no está en el perfil por defecto. Añadirlo como ruta custom cuando un sistema tenga directorios home de usuario que deban sobrevivir a una restauración."
],
"customPathsTitle": "Cómo se tratan las rutas custom",
"customPathsBody": "Una ruta custom añadida en línea en modo Custom o persistida en <code>backup-extra-paths.txt</code> pasa por el mismo pipeline de <code>rsync</code> que las rutas del perfil por defecto. Se aplican las exclusiones globales. Si la ruta custom está bajo <code>/root/</code> o <code>/usr/local/share/proxmenux/</code>, siguen aplicando las exclusiones específicas de arriba. Cada ruta archivada — default o custom — queda registrada en <code>metadata/paths_archived.txt</code>. Las rutas que no existen en el origen se registran en <code>metadata/missing_paths.txt</code> sin detener la copia."
},
"archiveStructure": {
"heading": "Estructura del archive",
"intro": "El directorio de staging que produce cada backend sigue el mismo layout con independencia del destino. El tarball, el <code>.pxar</code> de PBS o el archivo Borg almacenan este árbol verbatim.",
"tree": "backup-[timestamp]/\n├── manifest.json # estado estructurado del host (kernel_params, hardware, storage, guests, components, source_host)\n├── metadata/\n│ ├── packages.manual.list # salida de apt-mark showmanual\n│ ├── run_info.env # hostname, timestamp, versión del kernel\n│ ├── paths_archived.txt # lista exacta de rutas que llegaron a rootfs/\n│ └── missing_paths.txt # rutas del perfil ausentes en el origen\n└── rootfs/\n ├── etc/ # /etc/pve, /etc/network, /etc/ssh, /etc/apt, ...\n ├── root/ # /root sin subpaths volátiles\n ├── usr/local/ # /usr/local/bin, /usr/local/sbin, /usr/local/share/proxmenux (sólo estado)\n └── var/ # /var/lib/pve-cluster, /var/spool/cron/crontabs"
},
"confirmation": {
"heading": "Resumen de confirmación",
"body": "Antes de que el backend escriba nada en el destino, ProxMenux muestra un diálogo resumen con el destino, el backup ID o nombre del archivo, el estado del cifrado y la lista de rutas que se copian. Cancelar aquí aborta la copia limpiamente — el directorio de staging se elimina por el hook <code>trap</code> definido en la función backend y ningún dato parcial llega al destino."
},
"writing": {
"heading": "Escritura en el destino",
"intro": "Una vez el usuario confirma, cada backend ejecuta su propio paso de escritura. La mecánica está cubierta en las páginas de cada destino; la superficie compartida son el log, el sidecar y la notificación de finalización.",
"rows": [
{
"topic": "Fichero de log",
"detail": "Cada backend escribe su salida completa en <code>/tmp/proxmenux-DESTINATION-backup-YYYYMMDD_HHMMSS.log</code> y, en caso de fallo, ofrece abrirlo en un diálogo scrollable. La ruta al log se imprime en el resumen de finalización sólo cuando el fichero tiene contenido."
},
{
"topic": "Sidecar (sólo local)",
"detail": "<code>hb_write_archive_sidecar</code> deposita un <code>*.proxmenux.json</code> junto al archivo local para que el Monitor lo identifique como copia de host de ProxMenux incluso tras movimientos o renombrados."
},
{
"topic": "Notificación (complete/fail)",
"detail": "Se dispara <code>hb_notify_lifecycle \"complete\"</code> o <code>\"fail\"</code> con duración, tamaño del archivo y — en fallos — la última línea del log que parezca un error."
}
]
},
"finishedScreens": {
"heading": "Cómo se ve una copia finalizada",
"intro": "El mismo evento de finalización lo exponen los dos puntos de entrada. El TUI escribe un bloque resumen en el terminal; la pestaña Backups del Monitor muestra la ejecución en la lista de archivos con badges de tamaño, duración y estado.",
"scriptsAlt": "TUI de ProxMenux Scripts mostrando una copia de host finalizada — destino, backup ID, ruta del snapshot, tamaño de datos, duración y estado de cifrado.",
"scriptsCaption": "Copia finalizada — ProxMenux Scripts (TUI). El bloque de finalización imprime el destino, backup ID, nombre del snapshot o archivo resultante, tamaño de datos, duración y estado de cifrado.",
"monitorAlt": "Pestaña Backups del Monitor de ProxMenux mostrando una entrada de copia de host finalizada con tamaño, duración, badge del método y indicador de cifrado.",
"monitorCaption": "Copia finalizada — pestaña Backups del Monitor de ProxMenux. La nueva copia aparece en la lista de archivos con el badge del método del destino, tamaño, duración y — cuando aplica — el indicador de cifrado."
},
"whereNext": {
"heading": "A dónde seguir",
"items": [
{
"label": "Destinos",
"href": "/docs/backup-restore/destinations",
"tail": " — detalles de configuración para Local, PBS y Borg."
},
{
"label": "Trabajos programados",
"href": "/docs/backup-restore/scheduled-jobs",
"tail": " — ejecutar la misma copia desatendida en un horario en lugar de interactivamente."
},
{
"label": "Restauración",
"href": "/docs/backup-restore/restoring",
"tail": " — el flujo que consume lo que esta página produce."
}
]
}
}
@@ -0,0 +1,94 @@
{
"meta": {
"title": "Restauración cross-kernel — detección de dirección, filtro de subconjunto seguro, hidratación | ProxMenux",
"description": "Cómo restaura ProxMenux una copia de host sobre un destino con un kernel de versión mayor distinta. Documenta cómo se detecta la dirección del salto, el filtro de subconjunto seguro que salta rutas críticas del arranque cuando el destino corre un kernel más reciente que la copia, y la hidratación independiente del kernel de cuatro fases que reaplica la configuración del usuario como IOMMU, IDs VFIO y tokens custom del cmdline sin copiar verbatim los ficheros ligados al kernel.",
"ogTitle": "ProxMenux Backup — restauración cross-kernel e hidratación",
"ogDescription": "Restauración cross-kernel direccional con filtro de subconjunto seguro e hidratación independiente del kernel.",
"twitterTitle": "Restauración cross-kernel | ProxMenux",
"twitterDescription": "Cómo maneja ProxMenux una restauración cuando el kernel del destino difiere del de la copia."
},
"header": {
"title": "Restauración cross-kernel",
"description": "Cómo maneja ProxMenux una restauración cuando el kernel del host de destino es distinto al kernel que había en el momento de la copia — especialmente cuando el destino ejecuta un kernel más reciente. Documenta cómo se detecta la diferencia, cómo se filtran las rutas críticas del arranque que podrían romper el destino, y cómo se reaplica la configuración propia del usuario sin copiar verbatim los ficheros ligados al kernel.",
"section": "Backup & Restore"
},
"intro": {
"title": "Cada salto de kernel se maneja de forma distinta",
"body": "Cuando la restauración detecta que la copia y el destino tienen versiones mayores distintas de kernel, el flujo se ramifica en función de la dirección del salto — si la copia es más antigua o más reciente que el destino — porque los dos casos tienen modos de fallo opuestos. Las copias más recientes que el destino se restauran limpiamente tal cual (verificado empíricamente en múltiples pruebas de banco). Las copias más antiguas que el destino necesitan un filtro para evitar romper el arranque del destino con configuración escrita para un kernel que desde entonces ha cambiado."
},
"directionCheck": {
"heading": "La comprobación de dirección",
"intro": "Durante la comprobación de compatibilidad, <code>hb_compat_check</code> compara el kernel registrado en el manifiesto de la copia contra el kernel actual del destino (<code>uname -r</code>) y clasifica la restauración en uno de tres casos, guardado en la variable interna <code>HB_COMPAT_KERNEL_DIRECTION</code>:",
"rows": [
{ "direction": "same", "condition": "La versión mayor del kernel coincide entre la copia y el destino.", "behavior": "El flujo de restauración completo corre sin cambios. Sin filtro adicional, sin hidratación, sin aviso especial en la interfaz." },
{ "direction": "bk_newer", "condition": "El kernel de la copia es más RECIENTE que el del destino (por ejemplo: la copia se hizo con kernel 7.0 y el destino corre kernel 6.17).", "behavior": "El flujo de restauración completo corre sin cambios, exactamente igual que en <code>same</code>. No se aplica ningún filtro. Verificado empíricamente: los controladores se reinstalan contra el kernel del destino, la configuración IOMMU se aplica limpia, las VMs con passthrough GPU arrancan sin problemas." },
{ "direction": "bk_older", "condition": "El kernel de la copia es más ANTIGUO que el del destino (por ejemplo: la copia se hizo con kernel 6.17 y el destino corre kernel 7.0).", "behavior": "Se activan el filtro de subconjunto seguro y la hidratación de cuatro fases descritos más abajo. La restauración procede — el destino reproduce el origen, pero los ficheros críticos del arranque no se copian verbatim." }
]
},
"whyBkNewerIsSafe": {
"heading": "Por qué una copia con kernel más reciente que el destino se restaura sin cambios",
"body": "Cuando la restauración corre contra un destino con un kernel <em>más antiguo</em> que el registrado en la copia, todos los mecanismos de los que depende la restauración son independientes de la versión del kernel. Los instaladores de controladores de GPU y otros dispositivos PCI detectan el kernel en ejecución con <code>uname -r</code> y compilan DKMS contra lo que tenga el destino. La instalación de paquetes por APT trae binarios construidos para la distribución del destino. Los tokens IOMMU del cmdline como <code>intel_iommu=on</code> son estables entre versiones mayores de kernel. La copia lleva rutas escritas bajo un kernel más reciente, pero esas rutas (blacklists de módulos, defaults de GRUB, configuración de initramfs) siguen siendo sintaxis válida en el más antiguo — los kernels ignoran los tokens que no reconocen en lugar de fallar. Este caso es equivalente en la práctica a una restauración con el mismo kernel, y ProxMenux lo trata como tal."
},
"safeSubsetFilter": {
"heading": "El filtro de subconjunto seguro (sólo cuando el kernel del destino es más reciente)",
"intro": "Cuando el kernel del destino es más reciente que el de la copia, la comprobación de compatibilidad añade 16 rutas críticas del arranque de <code>hb_unsafe_paths_cross_version</code> a <code>RS_SKIP_PATHS</code>. Estas rutas se excluyen de la restauración porque escribir una versión suya de un kernel más antiguo sobre un destino que corre uno más reciente ha causado kernel panics en pruebas de banco. Las rutas cubren cuatro categorías:",
"categoryRows": [
{ "category": "Bootloader", "paths": "<code>/etc/default/grub</code>, <code>/etc/kernel</code>", "reason": "Defaults de GRUB atados al orden previo de kernels, y estado de proxmox-boot-tool (cmdline, UUIDs de ESP, hooks) que referencia rutas e identificadores de la instalación más antigua." },
{ "category": "Módulos del kernel y artefactos de arranque", "paths": "<code>/etc/modules-load.d</code>, <code>/etc/modprobe.d</code>, <code>/etc/initramfs-tools</code>", "reason": "Listas de autocarga que pueden referenciar módulos renombrados entre majors del kernel, opciones de módulo que pueden no aplicar, hooks de initramfs escritos para el kernel más antiguo." },
{ "category": "Stack de almacenamiento e identidad de filesystem", "paths": "<code>/etc/fstab</code>, <code>/etc/multipath</code>, <code>/etc/iscsi</code>, <code>/etc/udev/rules.d</code>, <code>/etc/zfs</code>", "reason": "UUIDs que pueden no existir en esta instalación, drivers de multipath que cambian entre kernels, parámetros iSCSI que evolucionan, reglas udev que pueden atarse a subsistemas inexistentes, estado ZFS (<code>zpool.cache</code> + <code>hostid</code>) que puede bloquear el pool como si no perteneciera al host." },
{ "category": "Fuentes APT", "paths": "<code>/etc/apt</code>", "reason": "Las suites de fuentes APT pueden disparar un downgrade de paquetes críticos en la próxima actualización." },
{ "category": "systemd", "paths": "<code>/etc/systemd/system</code>, <code>/etc/systemd/journald.conf</code>, <code>/etc/systemd/logind.conf</code>, <code>/etc/systemd/system.conf</code>, <code>/etc/systemd/user.conf</code>", "reason": "Overrides de unit y .wants ligados al major de systemd más antiguo; claves de configuración que pueden no parsearse en un systemd más reciente." }
],
"outroBody": "El filtro corre ANTES del diálogo de confirmación para que el usuario vea la lista exacta de rutas que se saltarán, categorizadas por motivo. La restauración procede igualmente — todo lo demás (VMs, LXCs, red, /etc/pve, usuarios, cron, estado de ProxMenux, paquetes, drivers, /root) se restaura con normalidad."
},
"hydration": {
"heading": "Hidratación independiente del kernel",
"intro": "El filtro de subconjunto seguro por sí solo dejaría al destino sin la configuración que el usuario había puesto dentro de esos ficheros críticos del arranque: cmdline IOMMU para passthrough GPU, IDs de dispositivo VFIO, <code>GRUB_TIMEOUT</code> custom, blacklists de nvidia. La pasada de hidratación reaplica esas piezas de forma independiente de la versión del kernel. Corren cuatro fases cuando el kernel del destino es más reciente que el de la copia, cada una aditiva (nunca sobrescribe un valor que el destino ya lleva) e idempotente (correr dos veces es un no-op).",
"phaseRows": [
{ "phase": "1a — Ruta GRUB", "detail": "Para hosts que usan GRUB (instalaciones ext4/lvm). <code>_rs_hyd_grub</code> mergea cada token de <code>manifest.kernel_params.cmdline_extra</code> de la copia en el <code>GRUB_CMDLINE_LINUX_DEFAULT</code> vivo del destino, saltando los tokens cuya clave el destino ya lleva. Después mergea claves whitelisted <code>GRUB_*</code> (<code>GRUB_TIMEOUT</code>, <code>GRUB_TIMEOUT_STYLE</code>, <code>GRUB_DEFAULT</code>, <code>GRUB_TERMINAL</code>, <code>GRUB_DISABLE_OS_PROBER</code>, <code>GRUB_SERIAL_COMMAND</code>, <code>GRUB_GFXMODE</code>, <code>GRUB_GFXPAYLOAD_LINUX</code>) del <code>/etc/default/grub</code> de la copia si difieren de las del destino." },
{ "phase": "1b — Ruta systemd-boot / ZFS", "detail": "Para hosts que usan systemd-boot (típicamente ZFS-on-root). <code>_rs_hyd_kernel_cmdline</code> mergea los tokens del usuario de <code>cmdline_extra</code> en el <code>/etc/kernel/cmdline</code> del destino, manteniendo intacto el boilerplate propio del destino: <code>root=</code>, <code>boot=</code> y <code>rootflags=</code>." },
{ "phase": "2 — Merge en /etc/modules", "detail": "<code>_rs_hyd_modules</code> añade los módulos de <code>manifest.kernel_params.modules_loaded_at_boot</code> que estén en la whitelist (<code>vfio</code>, <code>vfio_pci</code>, <code>vfio_iommu_type1</code>, <code>vfio_virqfd</code>, <code>kvm</code>, <code>kvm_intel</code>, <code>kvm_amd</code>, <code>nvidia</code>, <code>nvidia_drm</code>, <code>nvidia_modeset</code>, <code>nvidia_uvm</code>, <code>i915</code>, <code>xe</code>) Y que aún no estén presentes en <code>/etc/modules</code> del destino." },
{ "phase": "3 — Copia de ficheros whitelisted", "detail": "<code>_rs_hyd_files</code> copia ficheros escritos por el usuario del staging rootfs al destino en vivo cuando el contenido difiere. La whitelist cubre ficheros VFIO/nvidia/blacklist bajo <code>/etc/modprobe.d</code>, <code>/etc/modules-load.d</code>, y la regla VFIO bind + reglas udev de nvidia de ProxMenux bajo <code>/etc/udev/rules.d</code>. Los ficheros propiedad de la distro (<code>pve-blacklist.conf</code>, <code>mdadm.conf</code>, <code>nvme.conf</code>) se excluyen intencionadamente — sus contenidos evolucionan entre releases." },
{ "phase": "4 — Forzar reflows post-arranque", "detail": "Las cuatro fases escriben directamente en el destino vivo FUERA del pipeline normal de restauración. Para que los tokens/módulos/ficheros mergeados tengan efecto en el siguiente arranque, <code>HB_HYDRATION_APPLIED=1</code> se propaga a través de <code>plan.env</code> a <code>apply_pending_restore.sh</code>, que fuerza <code>NEEDS_INITRAMFS=1</code> y <code>NEEDS_GRUB=1</code> con independencia de lo que hubiera en la lista de apply. El dispatcher post-arranque después regenera el initramfs y refresca el bootloader." }
]
},
"planCommit": {
"heading": "Plan vs commit — el usuario ve un preview antes",
"body": "La hidratación corre en dos modos. Antes del diálogo de confirmación, ProxMenux ejecuta <code>_rs_apply_bk_older_hydration</code> en modo <code>plan</code>: calcula exactamente lo que se mergearía, rellena <code>RS_HYDRATION_SUMMARY</code> con un bloque verde que lista cada acción, y retorna sin escribir nada. El diálogo de confirmación muestra ese bloque verde junto a la lista ámbar de rutas saltadas por el subconjunto seguro, para que el usuario vea POR ADELANTADO qué se reaplicará automáticamente. Tras la confirmación del usuario, ProxMenux vuelve a ejecutar el mismo helper en modo <code>commit</code> — mismas fases, misma lógica, pero esta vez cada fase escribe en el destino vivo. Cancelar el diálogo de confirmación deja el destino intacto."
},
"flowDiagram": {
"heading": "El flujo cuando el kernel del destino es más reciente que el de la copia",
"intro": "Los pasos específicos que se añaden cuando el kernel del destino es más reciente se insertan dentro del flujo normal de restauración. Todo lo demás — hot apply, prepare pending, instalación de paquetes, dispatcher post-arranque — corre idéntico a una restauración con el mismo kernel.",
"diagram": " ┌────────────────────────────────────────────────────────────┐\n │ hb_compat_check │\n │ HB_COMPAT_KERNEL_DIRECTION = bk_older │\n └───────────────────────────┬────────────────────────────────┘\n │\n ▼\n ┌────────────────────────────────────────────────────────────┐\n │ Añade 16 rutas críticas del arranque a RS_SKIP_PATHS │\n │ /etc/default/grub, /etc/kernel, /etc/modules-load.d, ... │\n └───────────────────────────┬────────────────────────────────┘\n │\n ▼\n ┌────────────────────────────────────────────────────────────┐\n │ _rs_apply_bk_older_hydration \"plan\" │\n │ Calcula qué se mergearía │\n │ Rellena RS_HYDRATION_SUMMARY (bloque verde) │\n │ Sin escrituras │\n └───────────────────────────┬────────────────────────────────┘\n │\n ▼\n ┌────────────────────────────────────────────────────────────┐\n │ Diálogo de confirmación │\n │ Ámbar: rutas saltadas por el filtro de subconjunto seguro │\n │ Verde: tokens/ficheros reaplicados por la hidratación │\n │ El usuario acepta o cancela │\n └───────────────────────────┬────────────────────────────────┘\n │ (aceptado)\n ▼\n ┌────────────────────────────────────────────────────────────┐\n │ _rs_apply_bk_older_hydration \"commit\" │\n │ Fase 1a/1b: mergea tokens del cmdline + claves GRUB │\n │ Fase 2: añade módulos a /etc/modules │\n │ Fase 3: copia ficheros whitelisted vfio/nvidia │\n │ Fija HB_HYDRATION_APPLIED=1 │\n └───────────────────────────┬────────────────────────────────┘\n │\n ▼\n ┌────────────────────────────────────────────────────────────┐\n │ El resto de la restauración corre normalmente │\n │ _rs_apply hot (salta RS_SKIP_PATHS) │\n │ _rs_prepare_pending_restore (escribe plan.env con │\n │ HB_HYDRATION_APPLIED=1) │\n │ packages.manual.list install │\n │ Reinicio │\n │ apply_pending_restore.sh (fuerza NEEDS_INITRAMFS=1, │\n │ NEEDS_GRUB=1 por el flag de hidratación) │\n │ apply_cluster_postboot.sh │\n │ update-initramfs -u -k all │\n │ update-grub / proxmox-boot-tool refresh │\n │ component --auto-reinstall │\n └────────────────────────────────────────────────────────────┘"
},
"concreteExamples": {
"heading": "Ejemplos concretos",
"intro": "La pasada de hidratación no es abstracta — produce resultados observables y correctos en escenarios habituales. Dos ejemplos que la hidratación resuelve automáticamente:",
"rows": [
{ "scenario": "GPU passthrough (VFIO)", "detail": "El origen tenía <code>intel_iommu=on iommu=pt</code> en el cmdline, <code>vfio</code>/<code>vfio_pci</code>/<code>vfio_iommu_type1</code> en <code>/etc/modules</code>, un <code>/etc/modprobe.d/vfio.conf</code> con <code>options vfio-pci ids=10de:2216</code>, y un <code>/etc/modprobe.d/blacklist-nvidia.conf</code>. La hidratación mergea los tokens del cmdline en el GRUB o kernel cmdline del destino, añade los módulos vfio a <code>/etc/modules</code>, y copia los dos ficheros modprobe escritos por el usuario. En el siguiente arranque, IOMMU está activo, los módulos VFIO cargan, la GPU queda ligada a vfio-pci y la VM arranca con el passthrough funcionando." },
{ "scenario": "Defaults custom de GRUB", "detail": "El origen tenía <code>GRUB_TIMEOUT=1</code> y <code>GRUB_DISABLE_OS_PROBER=true</code>. La hidratación lee ambas claves del <code>/etc/default/grub</code> de la copia, ve que difieren de los defaults de la instalación fresca, y reescribe esas dos líneas en el fichero del destino (dejando todo lo demás, incluido <code>GRUB_DISTRIBUTOR</code>, intacto)." }
]
},
"callout": {
"warningTitle": "Qué no reaplica la hidratación cuando el kernel del destino es más reciente",
"warningBody": "La hidratación reaplica sólo la configuración que ProxMenux sabe que es segura entre versiones del kernel: tokens IOMMU, IDs VFIO, claves whitelisted de GRUB y módulos de una lista fija (<code>vfio*</code>, <code>nvidia*</code>, <code>i915</code>, <code>xe</code>, <code>kvm*</code>). Todo lo que quede fuera de ese conjunto — hooks custom de initramfs bajo <code>/etc/initramfs-tools/hooks/</code>, ficheros no whitelisted bajo <code>/etc/modprobe.d/</code>, overrides de unit de systemd escritos por el usuario — permanece excluido. El motivo es concreto: esos ficheros pueden invocar interfaces internas del kernel (APIs de módulos, layout de <code>/sys</code>, hooks de <code>udev</code>) que cambian entre versiones mayores, y aplicarlos verbatim sobre el kernel más reciente puede impedir que el destino arranque. Cuando se necesita reproducción exacta de la cadena de arranque, la restauración debe correr sobre un host con la misma versión mayor de kernel que la copia."
},
"codeReference": {
"heading": "Dónde viven los mecanismos",
"intro": "Para desarrolladores que quieran trazar o extender el comportamiento cross-kernel:",
"rows": [
{ "component": "Detección de dirección", "location": "<code>hb_compat_check</code> en <code>lib_host_backup_common.sh</code>. Fija <code>HB_COMPAT_KERNEL_DIRECTION</code>." },
{ "component": "Lista de rutas del subconjunto seguro", "location": "<code>hb_unsafe_paths_cross_version</code> en <code>lib_host_backup_common.sh</code>. Emite líneas <code>path\\tmotivo</code> usadas tanto por el filtro CLI como por el endpoint Web <code>/api/host-backups/restore/prepare</code>." },
{ "component": "Fases de hidratación", "location": "<code>_rs_hyd_grub</code>, <code>_rs_hyd_kernel_cmdline</code>, <code>_rs_hyd_modules</code>, <code>_rs_hyd_files</code> en <code>backup_host.sh</code>. Orquestados por <code>_rs_apply_bk_older_hydration</code>." },
{ "component": "Forzado de reflow post-arranque", "location": "<code>apply_pending_restore.sh</code> lee <code>HB_HYDRATION_APPLIED</code> de <code>plan.env</code> y fuerza <code>NEEDS_INITRAMFS=1</code>/<code>NEEDS_GRUB=1</code>." },
{ "component": "Preview Web", "location": "<code>/api/host-backups/restore/prepare</code> en <code>flask_server.py</code>. Fuentea la librería helper, ejecuta <code>_rs_apply_bk_older_hydration</code> en modo plan, devuelve las acciones al modal Web." }
]
},
"whereNext": {
"heading": "A dónde seguir",
"items": [
{ "label": "Restaurar", "href": "/docs/backup-restore/restoring", "tail": " — el pipeline completo de restauración en el que se enchufan los mecanismos de esta página." },
{ "label": "Cómo funciona", "href": "/docs/backup-restore/how-it-works", "tail": " — el manifiesto y los colectores que producen el bloque <code>kernel_params</code> del que lee la hidratación." }
]
}
}
@@ -0,0 +1,234 @@
{
"meta": {
"title": "Destino Borg — tipos de repositorio, autenticación SSH, cifrado | ProxMenux",
"description": "El destino Borg escribe las copias de host de ProxMenux en un repositorio Borg — local, en un disco externo montado, o en un servidor remoto accedido por SSH. Cubre la cadena de resolución del binario borg, las cuatro estrategias de clave SSH, el cifrado repokey, la configuración de destinos guardados y la retención por trabajo programado.",
"ogTitle": "ProxMenux Backup — destino Borg",
"ogDescription": "Cómo escribe ProxMenux las copias de host en repositorios Borg, con estrategias de autenticación SSH y cifrado repokey.",
"twitterTitle": "Destino Borg de copia | ProxMenux",
"twitterDescription": "Repositorios Borg local, USB y servidos por SSH para copias del host."
},
"header": {
"title": "Borg",
"description": "El destino Borg escribe las copias del host en un repositorio Borg. Se soportan tres tipos de repositorio: ruta local de sistema de ficheros, disco externo montado o servidor remoto vía SSH. Deduplicación a nivel de chunk entre todos los archivos del repositorio y cifrado opcional repokey.",
"section": "Backup & Restore"
},
"aboutBorg": {
"heading": "Qué es Borg",
"body": "Borg (también escrito BorgBackup) es una herramienta de copia de seguridad open-source con deduplicación, mantenida por la comunidad Borg Backup. Almacena cada archivo como un conjunto de chunks de longitud variable dentro de un repositorio; los chunks se comparten entre archivos, por lo que volver a copiar datos que no han cambiado tiene un coste de almacenamiento prácticamente nulo. Borg no está atado a Proxmox — es una herramienta de copia de uso general utilizada en muchos entornos. ProxMenux la usa como uno de los tres destinos para copias del host; cada mecanismo específico de Borg descrito en esta página (tipos de repositorio, borg-serve por SSH, cifrado repokey, prune) es comportamiento estándar de Borg."
},
"intro": {
"title": "Deduplicación por chunks con repositorios locales o servidos por SSH",
"body": "Un repositorio Borg almacena chunks que se comparten entre cada archivo que contiene, por lo que volver a copiar un fichero que no ha cambiado no transfiere ni almacena nada nuevo. ProxMenux invoca <code>borg create</code> contra el repositorio en el momento de la copia y <code>borg extract</code> en la restauración. El repositorio puede vivir en el mismo sistema de ficheros que el origen, en un disco externo montado, o en un host remoto accedido por SSH."
},
"binarySourcing": {
"heading": "El binario borg",
"intro": "Borg no es una dependencia base del instalador de ProxMenux. Cuando se ejecuta una copia, <code>hb_ensure_borg</code> resuelve el binario desde cuatro fuentes por orden y devuelve la primera que funciona:",
"rows": [
{
"priority": "1",
"source": "<code>borg</code> del sistema",
"detail": "Si el host ya tiene <code>borg</code> instalado vía APT (<code>which borg</code> resuelve), se usa ese binario."
},
{
"priority": "2",
"source": "Caché del state-dir",
"detail": "<code>/usr/local/share/proxmenux/borg</code> — conservado de una descarga previa desde GitHub en este host."
},
{
"priority": "3",
"source": "Bundle del Monitor AppImage",
"detail": "<code>/usr/local/share/proxmenux/monitor-app/usr/bin/borg</code> — el AppImage incluye un binario borg-linux64 firmado. Este es el camino offline-safe: un host sin internet sigue teniendo un <code>borg</code> operativo."
},
{
"priority": "4",
"source": "Descarga desde GitHub",
"detail": "<code>wget</code> contra la URL fijada de <code>borg-linux64</code> bajo <code>github.com/borgbackup/borg/releases/</code>, verificado contra un SHA-256 constante en <code>lib_host_backup_common.sh</code> (<code>HB_BORG_LINUX64_SHA256</code>). Si el checksum no coincide, el binario se descarta y la copia se aborta. El fichero descargado se cachea en el state-dir para que las copias posteriores usen el camino 2."
}
]
},
"repoTypes": {
"heading": "Tipos de repositorio",
"intro": "El tipo de repositorio se elige al añadir un destino. Cada tipo se resuelve a una URL de repositorio que Borg entiende.",
"rows": [
{
"type": "remote",
"url": "ssh://USER@HOST/RPATH",
"detail": "El repositorio vive en un servidor remoto que ejecuta <code>borg serve</code>. Requiere una conexión SSH a ese servidor."
},
{
"type": "usb",
"url": "/mnt/MOUNTPOINT/borgbackup",
"detail": "El repositorio vive en un disco externo montado (típicamente USB). El punto de montaje se resuelve vía <code>hb_prompt_mounted_path</code>, que detecta, monta o formatea particiones USB según sea necesario."
},
{
"type": "local",
"url": "/backup/borgbackup (cualquier ruta absoluta)",
"detail": "El repositorio vive en un directorio local. Sólo tiene sentido cuando el directorio está en un disco físico distinto — un repositorio en el mismo disco que el origen protege contra error humano pero no contra fallo de disco."
}
]
},
"serverSetup": {
"heading": "Preparar el servidor Borg (lado servidor)",
"intro": "El tipo de repositorio <code>remote</code> espera un servidor Borg operativo accesible por SSH. ProxMenux no bootstrapea el servidor por sí mismo — sólo autoriza una clave contra una cuenta existente en él. Esta sección documenta lo que necesita el servidor antes de que ProxMenux pueda conectarse.",
"hostChoicesTitle": "Dónde puede vivir el servidor",
"hostChoicesBody": "Cualquier host Linux con acceso SSH cumple. Setups habituales:",
"hostChoicesItems": [
"Un NAS dedicado o caja de backup (Debian, Ubuntu, TrueNAS SCALE con shell).",
"Un contenedor LXC dentro de un nodo Proxmox. Huella pequeña, aislado del host que ejecuta las copias.",
"Otro host Proxmox en la misma LAN, o una VM en cualquier lugar alcanzable por SSH."
],
"lxcWarningTitle": "LXC como servidor Borg",
"lxcWarningBody": "Si el servidor Borg se ejecuta dentro de un LXC, el contenedor debe tener una cuenta de usuario con contraseña.",
"requirementsTitle": "Requisitos en el servidor",
"requirementsRows": [
{
"requirement": "binario borg en <code>/usr/bin/borg</code>",
"detail": "La línea <code>command=\"/usr/bin/borg serve ...\"</code> que ProxMenux escribe en <code>authorized_keys</code> hardcodea esa ruta. Instalar vía APT (<code>apt install borgbackup</code>) lo deja ahí. Un binario independiente debe symlinkarse a <code>/usr/bin/borg</code>."
},
{
"requirement": "Una cuenta de usuario dedicada (típicamente <code>borg</code>)",
"detail": "Es dueña del directorio del repositorio y recibe las conexiones SSH entrantes. No necesita sudo ni acceso a shell — la línea de authorized_keys desactiva las shells interactivas de todos modos."
},
{
"requirement": "Un directorio de repositorio escribible",
"detail": "La ruta que el usuario introduce en ProxMenux (por ejemplo <code>/backup/borgbackup</code>) debe existir en el servidor y ser propiedad del usuario borg."
},
{
"requirement": "Demonio SSH aceptando al usuario borg",
"detail": "<code>PubkeyAuthentication yes</code> (por defecto). La autenticación por contraseña sólo hace falta para el flujo puntual <em>generate-auto</em> — una vez instalada la clave, el servidor puede desactivar la autenticación por contraseña por completo."
}
],
"minimalSetupTitle": "Setup mínimo del servidor",
"minimalSetupBody": "En un servidor Borg Debian o Ubuntu, un baseline funcional son cuatro comandos como root:",
"minimalSetupCmd": "apt install borgbackup\nuseradd -m -d /home/borg -s /bin/bash borg\nmkdir -p /backup/borgbackup\nchown borg:borg /backup/borgbackup",
"minimalSetupNote": "Tras esto, el modo <code>generate-auto</code> de ProxMenux puede conectarse usando la contraseña del usuario borg una vez, instalar su propia clave SSH, y cada copia posterior usa esa clave. No hace falta más configuración en el servidor — la clave se restringe a sí misma a <code>borg serve</code> sobre esa ruta."
},
"sshAuth": {
"heading": "Autenticación SSH (lado cliente)",
"intro": "Los repositorios Borg remotos se acceden vía SSH. La conexión va desde el host ProxMenux a una cuenta de usuario en el servidor Borg que ejecuta <code>borg serve</code>. Ese usuario se llama típicamente <code>borg</code>, NO el usuario admin/root del servidor — la línea de comando de borg-serve bloquea la conexión a esa ruta concreta del repositorio (ver las estrategias de clave más abajo).",
"strategiesTitle": "Las cuatro estrategias de clave",
"strategiesIntro": "Al añadir un destino remoto, ProxMenux pregunta por el usuario SSH, host y ruta remota, y a continuación pregunta cómo autenticar. Cuatro modos:",
"strategyRows": [
{
"mode": "generate-auto",
"label": "Recomendado",
"detail": "ProxMenux genera una nueva keypair ed25519 en <code>~/.ssh/borg_proxmenux_HOST_ed25519</code>, y a continuación usa <code>sshpass</code> para hacer login UNA VEZ en el servidor con la contraseña de admin y añadir la clave pública a <code>~borg/.ssh/authorized_keys</code>. La contraseña de admin se usa sólo para esa única llamada — nunca se almacena."
},
{
"mode": "generate-manual",
"label": "Sin contraseña admin en este host",
"detail": "ProxMenux genera la keypair como arriba pero muestra la línea completa de <code>authorized_keys</code> para que el usuario la pegue manualmente en el servidor. La contraseña de admin nunca sale del host ProxMenux porque nunca se pregunta."
},
{
"mode": "generate-pct",
"label": "El servidor Borg es un LXC de PVE",
"detail": "El servidor Borg se ejecuta dentro de un LXC en un nodo PVE. ProxMenux autoriza la clave vía <code>pct exec</code> desde el host PVE — root en el host PVE escribe en el <code>~borg/.ssh/authorized_keys</code> del LXC sin necesidad de hacer SSH al LXC."
},
{
"mode": "existing",
"label": "Usar una clave existente",
"detail": "ProxMenux escanea <code>/root/.ssh/</code> y <code>$HOME/.ssh/</code> buscando claves privadas ed25519/RSA parseables y las lista. El usuario elige una o navega manualmente a una ruta no estándar."
},
{
"mode": "none",
"label": "Configuración SSH por defecto",
"detail": "Sin clave personalizada — Borg usa la configuración SSH por defecto del host (típicamente <code>~/.ssh/id_rsa</code> o un agente SSH)."
}
],
"restrictTitle": "La línea authorized_keys",
"restrictBody": "Para cada clave generada, la línea de <code>authorized_keys</code> que ProxMenux escribe en el servidor bloquea la clave a una única invocación de borg-serve contra la ruta configurada del repositorio:",
"restrictLine": "command=\"/usr/bin/borg serve --restrict-to-path RPATH\",restrict PUBKEY",
"restrictNote": "El <code>command=</code> fuerza que cada sesión SSH que use esta clave ejecute sólo ese comando borg-serve; <code>restrict</code> desactiva port forwarding, agent forwarding, X11 forwarding y asignación de PTY. La clave no se puede usar para abrir una shell interactiva en el servidor ni para acceder a ninguna otra ruta de repositorio, aunque la cuenta tenga privilegios más amplios."
},
"savedTargets": {
"heading": "Destinos guardados",
"intro": "Un destino guardado persiste la configuración del repositorio bajo un nombre amigable para no tener que reintroducir los detalles. Layout de almacenamiento en el directorio de estado de ProxMenux:",
"rows": [
{
"file": "borg-targets.txt",
"content": "Una línea por destino: <code>NAME|REPO|SSH_KEY_PATH|ENCRYPT_MODE</code>. La lee <code>hb_collect_borg_configs</code> para poblar el menú de selección de destino."
},
{
"file": "borg-pass-NAME.txt",
"content": "Passphrase del destino con el NAME dado arriba (<code>chmod 600</code>). Sólo está presente si el usuario eligió cifrado repokey."
}
],
"outro": "Guardar es opcional — el usuario puede rechazar el prompt de guardado para una copia puntual que no deje credenciales en el host."
},
"encryption": {
"heading": "Cifrado",
"body": "Los repositorios se inicializan con un modo de cifrado vía <code>hb_borg_init_if_needed</code>: <code>borg repo-create -e MODE</code> en versiones modernas, o el legacy <code>borg init --encryption=MODE</code>. ProxMenux expone dos modos: <code>repokey</code> (por defecto) y <code>none</code>. En modo <code>repokey</code>, Borg almacena la clave de cifrado dentro del propio repositorio; el acceso requiere una passphrase, que ProxMenux pregunta dos veces con validación de coincidencia y guarda en <code>borg-pass-NAME.txt</code>. Un diálogo de reconocimiento obligatorio se muestra tras guardar la passphrase: la passphrase es la única manera de acceder a los archivos cifrados, y perderla hace irrecuperable todo archivo del repositorio."
},
"runtimeEnv": {
"heading": "Entorno de ejecución",
"intro": "ProxMenux exporta las siguientes variables de entorno antes de invocar <code>borg</code>. Configuran la conexión y desbloquean el repositorio sin embeber secretos en la línea de comandos.",
"rows": [
{
"var": "BORG_RSH",
"value": "ssh -i SSH_KEY_PATH -o StrictHostKeyChecking=accept-new",
"purpose": "El comando de shell remoto que Borg usa para repositorios servidos por SSH. Se fija sólo cuando se seleccionó una clave personalizada; en caso contrario queda sin definir para que Borg use la configuración SSH por defecto."
},
{
"var": "BORG_PASSPHRASE",
"value": "(passphrase de borg-pass-NAME.txt)",
"purpose": "Desbloquea la repokey. Se fija sólo cuando el destino usa cifrado <code>repokey</code>. Nunca aparece en la lista de argumentos del proceso."
},
{
"var": "BORG_ENCRYPT_MODE",
"value": "repokey | none",
"purpose": "Lo usa <code>hb_borg_init_if_needed</code> al inicializar un repositorio que aún no existe. <code>borg create</code> lo ignora en repositorios existentes."
},
{
"var": "BORG_RELOCATED_REPO_ACCESS_IS_OK",
"value": "yes",
"purpose": "Suprime el prompt interactivo que Borg lanza cuando la URL del repositorio difiere de la URL desde la que se alcanzó originalmente (habitual tras un renombrado del punto de montaje o un cambio de dirección del host SSH)."
},
{
"var": "BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK",
"value": "yes",
"purpose": "Suprime el prompt interactivo que Borg lanza la primera vez que se accede a un repositorio sin cifrar desde un cliente nuevo."
}
]
},
"archiveFormat": {
"heading": "Nombrado de archivos y retención",
"intro": "Cada copia crea un archivo nuevo dentro del repositorio.",
"namePattern": "hostcfg-HOSTNAME-YYYYMMDD_HHMMSS",
"retentionBody": "Para trabajos programados, <code>run_scheduled_backup.sh</code> ejecuta <code>borg prune</code> contra el repositorio tras cada copia exitosa con los valores de retención configurados en el trabajo (<code>--keep-last</code>, <code>--keep-daily</code>, <code>--keep-weekly</code>). Las copias interactivas no aplican poda."
},
"restoreAccess": {
"heading": "Recuperación del lado de la restauración",
"body": "El flujo de restauración lista los archivos con <code>borg list REPO</code> y extrae el seleccionado con <code>borg extract REPO::ARCHIVE-NAME</code> a un directorio de staging que <code>_rs_check_layout</code> alimenta al pipeline estándar de restauración. Para recuperación manual fuera de ProxMenux, los mismos comandos funcionan; el árbol extraído es el layout estándar de tres bloques descrito en <em>Cómo funciona</em>."
},
"references": {
"heading": "Referencias",
"intro": "Documentación oficial de Borg para los componentes en los que se apoya ProxMenux.",
"items": [
{
"label": "Documentación de Borg",
"href": "https://borgbackup.readthedocs.io/",
"tail": " — punto de entrada principal, cubre conceptos, despliegue, quickstart y todos los comandos."
},
{
"label": "borg create",
"href": "https://borgbackup.readthedocs.io/en/stable/usage/create.html",
"tail": " — el comando que ProxMenux invoca en cada copia, con todas las flags soportadas."
},
{
"label": "Cifrado del repositorio",
"href": "https://borgbackup.readthedocs.io/en/stable/usage/init.html#encryption-mode",
"tail": " — los modos de cifrado que Borg soporta, incluido repokey que ProxMenux usa por defecto."
},
{
"label": "borg serve y despliegue SSH",
"href": "https://borgbackup.readthedocs.io/en/stable/deployment/central-backup-server.html",
"tail": " — cómo montar un servidor Borg central accedido por SSH, incluyendo el comando borg-serve y la flag restrict-to-path que ProxMenux escribe en authorized_keys."
},
{
"label": "borg prune",
"href": "https://borgbackup.readthedocs.io/en/stable/usage/prune.html",
"tail": " — el modelo de retención detrás de --keep-last / --keep-daily / --keep-weekly que ProxMenux aplica por trabajo programado."
}
]
}
}
@@ -0,0 +1,110 @@
{
"meta": {
"title": "Destinos de copia — Local, Proxmox Backup Server, Borg | ProxMenux",
"description": "Tres backends de almacenamiento reciben el mismo contenido de una copia de ProxMenux: un archivo local .tar.zst en cualquier sistema de ficheros escribible, un backup en un datastore de Proxmox Backup Server o un archivo en un repositorio local o remoto de Borg. Cada backend tiene sus propias características de compresión, deduplicación, cifrado y red.",
"ogTitle": "Destinos de ProxMenux Backup",
"ogDescription": "Local, Proxmox Backup Server y Borg — tres backends de almacenamiento para el mismo contenido de copia del host.",
"twitterTitle": "Destinos de ProxMenux Backup | ProxMenux",
"twitterDescription": "Archivo local, Proxmox Backup Server y Borg como backends para copias del host."
},
"header": {
"title": "Destinos",
"description": "Los tres backends de almacenamiento soportados por ProxMenux Backup: archivo local, Proxmox Backup Server (recomendado) y Borg. Cada uno recibe el mismo archivo de tres bloques; se diferencian en formato de almacenamiento, deduplicación, modelo de cifrado y requisitos de red.",
"section": "Backup & Restore"
},
"intro": {
"title": "El mismo contenido, tres backends",
"body": "Cada copia produce los mismos tres bloques (rootfs, manifiesto, aplicaciones). Lo que cambia entre destinos es cómo se almacenan esos bloques y cómo el usuario los recupera para una restauración. Cada backend está implementado como una función independiente en <code>backup_host.sh</code> — <code>_bk_local</code>, <code>_bk_pbs</code>, <code>_bk_borg</code> — pero los tres comparten el mismo paso de staging (<code>hb_prepare_staging</code>) y el mismo camino de restauración. La elección del destino sólo afecta a la escritura y la recuperación; no cambia lo que hace una restauración ni cómo consume el archivo."
},
"comparison": {
"heading": "Comparativa de características",
"intro": "La siguiente tabla lista las diferencias concretas entre los tres backends tal como se comportan hoy en ProxMenux. Los valores describen el comportamiento observado del backend en sí, no recomendaciones editoriales.",
"rows": [
{
"feature": "Formato de almacenamiento",
"local": "Un único fichero <code>.tar.zst</code> (o <code>.tar.gz</code> si <code>zstd</code> no está disponible).",
"pbs": "Backup PBS (chunks <code>.pxar</code> en el datastore).",
"borg": "Archivo Borg dentro de un repositorio Borg (ficheros de segmento)."
},
{
"feature": "Compresión",
"local": "zstd (nivel por defecto) mediante <code>tar --zstd</code>. Fallback a gzip.",
"pbs": "Gestionada por PBS. El cliente envía sin comprimir; el servidor chunkiza + comprime.",
"borg": "La integrada de Borg (lz4 por defecto). Configurable al inicializar el repo."
},
{
"feature": "Deduplicación",
"local": "Ninguna. Cada copia es un archivo completo independiente.",
"pbs": "Deduplicación completa a nivel de chunk entre todas las backups del datastore.",
"borg": "Deduplicación completa a nivel de chunk entre todos los archivos del repositorio."
},
{
"feature": "Cifrado en reposo",
"local": "Ninguno (depende de la protección a nivel de filesystem).",
"pbs": "Cifrado opcional del lado del cliente mediante keyfile. Si se activa, el blob de recuperación se sube como grupo de backups aparte.",
"borg": "Cifrado opcional repokey (la clave se guarda en el repo, se desbloquea con una passphrase)."
},
{
"feature": "Retención / poda",
"local": "Aplicada por trabajo programado vía <code>KEEP_LAST</code>. Los archivos antiguos (y sus sidecars + logs del runner) se eliminan de forma simétrica. Las copias interactivas no aplican poda.",
"pbs": "Aplicada por trabajo programado vía <code>proxmox-backup-client prune --keep-last / --keep-daily / --keep-weekly</code>. Las copias interactivas no aplican poda.",
"borg": "Aplicada por trabajo programado vía <code>borg prune --keep-last / --keep-daily / --keep-weekly</code>. Las copias interactivas no aplican poda."
},
{
"feature": "Red",
"local": "Ninguna. Escribe en un punto de montaje local (típicamente un disco interno o una unidad USB).",
"pbs": "TCP contra el servidor PBS (puerto por defecto 8007). Requiere credenciales PBS + fingerprint.",
"borg": "Ruta local de sistema de ficheros o túnel SSH a un host Borg remoto."
},
{
"feature": "Dependencias",
"local": "<code>tar</code>, <code>zstd</code> (presentes en Proxmox por defecto).",
"pbs": "Paquete <code>proxmox-backup-client</code> (incluido en Proxmox VE 8+).",
"borg": "Binario <code>borg</code>. ProxMenux lo provisiona automáticamente desde el bundle del Monitor AppImage cuando no está presente."
},
{
"feature": "Acceso a la restauración",
"local": "Cualquier host con tar+zstd puede extraer el archivo. No se necesita PBS ni Borg.",
"pbs": "Requiere <code>proxmox-backup-client</code> + credenciales PBS + el keyfile (si está cifrado).",
"borg": "Requiere <code>borg</code> + la ruta del repositorio + la passphrase (si está cifrado)."
}
],
"captionCode": "Característica",
"captionLocal": "Local",
"captionPbs": "Proxmox Backup Server (recomendado)",
"captionBorg": "Borg"
},
"sameArchive": {
"heading": "El layout del archivo no cambia con el destino",
"body": "Dentro de cualquiera de los tres destinos está presente el mismo layout <code>rootfs/</code> + <code>metadata/</code> + <code>manifest.json</code> descrito en <em>Cómo funciona</em>. Un <code>.tar.zst</code> extraído de un archivo local, un <code>.pxar</code> restaurado desde PBS y un archivo Borg extraído con <code>borg extract</code> producen todos un árbol de directorios idéntico. El camino de código de la restauración (<code>_rs_check_layout</code>, <code>_rs_apply</code>, <code>_rs_prepare_pending_restore</code>) lee los mismos tres bloques sin saber de qué destino vienen."
},
"extractStandalone": {
"heading": "Extraer una copia fuera de ProxMenux",
"intro": "Cualquiera de los tres formatos de archivo se puede leer con herramientas estándar sin tener ProxMenux instalado en el host de lectura. Los comandos siguientes producen el mismo árbol de directorios que consume internamente una restauración.",
"localCmd": "# Desde un archivo local .tar.zst:\ntar --zstd -xf hostcfg-HOST-TIMESTAMP.tar.zst\n\n# Desde el fallback .tar.gz:\ntar -xzf hostcfg-HOST-TIMESTAMP.tar.gz",
"pbsCmd": "# Desde un backup PBS (requiere proxmox-backup-client):\nproxmox-backup-client restore \\\n --repository USER@REALM@HOST:DATASTORE \\\n host/hostcfg-HOST/BACKUP-TIME \\\n hostcfg.pxar /tmp/hostcfg\n\n# Añadir --keyfile KEY-PATH cuando el backup está cifrado.",
"borgCmd": "# Desde un archivo Borg (requiere el binario borg + passphrase si hay cifrado):\nborg extract REPO-PATH::ARCHIVE-NAME\n\n# Sobre un repo servido por SSH:\nborg extract ssh://USER@HOST:PORT/REPO-PATH::ARCHIVE-NAME",
"note": "El árbol extraído puede inspeccionarse manualmente o alimentar una restauración manual. Consulta las páginas de cada destino para conocer el flujo exacto de recuperación que ProxMenux utiliza por dentro."
},
"whereNext": {
"heading": "Detalle por destino",
"intro": "Cada destino tiene su propia página con el flujo de configuración, el formato en disco y el comando de recuperación que utiliza la restauración.",
"items": [
{
"label": "Archivo local",
"href": "/docs/backup-restore/destinations/local",
"tail": " — preconfiguración del destino local, montaje de unidades USB, el chequeo de seguridad contra escribir el archivo dentro de sí mismo, el sidecar JSON que permite al Monitor identificar el fichero."
},
{
"label": "Proxmox Backup Server (recomendado)",
"href": "/docs/backup-restore/destinations/pbs",
"tail": " — selección de datastore, credenciales y fingerprint, ciclo de vida del keyfile de cifrado, passphrase de recuperación, subida del blob de recuperación a PBS para recuperación tras reinstalación."
},
{
"label": "Borg",
"href": "/docs/backup-restore/destinations/borg",
"tail": " — repositorios locales vs. servidos por SSH, cómo se obtiene el binario Borg (sistema / caché / bundle del Monitor AppImage / descarga de GitHub), inicialización del repositorio, gestión de la passphrase, setup de claves SSH para repos remotos."
}
]
}
}
@@ -0,0 +1,75 @@
{
"meta": {
"title": "Destino de archivo local — tar.zst en filesystem o unidad USB | ProxMenux",
"description": "El destino local de la copia escribe un único archivo .tar.zst en cualquier directorio escribible: un disco interno, un punto de montaje de Proxmox, un share NFS o una unidad USB. Documenta el flujo de configuración, la lógica de detección y montaje USB, el chequeo de seguridad contra escribir el archivo dentro de una ruta que se está copiando, y el sidecar JSON que identifica el fichero.",
"ogTitle": "ProxMenux Backup — Destino local",
"ogDescription": "Cómo escribe ProxMenux las copias locales como archivos .tar.zst y cómo configurar el directorio de destino o la unidad USB.",
"twitterTitle": "Destino local de copia | ProxMenux",
"twitterDescription": "Cómo escribe ProxMenux las copias locales como archivos .tar.zst en filesystem o USB."
},
"header": {
"title": "Archivo local",
"description": "El destino local escribe un único archivo tar comprimido en cualquier directorio escribible del host: un disco interno, un montaje NFS o SMB, o una unidad USB.",
"section": "Backup & Restore"
},
"intro": {
"title": "Un solo fichero, autocontenido",
"body": "Una copia local produce un único fichero <code>hostcfg-HOST-TIMESTAMP.tar.zst</code> (o <code>.tar.gz</code> cuando <code>zstd</code> no está presente). El fichero contiene el árbol completo del archivo — <code>manifest.json</code>, <code>metadata/</code> y <code>rootfs/</code> — y puede restaurarse en cualquier host Proxmox con el flujo de restauración de ProxMenux, o extraerse a mano con <code>tar --zstd -xf</code> en cualquier sistema Linux. Sin servidor, sin inicialización de repositorio, sin dependencia externa. Es el destino con el camino de recuperación más corto cuando ni PBS ni Borg están disponibles."
},
"targetConfig": {
"heading": "Configurar el directorio de destino",
"intro": "El destino local es un <strong>único directorio de destino persistido</strong> — no una lista. ProxMenux guarda la elección del usuario en <code>/usr/local/share/proxmenux/local-target.conf</code> y la lee en cada copia. Cuando no hay ningún destino configurado, se usa el valor por defecto <code>HB_LOCAL_TARGET_DEFAULT = /var/lib/vz/dump</code> (el mismo directorio que Proxmox utiliza para las salidas de <code>vzdump</code>). El destino se configura desde <em>Configure backup destinations → Local destinations</em>:",
"options": [
"<strong>Usar el valor por defecto (<code>/var/lib/vz/dump</code>).</strong> El almacenamiento local de Proxmox. Está presente en cualquier instalación de Proxmox; el archivo queda junto a las salidas de vzdump y lo detecta automáticamente la pestaña Backups del Monitor.",
"<strong>Introducir una ruta personalizada.</strong> Cualquier ruta absoluta del sistema de ficheros vale: un montaje NFS, un share SMB montado por <code>fstab</code>, un dataset ZFS dedicado, un segundo disco interno. ProxMenux valida que la ruta existe y es un directorio antes de persistirla.",
"<strong>Elegir una unidad USB.</strong> Abre el submenú USB (más abajo), que detecta los dispositivos extraíbles y ofrece montar o formatear uno."
]
},
"usbFlow": {
"heading": "Detección y montaje de la unidad USB",
"intro": "El submenú USB lista las particiones de los dispositivos extraíbles reportados por <code>lsblk</code>. Cada partición se muestra con su tamaño, etiqueta del filesystem y estado actual. El estado determina la acción que ProxMenux ofrece.",
"statesTitle": "Los tres estados del dispositivo",
"stateRows": [
{
"state": "mounted",
"shown": "Tamaño · label · [fstype] · → /punto/de/montaje",
"action": "La partición ya está montada en algún sitio. Seleccionarla persiste ese punto de montaje como destino local. No se realiza ningún montaje."
},
{
"state": "unmounted",
"shown": "Tamaño · label · [fstype] · (no montada — se montará)",
"action": "Hay un filesystem pero no está montado. Al confirmar, ProxMenux ejecuta <code>hb_mount_usb_partition</code>: crea <code>/mnt/backup-LABEL</code> (o una ruta basada en UUID si no hay label), monta la partición y persiste el punto de montaje como destino local."
},
{
"state": "empty",
"shown": "Tamaño · disco USB en crudo — sin filesystem (se FORMATEARÁ)",
"action": "El dispositivo no tiene filesystem. Camino destructivo — protegido por dos confirmaciones. Primero un diálogo Yes/No explica que la operación borrará el disco. Después una caja de entrada obliga al usuario a <strong>escribir la ruta exacta del dispositivo</strong> (por ejemplo <code>/dev/sdb</code>) antes de que ProxMenux cree una partición GPT + ext4 fresca y la monte."
}
],
"notMountedFallback": "Cuando no se detecta ningún dispositivo USB, el submenú cae en un inputbox simple. El usuario puede introducir una ruta de punto de montaje arbitraria; si la ruta no es un punto de montaje registrado, un diálogo de confirmación advierte antes de continuar."
},
"safetyCheck": {
"heading": "Chequeo de seguridad — destino dentro de una ruta copiada",
"body": "Antes de escribir el archivo, <code>_bk_local</code> verifica que el directorio de destino <strong>no</strong> sea un subcamino de ninguno de los directorios que se están copiando. Un footgun habitual sería añadir <code>/root</code> al perfil y elegir <code>/root/backups</code> como destino — el archivo se incluiría a sí mismo, produciendo o bien un archivo corrupto o bien crecimiento sin límite hasta llenar el disco. El chequeo resuelve ambos caminos con <code>readlink -m</code>, los compara y, si hay conflicto, aborta la copia con un diálogo que nombra la ruta en conflicto y lista tres formas de resolverlo: elegir un destino fuera de la ruta en conflicto, eliminar la entrada personalizada que contiene el destino, o usar modo Custom para desmarcar la ruta en conflicto en esa ejecución."
},
"archiveFormat": {
"heading": "Formato de archivo y compresión",
"intro": "El nombre del fichero de salida incorpora el hostname del origen y el timestamp de la copia para que un directorio con varios archivos se ordene cronológicamente y cada fichero se identifique por sí mismo.",
"namePattern": "hostcfg-HOSTNAME-YYYYMMDD_HHMMSS.tar.zst",
"compressionTitle": "Compresión",
"compressionBody": "El camino principal usa <code>tar --zstd -cf</code> — un pipeline de un solo comando que comprime al nivel por defecto de zstd. Cuando <code>zstd</code> no está presente en el origen (raro en Proxmox pero posible en instalaciones minimalistas), ProxMenux cae en <code>gzip</code>. En el camino de fallback, si <code>pv</code> está disponible, se añade una barra de progreso al pipeline para que el usuario vea crecer el tamaño del archivo en tiempo real; sin <code>pv</code>, se usa <code>tar -czf</code> plano en silencio.",
"sourceTitle": "Qué entra en el archivo",
"sourceBody": "El comando tar se invoca con <code>-C \"$staging_root\" .</code>, lo que archiva la <strong>raíz de staging completa</strong>: <code>rootfs/</code>, <code>metadata/</code> y <code>manifest.json</code>. Los tres bloques quedan uno al lado del otro en el nivel superior del tarball. Extraer el archivo produce exactamente el mismo árbol que consume el código de restauración."
},
"sidecar": {
"heading": "El sidecar JSON",
"intro": "Cada copia local con éxito produce un fichero compañero: <code>HOSTNAME-TIMESTAMP.tar.zst.proxmenux.json</code>, escrito junto al archivo por <code>hb_write_archive_sidecar</code>. Este pequeño fichero JSON permite al Monitor de ProxMenux identificar el archivo como una copia de host de ProxMenux incluso si posteriormente se mueve, renombra o archiva en otro lugar.",
"contentTitle": "Contenido del sidecar",
"contentBody": "El sidecar almacena la versión de schema, si la copia viene de una ejecución interactiva o de un trabajo programado (<code>kind</code>), el ID de trabajo para las ejecuciones programadas, el modo de perfil usado (<code>default</code> o <code>custom</code>), el hostname del origen, el basename original del archivo, un timestamp de creación en ISO-8601 y el tamaño del archivo en bytes.",
"whyBody": "La pestaña Backups del Monitor escanea los directorios locales configurados buscando sidecars <code>*.proxmenux.json</code> — no ficheros <code>*.tar.zst</code> — porque un <code>.tar.zst</code> sin sidecar podría no ser una copia de ProxMenux en absoluto. El escaneo es rápido (los JSON son diminutos) y el emparejamiento es estable frente a renombrados del archivo mientras el sidecar se renombre en paralelo."
},
"restoreAccess": {
"heading": "Restaurar desde un archivo local",
"body": "El flujo de restauración de ProxMenux descubre los archivos locales escaneando el destino local configurado buscando sidecars y mostrándolos en la lista de copias disponibles. Seleccionar uno dispara <code>_rs_check_layout</code>, que extrae el tarball en un directorio de staging y confirma el layout de tres bloques antes de continuar. Para una extracción manual fuera de ProxMenux, <code>tar --zstd -xf hostcfg-HOSTNAME-TIMESTAMP.tar.zst -C /tmp/hostcfg</code> produce el mismo árbol que consume el código de restauración."
}
}
@@ -0,0 +1,102 @@
{
"meta": {
"title": "Destino Proxmox Backup Server — repositorio, cifrado, recuperación | ProxMenux",
"description": "El destino PBS escribe las copias de host de ProxMenux como backups PBS. Documenta la auto-detección del repositorio desde /etc/pve/storage.cfg, la configuración manual de PBS, el comando de subida .pxar, el modelo de cifrado por keyfile del lado del cliente, el blob de escrow con passphrase de recuperación, y la recuperación del keyfile desde PBS en instalaciones frescas.",
"ogTitle": "ProxMenux Backup — destino Proxmox Backup Server",
"ogDescription": "Cómo escribe ProxMenux las copias de host en Proxmox Backup Server con cifrado por keyfile del lado del cliente y escrow de recuperación.",
"twitterTitle": "Destino PBS de copia | ProxMenux",
"twitterDescription": "Destino Proxmox Backup Server con cifrado por keyfile y escrow de passphrase de recuperación."
},
"header": {
"title": "Proxmox Backup Server",
"description": "El destino PBS sube la raíz de staging como un único backup .pxar a un datastore de Proxmox Backup Server, con cifrado opcional por keyfile del lado del cliente y escrow automático de una passphrase de recuperación para recuperación tras reinstalación.",
"section": "Backup & Restore"
},
"recommendedBadge": "Destino recomendado",
"aboutPbs": {
"heading": "Qué es Proxmox Backup Server",
"body": "Proxmox Backup Server (PBS) es el producto de servidor de copias propio de Proxmox, desarrollado y mantenido por el mismo equipo que autora Proxmox VE. Es un servidor dedicado diseñado para recibir copias desde hosts Proxmox VE (VMs, LXCs y — vía <code>proxmox-backup-client</code> — directorios arbitrarios del host) con deduplicación a nivel de chunk, cifrado del lado del cliente y políticas de retención aplicadas del lado del servidor. ProxMenux usa PBS como uno de los tres destinos para copias del host; cada mecanismo específico de PBS descrito en esta página (grupos de copia, archivos <code>.pxar</code>, <code>--backup-id</code>, cifrado por keyfile) es comportamiento estándar de PBS."
},
"intro": {
"title": "Un backup por ejecución, deduplicación a nivel de chunk",
"body": "Una copia PBS produce una única entrada en el datastore, agrupada bajo el backup ID <code>host/hostcfg-HOSTNAME/BACKUP-TIME</code>. El contenido es un archivo <code>.pxar</code> con el mismo layout de tres bloques descrito en <em>Cómo funciona</em>. PBS deduplica a nivel de chunk en todas las copias del datastore, por lo que las copias siguientes del mismo host transfieren y almacenan sólo los chunks que hayan cambiado. La retención la aplica el propio ProxMenux para los trabajos programados — <code>run_scheduled_backup.sh</code> ejecuta <code>proxmox-backup-client prune</code> con <code>--keep-last</code> / <code>--keep-daily</code> / <code>--keep-weekly</code> tras cada ejecución exitosa usando los valores configurados en el trabajo."
},
"repoSelection": {
"heading": "Selección del repositorio",
"intro": "ProxMenux descubre repositorios PBS desde dos fuentes en cada copia. El usuario elige uno desde un menú unificado; la elección determina <code>HB_PBS_REPOSITORY</code>, <code>HB_PBS_SECRET</code> y <code>HB_PBS_FINGERPRINT</code> para esa ejecución.",
"sourceRows": [
{
"source": "storage.cfg de Proxmox (auto-descubierto)",
"path": "/etc/pve/storage.cfg + /etc/pve/priv/storage/NAME.pw",
"content": "Cualquier entrada <code>pbs:</code> del propio storage de Proxmox se recoge automáticamente. Servidor, datastore, usuario y fingerprint vienen de la entrada. La contraseña se lee del directorio de credenciales propio de Proxmox. Sin re-introducción por el lado de ProxMenux — el repositorio queda disponible tan pronto como se configura en Proxmox."
},
{
"source": "Configuración manual de ProxMenux",
"path": "/usr/local/share/proxmenux/pbs-manual-configs.txt + pbs-pass-NAME.txt + pbs-fingerprint-NAME.txt",
"content": "Se añade desde <em>Configure backup destinations → PBS destinations → Add PBS</em>. Pregunta por un nombre, usuario (<code>root@pam</code> o <code>user@pbs!token</code>), host o IP, datastore y contraseña. La contraseña se re-pregunta ante entrada vacía — un guardado vacío persistiría silenciosamente y cada copia posterior fallaría con un error de autenticación opaco. Este camino se usa cuando el PBS objetivo no está registrado como storage de Proxmox."
}
],
"menuTitle": "Menú de selección",
"menuBody": "Ambas fuentes se muestran en un único menú, cada fila etiquetada con su origen (<code>[proxmox]</code> o <code>[manual]</code>). Las entradas cuya contraseña no se pudo resolver se marcan con un aviso <code>⚠ no password</code> — seleccionarlas dispara una re-introducción de contraseña antes de iniciar la copia. El fingerprint se pasa a <code>proxmox-backup-client</code> vía la variable de entorno <code>PBS_FINGERPRINT</code>; cuando no está presente, el cliente pide al usuario aceptar el certificado del servidor de forma interactiva en la primera copia."
},
"backupCommand": {
"heading": "El comando de copia",
"intro": "La subida es una única invocación de <code>proxmox-backup-client backup</code>. ProxMenux la ejecuta dentro de un envoltorio <code>env</code> para que las credenciales nunca aparezcan en la lista de argumentos del proceso.",
"cmd": "env \\\n PBS_PASSWORD=\"$HB_PBS_SECRET\" \\\n PBS_ENCRYPTION_PASSWORD=\"$HB_PBS_ENC_PASS\" \\\n PBS_FINGERPRINT=\"$HB_PBS_FINGERPRINT\" \\\n proxmox-backup-client backup \\\n hostcfg.pxar:$staging_root \\\n --repository USER@REALM@HOST:DATASTORE \\\n --backup-type host \\\n --backup-id hostcfg-HOSTNAME \\\n --backup-time BACKUP-EPOCH \\\n [--keyfile /usr/local/share/proxmenux/pbs-key.conf]",
"backupIdTitle": "Nombrado del backup ID",
"backupIdBody": "El backup ID por defecto es <code>hostcfg-HOSTNAME</code>. Se pide al usuario que lo confirme o edite antes de la subida; cualquier carácter fuera de <code>[A-Za-z0-9_-]</code> se elimina y los guiones finales se recortan. Reutilizar el mismo ID entre ejecuciones es intencional — PBS trata el ID como un <em>grupo</em>, y cada copia posterior aparece como un nuevo backup dentro de ese grupo, compartiendo dedup con las ejecuciones previas.",
"pxarTitle": "Por qué el origen es la raíz de staging completa",
"pxarBody": "El origen del <code>.pxar</code> es la <code>staging_root</code> entera — <code>rootfs/</code>, <code>metadata/</code> y <code>manifest.json</code> juntos. Versiones anteriores pasaban <code>$staging_root/rootfs</code> como origen; eso dejaba <code>metadata/</code> fuera del archivo y el chequeo de compatibilidad de la restauración no tenía nada que leer, degradándose a avisos cross-host incluso en restauraciones al mismo host. Los backups antiguos creados con el origen rootfs-only siguen restaurándose correctamente gracias a la rama caso-3 de <code>_rs_check_layout</code>, que envuelve un árbol plano <code>etc/var/root/usr</code> de vuelta en una jerarquía <code>rootfs/</code>."
},
"encryption": {
"heading": "Cifrado del lado del cliente",
"intro": "El cifrado por keyfile del lado del cliente de PBS cifra los chunks en el host de origen antes de la subida. ProxMenux habilita esta funcionalidad con una restricción añadida: la passphrase de recuperación es obligatoria cuando se activa el cifrado. La passphrase no protege el keyfile local; protege la copia de escrow del keyfile que ProxMenux sube a PBS para recuperación ante desastre.",
"keyfileTitle": "Keyfile",
"keyfileBody": "En el primer uso, <code>proxmox-backup-client key create --kdf none</code> genera el keyfile en <code>/usr/local/share/proxmenux/pbs-key.conf</code> (<code>chmod 600</code>). Las copias posteriores lo reutilizan tras un único diálogo de confirmación. Si la creación del keyfile falla, la copia se cancela y la salida de error de la herramienta se muestra en un diálogo.",
"recoveryTitle": "Passphrase de recuperación y blob de escrow",
"recoveryBody": "Tras crear el keyfile, ProxMenux pregunta dos veces por una passphrase de recuperación (con validación de coincidencia) y ejecuta <code>openssl</code> para producir <code>pbs-key.recovery.enc</code> — el keyfile cifrado con la passphrase. Se escribe una copia en <code>/root/pbs-key.recovery-HOSTNAME-YYYYMMDD.enc</code> para almacenamiento offsite. Cancelar el diálogo de la passphrase borra el keyfile recién creado.",
"blobUploadTitle": "Grupo emparejado en PBS",
"blobUploadBody1": "Tras una copia PBS que usó el keyfile, el blob de escrow se sube como un segundo grupo de copia: <code>host/hostcfg-HOSTNAME-keyrecovery/BACKUP-TIME</code>. El prefijo compartido <code>hostcfg-HOSTNAME</code> coloca ambos grupos adyacentes en la interfaz de PBS; el sufijo <code>-keyrecovery</code> etiqueta la relación. La subida se ejecuta sin <code>--keyfile</code> (el blob ya está protegido con passphrase por openssl) y sólo cuando la copia actual usó el keyfile.",
"blobUploadConstraintTitle": "Por qué dos grupos",
"blobUploadConstraintBody": "<code>--keyfile</code> es un flag por invocación en <code>proxmox-backup-client backup</code>: todos los archivos de una misma invocación se cifran con el keyfile o ninguno. <code>hostcfg.pxar</code> requiere cifrado; <code>keyrecovery.conf</code> no puede cifrarse con el mismo keyfile (la recuperación en instalación fresca requeriría el propio keyfile que pretende recuperar). Dos invocaciones, dos backup IDs.",
"blobUploadImageAlt": "Interfaz de PBS mostrando los grupos hostcfg-HOSTNAME y hostcfg-HOSTNAME-keyrecovery adyacentes en el listado del datastore.",
"blobUploadImageCaption": "Interfaz de PBS — los grupos de copia emparejados. El grupo principal contiene las copias del host; el grupo -keyrecovery contiene el blob de escrow.",
"recoverTitle": "Recuperación en instalación fresca",
"recoverBody": "En un host sin keyfile local, el flujo de restauración llama a <code>hb_pbs_try_keyfile_recovery</code>. La función lista los grupos keyrecovery del PBS configurado, descarga el más reciente y pregunta por la passphrase. En caso de éxito, <code>pbs-key.conf</code> se escribe en el directorio de estado de ProxMenux y la copia cifrada puede restaurarse. Sin el keyfile y la passphrase, la copia cifrada no es recuperable."
},
"restoreAccess": {
"heading": "Recuperación del lado de la restauración",
"body": "El flujo de restauración descubre las copias de host de ProxMenux en PBS listando los grupos de backups bajo el repositorio configurado y filtrando por patrón de backup ID. La pestaña Backups del Monitor renderiza la misma lista. Seleccionar un backup dispara <code>proxmox-backup-client restore</code> con el mismo repositorio + contraseña + fingerprint (y <code>--keyfile</code> cuando el backup iba cifrado), extrayendo el <code>.pxar</code> a un directorio de staging que <code>_rs_check_layout</code> alimenta al pipeline estándar de restauración. Para recuperación manual fuera de ProxMenux, el mismo comando extrae el archivo a cualquier ruta — el árbol resultante puede inspeccionarse o alimentar una restauración a mano."
},
"references": {
"heading": "Referencias",
"intro": "Documentación oficial de Proxmox Backup Server para los componentes en los que se apoya ProxMenux.",
"items": [
{
"label": "Documentación de Proxmox Backup Server",
"href": "https://pbs.proxmox.com/docs/",
"tail": " — punto de entrada principal, cubre instalación, administración, almacenamiento, usuarios y roles."
},
{
"label": "proxmox-backup-client",
"href": "https://pbs.proxmox.com/docs/backup-client.html",
"tail": " — la herramienta de línea de comandos que ProxMenux invoca en cada copia y restauración. Cubre backup IDs, tipos de backup, archivos, sintaxis del repositorio y variables de entorno."
},
{
"label": "Cifrado del lado del cliente",
"href": "https://pbs.proxmox.com/docs/backup-client.html#encryption",
"tail": " — creación del keyfile, modos --kdf, el modelo de cifrado que ProxMenux extiende con un escrow de passphrase."
},
{
"label": "Gestión de datastores",
"href": "https://pbs.proxmox.com/docs/storage.html",
"tail": " — creación y administración de los datastores que reciben las copias de host, incluyendo el layout del chunk-store y permisos."
},
{
"label": "Poda y recolección de basura",
"href": "https://pbs.proxmox.com/docs/maintenance.html#pruning",
"tail": " — el modelo de retención detrás de --keep-last / --keep-daily / --keep-weekly que ProxMenux aplica por trabajo programado, más cómo PBS reclama chunks tras podar."
}
]
}
}
@@ -0,0 +1,199 @@
{
"meta": {
"title": "Cómo funciona ProxMenux Backup por dentro — rootfs, manifiesto, aplicaciones",
"description": "Desglose detallado del contenido de una copia de ProxMenux: el rootfs producido por rsync del perfil de rutas por defecto, el manifiesto estructurado construido por seis colectores independientes, y el inventario de aplicaciones que dirige la reinstalación automática de paquetes y componentes tras una restauración.",
"ogTitle": "Cómo funciona ProxMenux Backup por dentro",
"ogDescription": "Los tres bloques de una copia de ProxMenux explicados: rootfs, manifiesto y aplicaciones.",
"twitterTitle": "Cómo funciona ProxMenux Backup | ProxMenux",
"twitterDescription": "Los tres bloques de una copia de ProxMenux y cómo la restauración reproduce el host de origen a partir de ellos."
},
"header": {
"title": "Cómo funciona",
"description": "Desglose interno de una copia de ProxMenux — sistema de ficheros, manifiesto e inventario de aplicaciones — y cómo la restauración consume los tres para reproducir el host de origen sobre un destino que puede no compartir el mismo kernel.",
"section": "Backup & Restore"
},
"intro": {
"title": "Un archivo, tres bloques",
"body": "Cada copia produce un layout de directorio con tres bloques bien definidos bajo una única raíz de staging. El archivo que se sube al destino (archivo local <code>.tar.zst</code>, backup PBS o archivo Borg) contiene ese layout exacto. La restauración lee los tres bloques de forma independiente, en un orden concreto que garantiza la corrección: primero se copia el <strong>rootfs</strong> para colocar la configuración, después se consulta <strong>el manifiesto</strong> para detectar drift y decidir qué omitir, y finalmente <strong>el inventario de aplicaciones</strong> dirige la pasada de reinstalación post-arranque. No hay dependencias entre bloques — cada uno puede inspeccionarse o extraerse de forma independiente."
},
"layout": {
"heading": "Layout del archivo",
"intro": "Cada archivo respeta el mismo layout con independencia del destino. El subdirectorio <code>metadata/</code> contiene los bloques estructurados; el subdirectorio <code>rootfs/</code> contiene la copia del sistema de ficheros.",
"treeCaption": "El directorio de staging generado durante una copia. Todos los destinos reciben el mismo árbol (adaptado a su formato nativo: tar para local, chunks PBS para PBS, segmentos borg para Borg).",
"tree": "backup-[timestamp]/\n├── manifest.json # estado estructurado del host\n├── metadata/\n│ ├── packages.manual.list # apt-mark showmanual\n│ ├── run_info.env # identidad de la ejecución + versión del kernel\n│ ├── paths_archived.txt # lista exacta de rutas que llegaron a rootfs/\n│ └── missing_paths.txt # rutas del perfil ausentes en el origen\n└── rootfs/\n ├── etc/ # /etc/pve, /etc/network, /etc/ssh, …\n ├── root/ # /root (con subdirs volátiles excluidos)\n ├── usr/local/ # /usr/local/bin, /usr/local/share/proxmenux, …\n └── var/ # /var/lib/pve-cluster, /var/spool/cron/…"
},
"rootfs": {
"heading": "El bloque rootfs",
"intro": "El árbol <code>rootfs/</code> es una <strong>copia plana del sistema de ficheros</strong> producida por <code>rsync</code> desde el host de origen. Contiene un <strong>perfil por defecto</strong> curado de rutas que importan para una restauración de Proxmox, más cualquier <strong>ruta personalizada</strong> añadida por el usuario al trabajo de copia o a la sesión interactiva. El conjunto es intencionadamente estrecho: solamente rutas que <em>contienen configuración</em> o <em>contienen estado que Proxmox no puede regenerar por sí solo</em>.",
"defaultProfileTitle": "El perfil por defecto",
"defaultProfileBody": "El perfil por defecto está definido por <code>hb_default_profile_paths</code> en <code>lib_host_backup_common.sh</code>. Cubre ocho categorías que en conjunto describen un host Proxmox operativo:",
"categoriesTitle": "Categorías de rutas",
"categoryRows": [
{
"category": "Núcleo PVE",
"paths": "/etc/pve, /var/lib/pve-cluster, /etc/vzdump.conf",
"why": "Contenido del filesystem del clúster, datos vivos del clúster, valores por defecto de vzdump."
},
{
"category": "Identidad del host y red",
"paths": "/etc/hostname, /etc/hosts, /etc/timezone, /etc/resolv.conf, /etc/network",
"why": "Todo lo necesario para que el host arranque en red con la misma identidad."
},
{
"category": "Acceso y autenticación",
"paths": "/etc/ssh, /etc/sudoers, /etc/sudoers.d, /etc/pam.d, /etc/security",
"why": "Claves SSH, reglas de sudo y configuración de PAM. Perderlas deja al usuario fuera del host restaurado."
},
{
"category": "Kernel y arranque",
"paths": "/etc/default/grub, /etc/kernel, /etc/modules, /etc/modules-load.d, /etc/modprobe.d, /etc/sysctl.conf, /etc/sysctl.d, /etc/udev/rules.d, /etc/fstab, /etc/iscsi, /etc/multipath",
"why": "Tokens IOMMU, blacklists de módulos, IDs de dispositivos VFIO, tabla de montaje, configuración del stack de almacenamiento."
},
{
"category": "Shell y locale",
"paths": "/etc/environment, /etc/bash.bashrc, /etc/inputrc, /etc/profile, /etc/profile.d, /etc/locale.gen, /etc/locale.conf",
"why": "Configuración de shell a nivel de sistema, variables de entorno, generación de locales."
},
{
"category": "Paquetería y cron",
"paths": "/etc/apt, /etc/cron.d, /etc/cron.{daily,hourly,weekly,monthly}, /etc/cron.allow, /etc/cron.deny, /var/spool/cron/crontabs",
"why": "Fuentes APT para resolución consistente de paquetes, tareas programadas definidas por el usuario."
},
{
"category": "Estado ProxMenux y herramientas",
"paths": "/etc/proxmenux, /etc/systemd/system, /etc/log2ram.conf, /etc/logrotate.conf, /etc/logrotate.d, /etc/lm-sensors, /etc/sensors3.conf, /etc/fail2ban, /etc/snmp, /etc/postfix, /etc/wireguard, /etc/openvpn, /etc/grafana, /etc/influxdb, /etc/prometheus, /etc/telegraf, /etc/zabbix",
"why": "Herramientas opcionales pero habituales de Proxmox. Las rutas ausentes se registran en <code>metadata/missing_paths.txt</code> sin detener la copia."
},
{
"category": "Binarios ProxMenux y root",
"paths": "/usr/local/bin, /usr/local/sbin, /usr/local/share/proxmenux, /root (subdirs volátiles excluidos)",
"why": "Binarios instalados por ProxMenux y configuración por usuario bajo <code>/root</code>. Las rutas volátiles (<code>.bash_history</code>, <code>.cache/</code>, <code>tmp/</code>, <code>.local/share/Trash/</code>) quedan fuera de la copia."
},
{
"category": "Estado ZFS (condicional)",
"paths": "/etc/zfs",
"why": "Sólo se incluye cuando el host de origen usa ZFS. Contiene <code>zpool.cache</code> y <code>hostid</code>."
}
],
"customTitle": "Ampliar el perfil con rutas propias",
"customBody": "Además del perfil por defecto, ProxMenux ofrece dos maneras de incluir rutas adicionales en una copia. Se combinan sin conflicto y ambas se aplican tanto a copias interactivas como a trabajos programados.",
"customExtrasTitle": "1. Extras persistentes (fichero por-host)",
"customExtrasBody": "Un fichero de texto en <code>/usr/local/share/proxmenux/backup-extra-paths.txt</code> guarda una lista de rutas absolutas que el usuario ha marcado como \"incluir siempre\" en este host. Cuando una copia se ejecuta en modo <strong>Default</strong>, ProxMenux añade automáticamente estas rutas al perfil por defecto sin preguntar. El fichero se edita desde la interfaz — no hay que tocarlo a mano — y persiste entre reinicios y actualizaciones. Cada línea es una ruta absoluta; se admiten comentarios con <code>#</code>.",
"customModeTitle": "2. Modo Custom (por ejecución)",
"customModeBody": "Al lanzar una copia en modo <strong>Custom</strong>, en lugar de aplicar el perfil por defecto directamente, se muestra un checklist con todas las rutas: las del perfil por defecto y las de extras persistentes (estas últimas premarcadas con <code>[+]</code>). El usuario marca o desmarca lo que quiera para esa ejecución concreta, y puede además pulsar <em>Add custom path</em> para introducir una ruta nueva — que queda registrada en el fichero de extras persistentes para futuras copias.",
"customMissingTitle": "Rutas ausentes en el origen",
"customMissingBody": "Cualquier ruta del perfil (por defecto o añadida) que no exista en el host de origen se registra en <code>metadata/missing_paths.txt</code> dentro del archivo. La copia no falla ni interrumpe — el usuario ve el resumen de rutas archivadas y rutas ausentes al terminar. En la práctica esto ocurre con las rutas de herramientas opcionales como <code>/etc/wireguard</code> o <code>/etc/prometheus</code> cuando esas herramientas no están instaladas."
},
"manifest": {
"heading": "El bloque manifiesto",
"intro": "<code>manifest.json</code> es un documento JSON estructurado que describe el host de origen en el momento de la copia. Se produce mediante <strong>seis colectores independientes</strong> orquestados por <code>build_manifest.sh</code>. Cada colector es de sólo lectura, produce un fragmento JSON bien definido y hace fallback a un valor vacío seguro si falla — el manifiesto sigue siendo utilizable aunque una sección quede incompleta.",
"orchestratorCaption": "Los seis colectores componen el manifiesto. Cada uno corre en su propio subproceso; un fallo en uno hace fallback al valor por defecto documentado y advierte, pero no aborta la copia.",
"collectorRows": [
{
"collector": "collect_source_host.sh",
"produces": "source_host",
"content": "Hostname, versión de PVE (<code>pveversion</code>), versión de PBS si el host ejecuta el rol de backup-server, kernel (<code>uname -r</code>), modo de arranque (efi/bios), tipo de filesystem raíz, modelo y arquitectura de CPU, memoria en KB."
},
{
"collector": "collect_hardware.sh",
"produces": "hardware_inventory",
"content": "GPUs (con fabricante y mapeo al instalador de ProxMenux), TPUs (Coral USB + M.2 detectados con <code>lsusb</code>/<code>lspci</code>), NICs (con MAC, slot PCI y pertenencia a bridges), dispositivos wireless. Las entradas de GPU llevan un heurístico <code>passthrough_eligible</code>."
},
{
"collector": "collect_storage.sh",
"produces": "storage_inventory",
"content": "Pools ZFS (con tipo de pool y discos miembro resueltos a <code>/dev/disk/by-id/*</code> para portabilidad), grupos de volúmenes LVM + thin pools, discos físicos con capacidad SMART, entradas de <code>storage.cfg</code> de PVE, puntos de montaje externos."
},
{
"collector": "collect_kernel.sh",
"produces": "kernel_params",
"content": "Tokens del usuario extraídos de <code>/proc/cmdline</code> (limpios de boilerplate como <code>BOOT_IMAGE=</code>, <code>root=</code>, <code>ro/rw</code>, <code>quiet</code>, <code>splash</code>), módulos cargados al arranque desde <code>/etc/modules</code>, y rutas de los ficheros <code>/etc/modprobe.d/*.conf</code> con directivas efectivas (<code>options</code>, <code>blacklist</code>, <code>install</code>, <code>alias</code>, <code>softdep</code>)."
},
{
"collector": "collect_proxmenux_state.sh",
"produces": "proxmenux_installed_components",
"content": "Lee <code>/usr/local/share/proxmenux/managed_installs.json</code> (registro de todo lo que ProxMenux ha instalado) e <code>installed_tools.json</code>. Cada entrada conserva la ruta al instalador (<code>menu_script</code>) para que la restauración pueda disparar el mismo flujo de instalación."
},
{
"collector": "collect_guests.sh",
"produces": "vms_lxcs_at_backup",
"content": "Enumera VMs (<code>qm list</code>) y LXCs (<code>pct list</code>) presentes en el momento de la copia — VMID, nombre, estado actual. Sólo el inventario: los datos reales del invitado son responsabilidad de <code>vzdump</code> / PBS."
}
],
"schemaTitle": "Validación por esquema",
"schemaBody": "El manifiesto valida contra <code>scripts/backup_restore/schema/manifest.schema.json</code>. Ejecutar <code>build_manifest.sh --validate</code> dispara una validación JSON Schema por Python (requiere <code>python3</code> + <code>jsonschema</code>). Si el módulo no está presente, la comprobación se omite silenciosamente — la validación es principalmente una ayuda de desarrollo, no una dependencia en tiempo de ejecución."
},
"applications": {
"heading": "El inventario de aplicaciones",
"intro": "Dos ficheros bajo <code>metadata/</code> catalogan todo lo instalado en el origen que no forma parte del conjunto de paquetes base de Proxmox VE. La restauración los utiliza para reproducir el conjunto exacto de software instalado por el usuario en el destino, usando APT o los instaladores propios de ProxMenux según cómo se instalara originalmente el software.",
"packagesTitle": "packages.manual.list",
"packagesBody": "Una lista de texto plano producida por <code>apt-mark showmanual</code>: todos los paquetes APT que fueron <em>instalados explícitamente</em> en el host de origen, ordenados alfabéticamente. Esto excluye los paquetes instalados como dependencias del ISO base de Proxmox VE (que APT del destino vuelve a traer automáticamente). Es leída por <code>_rs_run_complete_extras</code> durante la restauración, filtrada por un filtro <em>cascade-safe</em> de tres pases (<code>dpkg -s</code> para lo ya instalado, detección de sibling-major para librerías, <code>apt-get install --simulate</code> para riesgo de cascade-remove) y después instalada con <code>apt-get install -y</code>.",
"componentsTitle": "components_status.json (parte del rootfs)",
"componentsBody": "Un registro JSON bajo <code>/usr/local/share/proxmenux/</code> que anota cada componente que ProxMenux ha instalado con su estado exacto: versión, flags específicas de ProxMenux (para NVIDIA: booleano <code>patched</code>; para Coral: versión del DKMS). Este fichero vive dentro del rootfs — no en <code>metadata/</code> — porque se lee <em>después</em> de haber copiado el rootfs al destino. El dispatcher post-arranque (<code>apply_cluster_postboot.sh</code>) itera sobre sus entradas y ejecuta el hook <code>--auto-reinstall</code> de cada componente, que lee el estado registrado y reproduce la instalación contra el kernel actual del destino.",
"componentInstallersTitle": "Instaladores de componentes",
"componentInstallersBody": "Cuatro instaladores de ProxMenux exponen actualmente un punto de entrada <code>--auto-reinstall</code>:",
"installerRows": [
{
"component": "nvidia_driver",
"installer": "gpu_tpu/nvidia_installer.sh",
"action": "Lee <code>version</code> + <code>patched</code>. Descarga el runfile exacto de NVIDIA, compila los módulos DKMS contra el kernel del destino, reaplica el parche de ProxMenux si el origen lo tenía."
},
{
"component": "coral_driver",
"installer": "gpu_tpu/install_coral.sh",
"action": "Lee la versión del driver Coral. Compila el módulo DKMS contra el kernel del destino."
},
{
"component": "amdgpu_top",
"installer": "gpu_tpu/amd_gpu_tools.sh",
"action": "Lee la versión registrada. Vuelve a descargar el <code>.deb</code> exacto desde la release de GitHub."
},
{
"component": "intel_gpu_tools",
"installer": "gpu_tpu/intel_gpu_tools.sh",
"action": "Instala el paquete vía APT. Idempotente si ya está presente por <code>packages.manual.list</code>."
}
]
},
"restoreFlow": {
"heading": "Cómo consume la restauración los tres bloques",
"intro": "La restauración es un pipeline de cinco etapas. Cada etapa lee un subconjunto concreto del archivo y actualiza el host de destino. Ninguna etapa requiere que el host de origen esté accesible — el archivo es totalmente autocontenido.",
"stagesCaption": "La etapa 1 usa el manifiesto para decidir qué tocar. La etapa 2 copia las rutas del rootfs seguras de aplicar en un sistema en ejecución. La etapa 3 deja las rutas de riesgo preparadas para el siguiente arranque. La etapa 4 gestiona los paquetes. La etapa 5 corre tras el reinicio y reinstala los componentes contra el kernel del destino.",
"stageRows": [
{
"stage": "1",
"name": "Comprobación de compatibilidad",
"reads": "manifest.json",
"action": "Ejecuta <code>hb_compat_check</code>. Compara hardware (NICs, IDs de almacenamiento), versión de PVE y versión mayor del kernel entre origen y destino. Fija <code>HB_COMPAT_KERNEL_DIRECTION</code> (<code>same</code>, <code>bk_newer</code> o <code>bk_older</code>) y rellena <code>RS_SKIP_PATHS</code> con las exclusiones por drift de hardware y por cross-kernel."
},
{
"stage": "2",
"name": "Aplicación hot",
"reads": "rootfs/ (sólo rutas seguras)",
"action": "<code>_rs_apply … hot</code> copia las entradas cuyo <code>hb_classify_path</code> es <code>hot</code> directamente al destino en vivo. Todo lo bajo <code>/etc/pve</code>, <code>/etc/network</code> o clasificado como <em>reboot</em>/<em>dangerous</em> queda diferido."
},
{
"stage": "3",
"name": "Preparación de pending",
"reads": "rootfs/ (rutas reboot + dangerous)",
"action": "<code>_rs_prepare_pending_restore</code> deja las rutas de riesgo preparadas bajo <code>/var/lib/proxmenux/pending-restore/</code>, escribe <code>plan.env</code>, <code>apply-on-boot.list</code> y <code>rs-skip-paths.txt</code>, y habilita <code>proxmenux-restore-onboot.service</code> para que dispare en el siguiente arranque."
},
{
"stage": "4",
"name": "Instalación de paquetes",
"reads": "metadata/packages.manual.list",
"action": "<code>_rs_run_complete_extras</code> ejecuta el filtro cascade-safe y llama a <code>apt-get install -y</code> con la lista de paquetes superviviente. La salida completa va a <code>/var/log/proxmenux/restore-apt-*.log</code>."
},
{
"stage": "5",
"name": "Post-arranque",
"reads": "rootfs (ya aplicado) + components_status.json",
"action": "Tras el reinicio, <code>apply_pending_restore.sh</code> reproduce las rutas diferidas y <code>apply_cluster_postboot.sh</code> ejecuta <code>update-initramfs</code>, <code>update-grub</code> (o <code>proxmox-boot-tool refresh</code>) e itera sobre <code>components_status.json</code> disparando el hook <code>--auto-reinstall</code> de cada componente."
}
]
},
"whyItWorks": {
"heading": "Por qué la separación en tres bloques es la correcta",
"body": "La separación no responde a una decisión de sistema de ficheros — responde a una decisión de <strong>ciclo de vida</strong>. El contenido del sistema de ficheros se mueve con <code>rsync</code>: rápido, transparente, atómico por fichero. El estado de configuración que la restauración tiene que interpretar antes de tocar el destino se mueve como <strong>JSON estructurado</strong>: legible de forma independiente, versionable mediante un esquema, diff-eable contra el estado propio del destino. El software que se tiene que reinstalar contra el entorno del destino se mueve como <strong>inventario</strong>: sólo nombres y versiones, dejando que el gestor de paquetes del destino y los instaladores propios de ProxMenux decidan los binarios reales. Cada bloque se optimiza para lo que tiene que hacer, y los tres combinan en una restauración que es atómica en la intención pero tolerante a fallos en la práctica: un manifiesto corrupto sigue dejando el rootfs restaurable, un paquete perdido sigue dejando los componentes instalables, un instalador que falla en una entrada no detiene la siguiente."
}
}
@@ -0,0 +1,87 @@
{
"meta": {
"title": "ProxMenux Backup & Restore — Descripción general | Copia y restauración completa del host Proxmox VE",
"description": "ProxMenux Backup & Restore captura el estado completo de un host Proxmox — sistema de ficheros, manifiesto estructurado de configuración y paquetes/componentes instalados — y lo reproduce en el mismo host o en uno distinto. La copia y la restauración son autocontenidas: sin dependencias externas, y con soporte para restauraciones cross-kernel mediante un filtro direccional de subconjunto seguro y una hidratación kernel-agnóstica.",
"ogTitle": "ProxMenux Backup & Restore — Descripción general",
"ogDescription": "Copia y restauración completa del host Proxmox VE con manifiesto estructurado, lista de paquetes y reinstaladores de componentes.",
"twitterTitle": "ProxMenux Backup & Restore | ProxMenux",
"twitterDescription": "Copia y restauración completa del host Proxmox VE con manifiesto estructurado, lista de paquetes y reinstaladores de componentes."
},
"header": {
"title": "Backup & Restore",
"description": "Copia y restauración a nivel de host para Proxmox VE. Captura el sistema de ficheros, la configuración y los componentes instalados en un único archivo y reproduce el host sobre la misma instalación de Proxmox o sobre una distinta, sin dependencias externas.",
"section": "Backup & Restore"
},
"intro": {
"title": "Qué es, en un párrafo",
"body": "Una copia de ProxMenux captura el estado completo de un host Proxmox: <strong>el sistema de ficheros</strong> (directorios relevantes bajo <code>/etc</code>, <code>/root</code>, <code>/var/lib/pve-cluster</code>, más rutas personalizadas opcionales), <strong>un manifiesto estructurado</strong> (JSON con el hardware detectado, los parámetros del kernel, la topología de red, el estado de ZFS, los usuarios y las entradas de cron) y <strong>un inventario de aplicaciones</strong> (todos los paquetes marcados como instalados manualmente por APT, más la lista de componentes instalados por ProxMenux con sus versiones exactas). Cualquiera de los tres destinos soportados — archivo local, Proxmox Backup Server (recomendado) o Borg — recibe el mismo contenido autocontenido, y cualquiera de ellos puede hidratar el host de destino sin depender de que el origen esté accesible en el momento de la restauración."
},
"whatItIsNot": {
"heading": "Qué no es",
"intro": "La sección cubre copia y restauración <strong>a nivel de host</strong>: la instalación de Proxmox en sí, no las cargas de trabajo que se ejecutan sobre ella.",
"items": [
"<strong>No es una herramienta de copia de VMs/CTs.</strong> Los discos de los invitados y su estado de RAM no se capturan en esta función; para eso está <code>vzdump</code>. Los <strong>ficheros de configuración</strong> de los invitados (<code>/etc/pve/nodes/&lt;node&gt;/qemu-server/*.conf</code> y <code>lxc/*.conf</code>) <strong>sí</strong> se capturan, de modo que tras la restauración el inventario de invitados reaparece y sus discos pueden re-adjuntarse desde una copia existente de PBS o local.",
"<strong>No es una operación a nivel de clúster.</strong> Cada nodo se copia a sí mismo. La pertenencia al clúster se captura como parte de <code>/etc/pve</code> para que un nodo restaurado pueda re-incorporarse al clúster, pero restaurar un clúster completo requiere coordinación por nodo.",
"<strong>No es una imagen completa del disco.</strong> Los binarios del kernel, el initramfs y la partición de arranque no se capturan. En la restauración, ProxMenux utiliza los artefactos de arranque propios del host de destino (regenerados automáticamente por <code>update-initramfs</code> y la herramienta de bootloader) e instala los controladores adecuados contra el kernel que el destino tenga en ejecución."
]
},
"threePillars": {
"heading": "Los tres pilares de una copia",
"intro": "Un archivo de ProxMenux se estructura en torno a tres cargas útiles autocontenidas. La restauración utiliza las tres en conjunto para reproducir el host de origen sobre un destino que puede no tener siquiera el mismo kernel instalado.",
"diagramCaption": "Cada copia contiene los mismos tres bloques con independencia del destino. La restauración los consume todos: rootfs para colocar los ficheros, manifiesto para detectar drift y diferencias cross-kernel, e inventario de aplicaciones para reinstalar paquetes y componentes contra el kernel del propio destino.",
"pillar1Label": "Sistema de ficheros",
"pillar1Detail": "rootfs/\n(rsync de\n/etc, /root,\n/var/lib/pve-cluster,\n+ rutas opcionales)",
"pillar2Label": "Manifiesto",
"pillar2Detail": "manifest.json\n(hardware, params\ndel kernel, red,\nZFS, usuarios, cron,\npools ZFS, storage)",
"pillar3Label": "Aplicaciones",
"pillar3Detail": "packages.manual.list\n+ components_status.json\n(APT manual + instaladores\nProxMenux con versiones)"
},
"restoreIsUniversal": {
"heading": "La restauración reproduce el host de origen, no el archivo",
"body": "Restaurar una copia de ProxMenux no consiste solamente en extraer el sistema de ficheros. El flujo de restauración lee el manifiesto para detectar diferencias entre origen y destino (variaciones de hardware, renombrado de NICs, versión de kernel, identidad de la pool ZFS), reproduce el sistema de ficheros y lanza el instalador correspondiente a cada servicio que estuviera instalado en el origen (controlador NVIDIA, Coral TPU, herramientas AMD GPU, herramientas Intel GPU). Cada instalador se ejecuta contra el <strong>kernel actual del destino</strong>, por lo que el host restaurado no depende de que el kernel del origen esté presente. Cuando el kernel del destino es más reciente que el de la copia, una pasada de <strong>hidratación</strong> kernel-agnóstica funde la configuración propia del usuario (tokens IOMMU, IDs de dispositivos VFIO, quirks personalizadas, claves de GRUB) sobre la configuración de arranque fresca del destino, sin copiar verbatim los ficheros ligados al kernel."
},
"twoInterfaces": {
"heading": "Dos interfaces, un único backend",
"intro": "Cada paso del flujo de copia y restauración está disponible desde dos puntos de entrada. Ambos invocan la misma librería de shell, producen archivos idénticos y leen el mismo registro de trabajos.",
"cliLabel": "ProxMenux Scripts (TUI)",
"cliDetail": "menu → Utilities →\nHost Backup / Restore\n\nFlujo basado en diálogos,\namigable por SSH, admite\nejecución desatendida\ndesde scripts.",
"webLabel": "ProxMenux Monitor (Web UI)",
"webDetail": "Pestaña Backups en la\ninterfaz Web del Monitor.\n\nRestauración con un clic,\nlog en vivo, integrado con\nlas notificaciones y con\nel visor de rollback."
},
"whereNext": {
"heading": "A dónde seguir desde aquí",
"intro": "Cada subsección posterior desarrolla en detalle un aspecto del flujo. Se recomienda empezar por <em>Cómo funciona</em> para entender qué contiene el archivo y por qué. Consultar <em>Destinos</em> para configurar el destino de la copia. Leer <em>Restauración</em> y <em>Restauración cross-kernel</em> para el lado de recuperación.",
"items": [
{
"label": "Cómo funciona",
"href": "/docs/backup-restore/how-it-works",
"tail": " — los tres bloques (rootfs, manifiesto, aplicaciones) en detalle, con los colectores que los generan y el formato de cada fichero."
},
{
"label": "Destinos",
"href": "/docs/backup-restore/destinations",
"tail": " — comparativa entre archivo local, Proxmox Backup Server (recomendado) y Borg, y cómo configurar cada uno."
},
{
"label": "Crear copias",
"href": "/docs/backup-restore/creating-backups",
"tail": " — copias puntuales, perfil de rutas por defecto, adición de rutas personalizadas, cifrado en PBS."
},
{
"label": "Trabajos programados",
"href": "/docs/backup-restore/scheduled-jobs",
"tail": " — trabajos nuevos vs. adjuntarse a un trabajo vzdump existente en PVE, formatos de programación, el modal de detalle del trabajo."
},
{
"label": "Restauración",
"href": "/docs/backup-restore/restoring",
"tail": " — las tres acciones sobre un archivo (ver, descargar, restaurar), Completa vs. Personalizada, el dispatcher post-arranque y por qué importan los últimos diez minutos."
},
{
"label": "Restauración cross-kernel",
"href": "/docs/backup-restore/cross-kernel",
"tail": " — comportamiento direccional cuando el kernel del destino difiere del de la copia, el filtro de subconjunto seguro y las cuatro fases de hidratación."
}
]
}
}
File diff suppressed because one or more lines are too long
@@ -0,0 +1,148 @@
{
"meta": {
"title": "Trabajos programados — timers, modo adjunto, retención | ProxMenux",
"description": "Trabajos de copia de host programados en ProxMenux. Dos modos de creación (timer systemd propio o adjuntarse a un trabajo vzdump de PVE existente), valores de retención aplicados por trabajo vía proxmox-backup-client/borg/local prune, layout de almacenamiento bajo /var/lib/proxmenux/backup-jobs, y el script runner que produce archivos idénticos al flujo interactivo.",
"ogTitle": "ProxMenux Backup — trabajos programados",
"ogDescription": "Copias de host desatendidas programadas con modo adjunto, retención, y los mismos tres destinos que el flujo interactivo.",
"twitterTitle": "Trabajos programados | ProxMenux",
"twitterDescription": "Trabajos de copia de host desatendidos con modo adjunto y retención."
},
"header": {
"title": "Trabajos programados",
"description": "Trabajos de copia de host desatendidos. Dos modelos de creación: un trabajo nuevo e independiente con su propio horario, o un trabajo adjuntado a una tarea vzdump de PVE existente que hereda el horario y la retención de esa tarea. Ambos producen archivos idénticos al flujo interactivo.",
"section": "Backup & Restore"
},
"intro": {
"title": "Los dos modelos de trabajo programado",
"body": "Un trabajo programado puede crearse siguiendo uno de dos modelos:",
"modelsList": [
"<strong>Trabajo nuevo e independiente</strong> — el propio ProxMenux define el horario del trabajo con un timer systemd propio, independiente de cualquier otra tarea del host. Compatible con los tres destinos: Local, PBS y Borg.",
"<strong>Adjuntarse a una tarea vzdump de PVE existente</strong> — el trabajo no lleva horario propio; se ejecuta automáticamente cada vez que se dispara la tarea vzdump padre que ya copia las VMs y los LXCs del host. Hereda el horario y la retención de la tarea padre. Compatible con Local y PBS (Borg no está soportado porque no existe scheduler nativo de PVE para Borg)."
]
},
"attachBadge": {
"title": "Modo adjunto — recomendado cuando ya existe una tarea vzdump de PVE",
"body": "Cuando ya hay una tarea de copia vzdump de PVE configurada para las VMs y los LXCs de este nodo, adjuntar la copia de host a esa tarea garantiza que la configuración del host se captura en la <strong>misma ventana</strong> que los invitados. En la restauración, las configuraciones de los invitados vienen de la copia de host (viven bajo <code>/etc/pve</code>), y los discos de los invitados vienen de la copia vzdump tomada al mismo tiempo — ambos conjuntos son consistentes entre sí, por lo que una recuperación completa del nodo puede reproducir el host y re-adjuntar cada invitado sin drift de versiones."
},
"modes": {
"heading": "Los dos modos",
"rows": [
{
"mode": "Nuevo trabajo programado",
"backends": "Local, PBS, Borg",
"schedule": "Expresión <code>OnCalendar</code> propia (sintaxis de calendario systemd — por ejemplo <code>daily</code>, <code>Mon..Fri 03:00</code>).",
"retention": "Se pregunta por separado: <code>keep-last</code>, <code>keep-hourly</code>, <code>keep-daily</code>, <code>keep-weekly</code>, <code>keep-monthly</code>, <code>keep-yearly</code>. La aplica el runner tras cada copia exitosa."
},
{
"mode": "Adjuntar a un trabajo vzdump de PVE",
"backends": "Local, PBS (Borg no tiene scheduler del lado PVE)",
"schedule": "Heredado del trabajo PVE padre. No se instala timer systemd del lado de ProxMenux.",
"retention": "Heredada de la configuración <code>prune-backups</code> del padre (mapeada uno-a-uno a las variables <code>KEEP_*</code> del runner vía <code>hb_pve_prune_to_keep_env</code>)."
}
]
},
"attachDetail": {
"heading": "Cómo funciona el modo adjunto",
"intro": "PVE escribe las tareas <code>vzdump</code> en <code>/etc/pve/jobs.cfg</code> — una entrada por tarea, cada una apuntando a un storage donde caen los dumps de VMs y LXCs. El modo adjunto requiere que ese storage sea un backend que ProxMenux entienda (Local o PBS); cuando la tarea dispara, ProxMenux se ejecuta al mismo tiempo.",
"steps": [
{
"step": "1",
"detail": "Durante la creación del trabajo, ProxMenux lista las tareas PVE padre compatibles vía <code>hb_pve_list_vzdump_jobs_for_backend</code>. El usuario elige una."
},
{
"step": "2",
"detail": "El <code>.env</code> del trabajo se escribe con <code>PVE_PARENT_JOB</code>, <code>PVE_STORAGE</code> y los valores heredados de <code>KEEP_*</code>; no se crea timer systemd."
},
{
"step": "3",
"detail": "<code>hb_install_vzdump_hook</code> registra un script-hook en <code>/etc/vzdump.conf</code>. Cuando PVE ejecuta cualquier tarea vzdump, el script-hook dispara; si el <code>$STOREID</code> que se le pasa coincide con el <code>PVE_STORAGE</code> de un trabajo adjuntado, el runner se invoca para ese trabajo."
},
{
"step": "4",
"detail": "El archivo aterriza en el mismo storage donde los dumps de vzdump acaban de escribirse: <code>path/dump/</code> para Local, o el repositorio PBS configurado en la entrada de storage de PVE."
}
],
"outroBody": "El modo adjunto tiene una implicación operativa: desactivar o eliminar la tarea padre de PVE también desactiva la copia de host — no hay timer propio al que recurrir. La entrada del trabajo permanece en disco para poder re-adjuntarla más tarde."
},
"storageLayout": {
"heading": "Ficheros que componen un trabajo",
"intro": "Cada trabajo programado queda completamente descrito por tres o cuatro ficheros en disco. Consultarlos permite ver toda la configuración del trabajo sin depender de la interfaz.",
"rows": [
{
"path": "/var/lib/proxmenux/backup-jobs/JOB_ID.env",
"content": "Backend, backup ID o destino, horario (modo Nuevo) o padre PVE (modo adjunto), flag enabled, valores <code>KEEP_*</code> de retención, punteros a credenciales."
},
{
"path": "/var/lib/proxmenux/backup-jobs/JOB_ID.paths",
"content": "Una ruta absoluta por línea — la selección congelada resuelta desde el perfil en el momento de creación del trabajo. Editar el fichero re-ejecuta el trabajo con la nueva selección en el siguiente disparo del timer."
},
{
"path": "/etc/systemd/system/proxmenux-backup-JOB_ID.timer + .service",
"content": "Sólo modo Nuevo. El service invoca <code>run_scheduled_backup.sh JOB_ID</code>. El timer lo programa con <code>Persistent=true</code> (los disparos perdidos se ejecutan al siguiente arranque) y un pequeño <code>RandomizedDelaySec=120</code> para repartir carga cuando varios trabajos comparten la misma expresión OnCalendar."
},
{
"path": "script-hook de /etc/vzdump.conf",
"content": "Sólo modo adjunto. Lo instala una vez <code>hb_install_vzdump_hook</code>; casa el <code>PVE_STORAGE</code> de cada trabajo adjuntado contra el <code>$STOREID</code> que PVE pasa al script-hook."
}
]
},
"runner": {
"heading": "Qué hace un trabajo cuando se dispara",
"intro": "Cada trabajo — sea del modelo nuevo o adjunto — ejecuta la misma secuencia de tres pasos:",
"steps": [
"<strong>Preparar la copia.</strong> Lee la configuración del trabajo (destino, perfil, rutas) y ensambla el árbol de la copia siguiendo exactamente el mismo procedimiento que el flujo interactivo. El resultado es el mismo archivo que produciría una copia manual con esos ajustes.",
"<strong>Escribir en el destino.</strong> Sube o escribe la copia al destino configurado — un archivo local <code>.tar.zst</code>, un backup PBS o un archivo Borg — usando exactamente las mismas herramientas y credenciales que utilizaría una copia manual al mismo destino.",
"<strong>Aplicar retención.</strong> Elimina las copias antiguas del destino conservando los valores <code>keep-last</code> / <code>keep-daily</code> / <code>keep-weekly</code> configurados en el trabajo. La poda la realiza el propio destino: PBS mantiene la cuenta en su lado, Borg ejecuta <code>borg prune</code>, y en Local ProxMenux borra los archivos que quedan fuera del <code>keep-last</code>."
]
},
"management": {
"heading": "Gestión de trabajos",
"intro": "El menú del scheduler (TUI de Scripts) y la pestaña Backups del Monitor exponen las mismas acciones sobre cualquier trabajo.",
"rows": [
{
"action": "Run now",
"detail": "Invoca el runner de inmediato, saltándose el timer / hook de vzdump. Útil para verificar una configuración de trabajo sin esperar al siguiente disparo programado."
},
{
"action": "Enable / Disable",
"detail": "Modo Nuevo: <code>systemctl enable/disable --now</code> sobre el timer. Modo adjunto: cambia el flag <code>ENABLED</code> en el env del trabajo — el script-hook lo respeta en el siguiente disparo de PVE."
},
{
"action": "Edit",
"detail": "Reabre los prompts de destino, horario, perfil y retención y reescribe los ficheros del trabajo. Preserva el ID del trabajo."
},
{
"action": "Delete",
"detail": "Elimina el env del trabajo, el fichero de rutas, el timer + service systemd (modo Nuevo) y desactiva el binding del hook (modo adjunto). No toca los archivos ya presentes en el destino."
},
{
"action": "View log",
"detail": "Muestra en streaming <code>/var/log/proxmenux/backup-jobs/JOB_ID-YYYYMMDD_HHMMSS.log</code> — un fichero de log por ejecución. El runner también emite una línea de estado compacta a journald bajo el service systemd."
}
]
},
"notifications": {
"heading": "Notificaciones",
"body": "Cada ejecución programada dispara los mismos eventos <code>hb_notify_lifecycle</code> que el flujo interactivo (<code>start</code>, <code>complete</code>, <code>fail</code>). Si hay canales de notificación configurados en el Monitor, los trabajos desatendidos exponen sus resultados igual que las copias manuales — un usuario no necesita revisar el log para saber si un trabajo tuvo éxito."
},
"whereNext": {
"heading": "A dónde seguir",
"items": [
{
"label": "Crear copias",
"href": "/docs/backup-restore/creating-backups",
"tail": " — el flujo interactivo que comparte backend con el scheduler."
},
{
"label": "Destinos",
"href": "/docs/backup-restore/destinations",
"tail": " — configuración por backend usada tanto por el flujo interactivo como por el scheduler."
},
{
"label": "Restauración",
"href": "/docs/backup-restore/restoring",
"tail": " — el flujo que consume lo que producen los trabajos."
}
]
}
}
@@ -20,7 +20,7 @@
"title": "Antes de empezar",
"drivers": "<strong>Drivers de Coral ya instalados en el host</strong>. Este script no los instala; solo configura el passthrough al contenedor. Ejecuta <hostLink>Install Coral TPU on the Host</hostLink> primero si no lo has hecho.",
"driversCheck": "ls /dev/apex_* 2>/dev/null ; lsusb | grep -E '1a6e:089a|18d1:9302'",
"container": "<strong>Un contenedor LXC existente</strong>, idealmente con una distro basada en <strong>Debian / Ubuntu</strong>. La instalación dentro del contenedor usa <code>apt-get</code>; los contenedores Alpine / Arch no están soportados por este script actualmente.",
"container": "<strong>Un contenedor LXC existente</strong>, idealmente con una distro basada en <strong>Debian / Ubuntu</strong> — la instalación del runtime dentro del contenedor usa <code>apt-get</code>. Los <strong>contenedores no-Debian</strong> (Alpine, Arch, RHEL, SUSE…) siguen estando soportados en <strong>modo passthrough-only</strong>: el script detecta la distro y ofrece un prompt para saltarse la instalación APT de <code>libedgetpu</code> mientras escribe la config de passthrough del dispositivo — útil para contenedores de aplicación que ya incluyen el runtime (p.ej. la imagen Docker de Frigate).",
"downtime": "<strong>Asume una breve interrupción</strong> del contenedor. El script lo para para aplicar los cambios de config y lo arranca de nuevo para instalar los drivers dentro. No hace falta reiniciar el host."
},
"hostPrep": {
@@ -70,8 +70,8 @@
],
"noIgpuTitle": "¿Por qué no hay drivers de iGPU aquí?",
"noIgpuBody": "Versiones anteriores de este script también instalaban Intel <code>va-driver-all</code>, <code>intel-opencl-icd</code> y compañía para que el mismo contenedor pudiera hacer decode de vídeo Quick Sync junto a la inferencia de Coral. Esa doble responsabilidad causaba fallos confusos cuando el usuario solo quería Coral. El lado iGPU es ahora trabajo exclusivo de <lxcGpuLink>Añadir GPU a LXC</lxcGpuLink> — ejecútalo primero si también quieres decode de vídeo por hardware en el contenedor.",
"debianTitle": "Solo contenedores Debian / Ubuntu",
"debianBody": "La instalación dentro del contenedor usa <code>apt-get</code> directamente. Los contenedores Alpine, Arch o basados en RHEL no están soportados actualmente — el paso de instalación fallará y dejará el LXC con la config de passthrough pero sin drivers dentro. Para esas distros, instala el runtime de Coral manualmente siguiendo la <coralLink>guía oficial</coralLink> de Google después del paso de config del LXC."
"debianTitle": "Contenedores no-Debian — modo passthrough-only",
"debianBody": "La instalación del runtime dentro del contenedor usa <code>apt-get</code>, que solo viene con distros de la familia Debian/Ubuntu. En contenedores <strong>Alpine, Arch, RHEL o SUSE</strong> el script detecta la distro vía <code>/etc/os-release</code> y muestra un prompt de confirmación: <em>continuar en modo passthrough-only</em> (escribe la config del dispositivo en <code>/etc/pve/lxc/&lt;ctid&gt;.conf</code> y se salta la instalación APT de <code>libedgetpu</code>) o <em>cancelar</em>. Passthrough-only es la opción correcta si el contenedor de aplicación que va a usar Coral ya incluye el runtime — el ejemplo canónico es la imagen Docker de Frigate. Si no, sigue la <coralLink>guía oficial</coralLink> de Google para instalar <code>libedgetpu</code> manualmente después de que el script haya escrito la config del LXC."
},
"summary": {
"title": "Resumen",
@@ -95,8 +95,8 @@
"apexBody": "El módulo apex del host no está cargado. En el host: <code>lsmod | grep apex</code> — si está vacío, ejecuta <code>modprobe apex</code>, o reinicia si acabas de instalar los drivers de Coral. Una vez el host tenga <code>/dev/apex_0</code>, reinicia el contenedor: <code>pct stop &lt;ctid&gt; &amp;&amp; pct start &lt;ctid&gt;</code>.",
"replugTitle": "La Coral USB desaparece al reconectarla en otro puerto",
"replugBody": "Justo por eso el script monta <code>/dev/bus/usb</code> en lugar del symlink <code>/dev/coral</code>. Si te pasa esto, comprueba que tu config del LXC tiene <code>lxc.mount.entry: /dev/bus/usb dev/bus/usb ...</code> y no una referencia directa a <code>/dev/coral</code>. Las configs viejas de versiones anteriores del script pueden necesitar actualizarse — vuelve a ejecutar el script sobre el mismo contenedor y la config se refresca.",
"alpineTitle": "La instalación dentro del contenedor falla en un contenedor Alpine",
"alpineBody": "El script usa <code>apt-get</code>, que Alpine no tiene. La config de passthrough del LXC sigue siendo válida — solo instala el runtime de Coral manualmente con <code>apk add</code> siguiendo la guía de Google para Alpine, o usa un contenedor basado en Debian si no necesitas la huella más pequeña.",
"alpineTitle": "Contenedor Alpine / Arch / RHEL / SUSE — runtime no instalado",
"alpineBody": "Si elegiste <em>modo passthrough-only</em> cuando el script lo preguntó, la config del LXC se escribió y el dispositivo Coral es visible dentro del contenedor, pero el runtime <code>libedgetpu</code> no está instalado. Es así por diseño: el repo APT de Google solo se publica para Debian/Ubuntu. Instala el runtime manualmente con el gestor de paquetes de tu distro (Alpine: <code>apk add</code>; Arch: AUR; RHEL/SUSE: compilar desde fuente) siguiendo la guía oficial de Google, o usa un contenedor de aplicación que incluya el runtime — la imagen Docker de Frigate es el ejemplo canónico: solo expone el dispositivo con <code>--device /dev/apex_0:/dev/apex_0</code> (M.2) o el bind mount USB que el script ya escribió (USB).",
"frigateTitle": "Frigate dice 'Coral EdgeTPU detected but not available'",
"frigateBody": "Casi siempre es un problema de permisos dentro del contenedor. Frigate corre como root por defecto; comprueba que el usuario root está en el grupo <code>plugdev</code> dentro del contenedor (para USB), y que el proceso puede leer <code>/dev/apex_0</code> (para M.2). <code>ls -l /dev/apex_0</code> desde dentro del contenedor debería mostrar el grupo <code>apex</code> — si no, añade el alineamiento de GID a <code>/etc/group</code> o cambia el contenedor a modo privilegiado.",
"logsTitle": "Revisa los logs del host y del contenedor",
@@ -35,6 +35,32 @@
}
]
},
"flow": {
"heading": "Diagrama Network Flow",
"intro": "Entre la fila superior y las tres tarjetas de grupos, la pestaña renderiza una vista de topología en vivo llamada <strong>Network Flow</strong>. Dibuja cada camino que un paquete puede tomar a través del host — NICs físicas en un extremo, bridges en el medio, VMs y contenedores en el otro — con pulsos animados que muestran el tráfico rx/tx en tiempo real sobre cada enlace.",
"imageAlt": "Diagrama Network Flow — NICs a la izquierda, host y bridges en el medio, VMs y LXCs a la derecha, con pulsos animados en cada conexión",
"imageCaption": "Network Flow — nodos con código de color más cometas animados cuya dirección y grosor reflejan el tráfico en vivo.",
"elementsTitle": "Qué muestra el diagrama",
"elementsIntro": "Cada nodo es una entidad del mismo inventario que usan las tarjetas de abajo, pero organizadas como topología para que las relaciones se vean de un vistazo:",
"elements": [
"<strong>NICs</strong> (ámbar) — cada interfaz física con enlace activo. Las interfaces reportadas como down se dibujan atenuadas.",
"<strong>Host</strong> (ámbar) — el propio host Proxmox, situado entre las NICs y los bridges. Renderizado como anclaje fijo; no clicable.",
"<strong>Bridges</strong> (cian) — bridges Linux y OVS. Sólo se dibujan los bridges que llevan al menos un guest activo; los bridges sin uso se ocultan para que el diagrama muestre lo que realmente mueve tráfico.",
"<strong>LXCs</strong> (cian) — contenedores en ejecución conectados a un bridge.",
"<strong>VMs</strong> (púrpura) — máquinas virtuales en ejecución conectadas a un bridge.",
"Los guests offline (VMs / contenedores parados) se ocultan."
],
"pulsesTitle": "Qué codifica la animación",
"pulsesBody": "Los cometas animados que viajan por cada arista representan tráfico en vivo:",
"pulses": [
"<strong>Dirección</strong> — un pulso que fluye hacia la NIC es <em>tx</em> del guest; hacia el guest es <em>rx</em>.",
"<strong>Grosor de trazo</strong> escala con el rate combinado rx+tx del guest. Un guest inactivo dibuja una línea animada tenue; uno con carga la dibuja gruesa.",
"<strong>Halo de la cabeza del cometa</strong> — templado hacia ~1 MB/s, caliente a ≥30 MB/s. Útil para detectar de un vistazo qué guest está dominando una NIC.",
"<strong>Click</strong> — cada nodo excepto el host es clicable y abre el mismo modal de detalle por interfaz documentado más abajo. Pulsar el host es intencionadamente un no-op — no hay modal a nivel de host en esta vista."
],
"useTitle": "Cuándo es útil",
"useBody": "Las tarjetas de grupos de abajo te dicen <em>qué</em> existe; el diagrama te dice <em>cómo está conectado</em> y por dónde fluye el tráfico ahora mismo. Patrones fáciles de ver de un vistazo: un bridge sin ningún guest activo conectado, dos guests pesados usando la misma NIC (candidato a cuello de botella), o una única VM saturando un enlace mientras el resto está tranquilo."
},
"groups": {
"heading": "Tres grupos de interfaces",
"intro": "Bajo la fila superior, tres tarjetas dividen el inventario por rol. Cada tarjeta tiene su propia insignia de recuento de activas en la cabecera. El <strong>tipo</strong> de interfaz se identifica de un vistazo mediante una insignia coloreada en cada fila:",
@@ -53,6 +53,30 @@
"sparklineTitle": "El sparkline es significativo",
"sparklineBody": "La tarjeta de temperatura dibuja una traza de 5 minutos bajo el valor, con la línea y el degradado siguiendo el mismo par Warning/Critical documentado arriba. Es la forma más rápida de ver si el host está en escalada térmica sin abrir la modal de detalle."
},
"processes": {
"heading": "Top procesos por CPU / Memoria",
"intro": "Las tarjetas CPU Usage y Memory de la pestaña Resumen son clicables. Al pulsar cualquiera de ellas se abre una lista ordenable con los 25 procesos top — ordenada por uso de CPU si la abriste desde la tarjeta de CPU, o por memoria residente si la abriste desde la de Memory.",
"listTitle": "El diálogo con la lista",
"listItems": [
"<strong>Auto-refresco</strong> — la lista se actualiza cada 5 segundos mientras el diálogo está abierto y deja de pedir datos en cuanto se cierra.",
"<strong>Filtro</strong> — la caja de búsqueda acota la lista por command, user o PID.",
"<strong>Barra en línea</strong> — la columna de la métrica principal dibuja una barra pequeña escalada al mayor valor de la lista filtrada, para que el orden siga siendo visible aunque ningún proceso esté cerca del 100 %.",
"<strong>Layout móvil</strong> — por debajo de 640 px las columnas PID y User se ocultan para que Command, CPU % y Memory sigan cabiendo en la pantalla de un teléfono sin scroll horizontal."
],
"captureListAlt": "Modal Top processes by Memory — tabla con columnas PID, USER, COMMAND, CPU %, Memory ordenada por RSS",
"captureListCaption": "La tarjeta Memory abre la lista ordenada por RSS (acento índigo). La tarjeta CPU abre la misma lista ordenada por uso de CPU (acento azul).",
"detailTitle": "Detalle por proceso",
"detailIntro": "Al pulsar cualquier fila de la lista se abre un segundo diálogo con la foto en vivo de ese proceso, organizada en cuatro secciones:",
"detailItems": [
"<strong>Overview</strong> — estado, proceso padre, número de hilos, descriptores de fichero abiertos, usuario y grupo.",
"<strong>Resources</strong> — CPU %, Memoria %, Resident (RSS), Virtual size, Swap, totales de I/O de lectura y escritura.",
"<strong>Command</strong> — nombre corto, línea de comandos completa, ruta del ejecutable y directorio de trabajo.",
"<strong>Lifetime</strong> — timestamp de arranque y tiempo transcurrido en ejecución."
],
"detailRefresh": "El diálogo de detalle se refresca cada 3 segundos mientras está abierto. Si el proceso termina con el diálogo abierto, el polling se detiene, aparece un banner ámbar <em>This process has finished</em> y el último snapshot capturado se queda en pantalla (atenuado) para que sigas viendo qué estaba pasando justo antes de que terminara.",
"captureDetailAlt": "Modal de detalle de proceso — secciones Overview, Resources, Command y Lifetime para un único PID",
"captureDetailCaption": "Diálogo de detalle por proceso abierto desde una fila de la lista. El color de acento sigue al de la tarjeta que lo abrió (azul para CPU, índigo para Memory)."
},
"middle": {
"heading": "Medio: gráficas de métricas del nodo",
"body1": "Bajo la fila superior se encuentra el componente <code>NodeMetricsCharts</code> — gráficas históricas de CPU, memoria y E/S de disco tomadas del propio almacén RRD de Proxmox vía <code>/api/node/metrics</code>. Un selector de timeframe alterna entre <em>1 hora / 24 horas / 7 días / 30 días / 1 año</em>; la resolución de los datos baja a medida que crece la ventana para que la gráfica se mantenga fluida.",
@@ -79,13 +79,13 @@
},
{
"tool": "Log2RAM (consciente de SSD, automático)",
"what": "Detecta si el disco raíz es SSD / NVMe e instala Log2RAM desde el git upstream. Dimensiona el ramdisk según la RAM del host (128M / 256M / 512M), programa sync periódico y un auto-sync con umbral del 95 %. Ajusta los límites de journald para caber en el ramdisk.",
"what": "Reduce el desgaste del SSD/NVMe moviendo /var/log a una ramdisk tmpfs con sync periódico al disco. Se instala desde el proyecto oficial cuando el disco raíz es SSD o NVMe. Dimensiona la ramdisk según la RAM (128M / 256M / 512M), programa el sync periódico y un guardián de auto-sync que compacta al 80% y trunca los logs calientes al 92% antes de escribir. Ajusta los límites de journald para caber en la ramdisk. Detalle completo en <link>Log2RAM</link>.",
"category": "Storage",
"categorySlug": "storage"
},
{
"tool": "ZFS autotrim (solo SSD)",
"what": "Activa zpool autotrim=on en cada pool ZFS cuyos vdevs sean todos SSD/NVMe con soporte TRIM (comprueba /sys/block/<dev>/queue/rotational y discard_granularity). Los pools respaldados por HDDs se saltan automáticamente. Solo los pools realmente cambiados por ProxMenux quedan registrados para el uninstall — los pools en los que activaste autotrim a mano se dejan en paz.",
"what": "Activa zpool autotrim=on en cada pool ZFS cuyos vdevs sean todos SSD/NVMe con soporte TRIM (comprueba /sys/block/[dev]/queue/rotational y discard_granularity). Los pools respaldados por HDDs se saltan automáticamente. Solo los pools realmente cambiados por ProxMenux quedan registrados para el uninstall — los pools en los que activaste autotrim a mano se dejan en paz.",
"category": "Storage",
"categorySlug": "storage"
},
@@ -25,43 +25,43 @@
"categories": [
{
"name": "Basic Settings",
"description": "Repositorios, upgrade del sistema, zona horaria, locale, utilidades comunes."
"description": "Sanea las fuentes APT, ejecuta el upgrade oficial de Proxmox y fija zona horaria, locale y utilidades básicas. Es la base sobre la que apoyan todas las demás categorías."
},
{
"name": "System",
"description": "Journald, logrotate, límites del kernel, tuning de memoria, kernel panic, reinicios rápidos."
"description": "Ajusta el subsistema de logs y los límites del kernel para un host que aloja muchas VMs y contenedores. Cubre journald, logrotate, sysctl (memoria, límites de ficheros), comportamiento en panic y reinicios rápidos."
},
{
"name": "Virtualization",
"description": "Auto-instalación de guest agent, activación de IOMMU/VFIO para passthrough de PCI."
"description": "Prepara el host para virtualización avanzada. Auto-instala el guest agent en las plantillas y activa IOMMU/VFIO para passthrough de dispositivos PCI (GPU, controladoras, TPU)."
},
{
"name": "Network",
"description": "APT sobre IPv4, tuning de sysctl de red, Open vSwitch, TCP BBR, nombres de interfaz persistentes."
"description": "Endurece y afina la pila de red del host. Fuerza APT sobre IPv4, aplica sysctl con hardening y tuning de buffers TCP, ofrece Open vSwitch y BBR, y fija nombres persistentes de interfaces por MAC."
},
{
"name": "Storage",
"description": "Dimensionado del ARC de ZFS, ZFS auto-snapshot, límites de velocidad de backups vzdump."
"description": "Configura los subsistemas de almacenamiento habituales de Proxmox: ARC de ZFS, auto-snapshots y límites de velocidad de vzdump para evitar saturar el disco durante backups."
},
{
"name": "Security",
"description": "Desactivar portmapper/rpcbind para reducir la superficie de ataque."
"description": "Reduce la superficie de ataque expuesta por defecto. Desactiva los servicios RPC (portmapper/rpcbind) que Proxmox no necesita pero deja escuchando."
},
{
"name": "Customization",
"description": "Colores y aliases de bashrc, banner MOTD, eliminación del aviso de suscripción."
"description": "Cambia la experiencia visual y de shell del host: colores y aliases en bashrc, banner MOTD y eliminación del aviso de suscripción del web UI."
},
{
"name": "Monitoring",
"description": "OVH Real-Time Monitoring (solo en servidores detectados como OVH)."
"description": "Integra el host con Real-Time Monitoring de OVH. Sólo aparece cuando ProxMenux detecta un servidor OVH."
},
{
"name": "Performance",
"description": "gzip paralelo (pigz) para compresión más rápida en backups y transferencias."
"description": "Acelera las operaciones de compresión (backups, transferencias) sustituyendo gzip por su versión paralela pigz."
},
{
"name": "Optional",
"description": "Fixes de CPU AMD, Fastfetch, Figurine, repo de Ceph, High Availability, Log2RAM."
"description": "Piezas de nicho que no todo host necesita: fixes de CPU AMD, banner Fastfetch, hostname 3D con Figurine, repositorio de Ceph, servicios de Alta Disponibilidad y Log2RAM para reducir el desgaste del SSD."
}
],
"mixTip": {
@@ -136,6 +136,27 @@
"automates": "Este ajuste automatiza el siguiente proceso:",
"outro": "Tras la instalación, verás tu hostname mostrado en ASCII art 3D cada vez que hagas login, dejando claro inmediatamente con qué nodo Proxmox estás trabajando."
},
"log2ram": {
"title": "Instalar Log2RAM (reducción de desgaste en SSD/NVMe)",
"intro": "Log2RAM monta <code>/var/log</code> sobre una ramdisk tmpfs y sincroniza periódicamente el contenido al disco subyacente. En un hipervisor el churn de journald golpea el SSD del sistema cada pocos segundos; mover las escrituras a RAM reduce el desgaste y la I/O de disco sin perder logs — la sincronización periódica los vuelca a disco y un apagado limpio también los vuelca.",
"upstreamLabel": "Proyecto oficial:",
"upstreamUrl": "https://github.com/azlux/log2ram",
"upstreamLinkLabel": "azlux/log2ram en GitHub",
"doesLabel": "Qué hace ProxMenux:",
"doesItems": [
"Detecta si el disco raíz es SSD/NVMe leyendo <code>/sys/block/&lt;dev&gt;/queue/rotational</code>. En un disco rotacional el flujo Automatizado pregunta antes de instalar.",
"Clona el repositorio oficial (<code>azlux/log2ram</code>) en <code>/tmp/log2ram</code> y ejecuta su <code>install.sh</code>, luego habilita la unit systemd <code>log2ram</code>.",
"Dimensiona la ramdisk según la RAM del host: <code>≤ 8 GB → 128M</code>, <code>≤ 16 GB → 256M</code>, <code>&gt; 16 GB → 512M</code>. Escribe el valor en <code>SIZE=</code> de <code>/etc/log2ram.conf</code>.",
"Programa una sincronización periódica a disco vía <code>/etc/cron.d/log2ram</code>: cada 1h / 3h / 6h según el mismo tramo de RAM.",
"Instala un guardián de auto-sync en <code>/usr/local/bin/log2ram-check.sh</code>, conectado a <code>/etc/cron.d/log2ram-auto-sync</code> para ejecutarse cada 10 minutos. Cuando <code>/var/log</code> alcanza el 80% del tamaño de la ramdisk el guardián compacta journald; al 92% además trunca <code>pveproxy access/error</code> y <code>pveam.log</code> antes de sincronizar — el comando <code>log2ram write</code> por sí solo copia tmpfs a disco pero NO reduce la tmpfs, así que este guardián evita que PVE caiga con <em>No space left on device</em> cuando los logs crecen sin control.",
"Ajusta los límites de systemd-journald (<code>SystemMaxUse</code>, <code>RuntimeMaxUse</code>) para que quepan en la ramdisk y así una ráfaga puntual no la llene.",
"Se registra en <code>installed_tools.json</code> para poder revertirlo desde Uninstall Optimizations."
],
"howUseLabel": "Cómo se usa:",
"howUseBody": "En el flujo Automatizado Log2RAM se aplica sin intervención cuando se detecta un disco raíz SSD/NVMe. En el flujo Personalizable el script pregunta por el tamaño, el intervalo de sincronización y si activar el guardián de auto-sync al 90%.",
"verifyLabel": "Verificar y gestionar desde la shell:",
"verifyCode": "# Estado del servicio y timers configurados\nsystemctl status log2ram\nsystemctl list-timers log2ram*\n\n# Uso actual de la ramdisk — /var/log ES la tmpfs\ndf -h /var/log\n\n# Forzar sincronización ahora (tmpfs → disco); NO reduce la tmpfs\nlog2ram write\n\n# Disparar el guardián de auto-sync manualmente (compacta + sincroniza si el uso es alto)\n/usr/local/bin/log2ram-check.sh\n\n# Configuración actual: SIZE, mail, path\ncat /etc/log2ram.conf\n\n# Crons específicos de ProxMenux\ncat /etc/cron.d/log2ram /etc/cron.d/log2ram-auto-sync\n\n# Actividad reciente de Log2RAM\njournalctl -u log2ram -n 50 --no-pager"
},
"autoApplication": {
"title": "Aplicación automática",
"body": "Estas funcionalidades opcionales solo se aplican cuando se seleccionan específicamente durante el proceso post-instalación. Cada funcionalidad puede elegirse individualmente según tus necesidades y preferencias específicas."
@@ -9,7 +9,7 @@
},
"intro": {
"title": "Qué cubre esta categoría",
"body": "Tres optimizaciones relacionadas con almacenamiento: tunear el tamaño de la caché <strong>ARC de ZFS</strong> a una fracción sensata de la RAM del host, instalar y programar <strong>auto-snapshots de ZFS</strong>, y eliminar throttles de <strong>vzdump</strong> para que los backups corran a máxima velocidad. Las tres son independientes — elige las que se ajusten a tu setup."
"body": "Tres optimizaciones relacionadas con almacenamiento: tunear el tamaño de la caché <strong>ARC de ZFS</strong> a una fracción sensata de la RAM del host, instalar y programar <strong>auto-snapshots de ZFS</strong>, y eliminar throttles de <strong>vzdump</strong> para que los backups corran a máxima velocidad. Las tres son independientes — elige las que se ajusten a tu setup. Una cuarta optimización cercana al almacenamiento, <link>Log2RAM</link>, reduce el desgaste del SSD/NVMe moviendo <code>/var/log</code> a una ramdisk — vive en la página Optional porque el menú Personalizable de ProxMenux la agrupa allí."
},
"notTrackedTitle": "Ninguna de estas está en el menú Uninstall",
"notTrackedBody": "A diferencia de la mayoría de optimizaciones post-instalación, las tres opciones de Almacenamiento <strong>no se registran actualmente</strong> en el flujo Uninstall Optimizations. Si las aplicas y más tarde quieres revertir, tendrás que hacerlo a mano. Los comandos manuales de rollback se muestran bajo cada sección.",
@@ -148,6 +148,11 @@
"href": "/docs/post-install/uninstall",
"tail": " — revierte cambios de ARC / vzdump."
},
{
"label": "Log2RAM",
"href": "/docs/post-install/optional#log2ram",
"tail": " — reduce el desgaste del SSD/NVMe usando una ramdisk para /var/log; documentado en Optional."
},
{
"label": "Customizable Post-Install",
"href": "/docs/post-install/customizable",