Tres scripts que convierten un servidor Debian, Ubuntu u otra distribución basada en Debian en un sistema Btrfs bien organizado y listo para instantáneas:
setup-btrfs.sh— migra una única partición root en Btrfs a una estructura clara de subvolúmenes, lista para Timeshift y cargas de trabajo con contenedores.setup-timeshift.sh— instala y conecta Timeshift congrub-btrfs, incluida la regeneración automática de GRUB al cerrar la GUI después de guardar un comentario.setup-snapper.sh— una vez que root se ejecuta desde un subvolumen con nombre, añade encima una configuración de Snapper al estilo SUSE: instantáneas de línea de tiempo, instantáneas alrededor de cada cambio deapte instantáneas arrancables desde GRUB mediantegrub-btrfs.
Ejecuta primero setup-btrfs.sh; setup-timeshift.sh y setup-snapper.sh requieren un subvolumen root con nombre y te lo indicarán si aún no es el caso.
setup-btrfs.sh ayuda a convertir un servidor Debian, Ubuntu u otra distribución basada en Debian con una única partición root en Btrfs en un sistema con una estructura clara de subvolúmenes, listo para Timeshift y cargas de trabajo con contenedores. Funciona tanto para el cambio único en una instalación nueva como, después, en un sistema ya en marcha y migrado, para añadir los subvolúmenes que aún falten (sin necesidad de reiniciar).
En un sistema basado en Debian con root en Btrfs, el script:
-
Detecta el dispositivo root actual con
findmnt(por ejemplo/dev/vda2[/@rootfs]→/dev/vda2). -
Monta el nivel superior de Btrfs (
subvolid=5) en/mnt/btrfs-root. -
Comprueba el espacio libre de antemano (cada byte en
/se duplica brevemente durante la migración) y aborta si el espacio es insuficiente. -
Detecta una migración ya (parcialmente) realizada y cambia automáticamente a un modo incremental: si
/ya se ejecuta desde un subvolumen con nombre, root, GRUB y el subvolumen por defecto no se tocan — solo se añaden subvolúmenes para las rutas destino que aún no están montadas por separado, activos de inmediato, sin necesidad de reiniciar. Cada ruta destino se clasifica individualmente: ya configurada correctamente (se omite, ni siquiera aparece en el diálogo de selección), ocupada por otra cosa (se omite con una advertencia, nunca se sobrescribe), o aún pendiente (candidata para selección). -
Pide confirmación explícita en una terminal interactiva (escribir "ja") antes de cambiar nada, con una advertencia sobre lo que hace el script y que un fallo puede dejar el sistema sin arrancar. Se omite sin terminal (ejecuciones automatizadas).
-
Muestra un diálogo de selección interactivo (
whiptail) si se ejecuta en una terminal: los subvolúmenes universalmente útiles (@root,@home,@log,@cache,@tmp_var,@tmp) están preseleccionados, todo lo que depende de la pila de software (bases de datos, ClamAV, Docker/Podman, docroot de servidor web) empieza deseleccionado — ambos ajustables libremente. Las rutas deseleccionadas simplemente se quedan en@sin subvolumen propio. Sin terminal interactiva (por ejemplo, ejecuciones automatizadas), solo se crean los subvolúmenes universalmente útiles sin preguntar. -
Detiene servicios conocidos de bases de datos, datastores y contenedores antes de copiar sus datos si están activos. En modo incremental se reinician después de activar los nuevos montajes; en la migración inicial quedan detenidos hasta el reinicio — para una copia consistente en lugar de archivos a medio escribir.
-
Ofrece opcionalmente una selección interactiva solo con paquetes APT, con descripciones breves, para:
timeshift: snapshots sencillos de restauración del sistema.snapper: gestión de snapshots Btrfs para servidor/CLI.btrbk: backups Btrfs y replicación por SSH.btrfsmaintenance: tareas programadas de scrub, balance, trim y defrag.duperemove: deduplicación de extents Btrfs coincidentes.grub-btrfs: hace que los snapshots de Btrfs sean arrancables desde el menú de GRUB — avanzado: requiere un gestor de snapshots ya configurado (Timeshift/Snapper). Después, ejecutasetup-timeshift.shosetup-snapper.shpara la integración completa.
Las herramientas solo se instalan — no se configuran automáticamente.
-
Crea (de forma idempotente) los siguientes subvolúmenes:
@(nuevo root)@root@home@spool@log@cache@tmp_var@srv@tmp@opt@containers@docker@mongodb@mysql@postgresql@chroma@clamav@stalwart@elasticsearch@opensearch@clickhouse@cassandra@couchdb@neo4j@rabbitmq@docker-volumes@containers-volumes@www
-
Copia el sistema root actual a
@(excluyendo/dev,/proc,/sys,/run,/mnt,/media,/lost+found, además de — derivado automáticamente del mapeo de abajo — cada ruta que tenga su propio subvolumen). -
Copia el contenido de los directorios principales a sus subvolúmenes:
/root→@root/home→@home/var/spool→@spool/var/log→@log/var/cache→@cache/var/tmp→@tmp_var/srv→@srv/tmp→@tmp/opt→@opt/var/lib/containers→@containers/var/lib/docker→@docker/var/lib/mongodb→@mongodb/var/lib/mysql→@mysql/var/lib/postgresql→@postgresql/var/lib/chroma→@chroma/var/lib/clamav→@clamav/var/lib/stalwart→@stalwart/var/lib/elasticsearch→@elasticsearch/var/lib/opensearch→@opensearch/var/lib/clickhouse→@clickhouse/var/lib/cassandra→@cassandra/var/lib/couchdb→@couchdb/var/lib/neo4j→@neo4j/var/lib/rabbitmq→@rabbitmq/var/lib/docker/volumes→@docker-volumes/var/lib/containers/storage/volumes→@containers-volumes/var/www→@www
Los subvolúmenes de bases de datos y datastores (
@mongodb,@mysql,@postgresql,@chroma,@clamav,@stalwart,@elasticsearch,@opensearch,@clickhouse,@cassandra,@couchdb,@neo4j,@rabbitmq) y los volúmenes nombrados de Docker/Podman (@docker-volumes,@containers-volumes) conservan montajes Btrfs normales con CoW y checksums, pero recibenbtrfs property set ... compression noantes de copiar los datos. Así el script no depende de opcionescompress/nodatacowen fstab por subvolumen, que Btrfs no separa de forma fiable entre montajes del mismo sistema de archivos. Las capas de imagen y metadatos en@docker/@containerssiguen usando la política comprimida normal. -
Prepara los puntos de montaje dentro del nuevo root (
@) para que los subvolúmenes se puedan montar allí. -
Modifica
/etc/fstaben el sistema actual:- crea una copia de seguridad
fstab.backup-YYYY-MM-DD-HHMMSS, - comenta las líneas antiguas de root Btrfs como
#OLD-ROOT …, - añade nuevas entradas Btrfs para
/,/home,/var/log,/var/lib/docker,/var/www, etc., usando los subvolúmenes@…correspondientes.
- crea una copia de seguridad
-
Ajusta GRUB (si está presente):
- reemplaza
@rootfspor@en/etc/default/grubsi es necesario, - ejecuta
update-grubogrub-mkconfig -o /boot/grub/grub.cfgsi están disponibles.
- reemplaza
-
Define el subvolumen por defecto de Btrfs como
@, de modo que el sistema arranque desde@. -
Asegura que los puntos de montaje necesarios también existan en el root actual (
/home,/var/lib/docker, …). -
Valida el nuevo
/etc/fstabautomáticamente confindmnt --verify(solo lectura, no remonta nada en caliente) y aborta antes de que reinicies por error con un fstab roto.
Resultado:
- Root se ejecuta desde
@(compatible con Timeshift). - Rutas importantes como
/home,/var/log,/var/lib/docker,/var/wwwviven en subvolúmenes separados.
- Sistema Debian o basado en Debian con:
aptsystemd
- Sistema de ficheros root en Btrfs sobre un único dispositivo (por ejemplo una partición Btrfs
/dev/vda2); no activar LVM para el sistema de ficheros root. - Ejecutar el script como root.
El script instalará automáticamente, si faltan:
rsyncbtrfs-progs
En una ejecución interactiva, el script también puede ofrecer paquetes APT opcionales (timeshift, snapper, btrbk, btrfsmaintenance, duperemove) si están disponibles en los repositorios configurados. En ejecuciones automatizadas/no interactivas esta selección se omite.
Lo más sencillo es usarlo en una instalación nueva de servidor, ya que ahí todos los directorios están vacíos o son pequeños. Pero el script también funciona en sistemas ya en producción, siempre que haya suficiente espacio libre (se comprueba automáticamente — cada byte en
/se duplica brevemente durante la migración). Para una copia consistente, los servicios conocidos de bases de datos, datastores y contenedores se detienen automáticamente antes de copiar sus datos; en modo incremental se reinician después demount -ay en la migración inicial quedan detenidos hasta el reinicio.Aun así, en un sistema en producción: haz una copia de seguridad antes, planifica una ventana de mantenimiento para el reinicio final, y ten en cuenta que las aplicaciones fuera de esta lista (por ejemplo un proceso de servidor web propio con archivos abiertos en
/srvo/var/www) siguen funcionando durante la copia y en teoría podrían acabar con una instantánea inconsistente en su subvolumen.
-
Instala Debian de forma que tengas:
- una pequeña partición EFI (por ejemplo
/dev/vda1), - una partición grande en Btrfs como root (por ejemplo
/dev/vda2). - LVM no seleccionado/activado para el sistema de ficheros root.
- una pequeña partición EFI (por ejemplo
-
Inicia sesión como root (o usa
sudo). -
Clona este repositorio:
git clone https://github.com/debian-btrfs/layout-script.git cd btrfs-layout -
Haz el script ejecutable:
chmod +x setup-btrfs.sh
-
Ejecútalo:
sudo ./setup-btrfs.sh
-
Revisa
/etc/fstaby comprueba que:/usasubvol=@,- las rutas adicionales (
/home,/var/log,/var/lib/docker,/var/www, …) tienen entradas Btrfs con los subvolúmenes@…esperados.
-
Aplica y prueba los montajes:
systemctl daemon-reload mount -a
No debería mostrar errores.
-
Reinicia:
reboot
-
Después del reinicio, verifica:
findmnt -o TARGET,SOURCE,FSTYPE,OPTIONS / findmnt -o TARGET,SOURCE,FSTYPE,OPTIONS /home /var/log /var/lib/docker /var/www
Deberías ver:
/desde...[/@]consubvol=@,/homedesde...[/@home], etc.
En este punto, Timeshift puede usar @ como subvolumen root y tu diseño está listo para snapshots y contenedores.
setup-timeshift.sh conecta una configuración Btrfs existente de Timeshift con grub-btrfs. No adivina ni sobrescribe el dispositivo de backup ni los horarios de snapshots configurados.
- Comprueba que
/se ejecute desde un subvolumen Btrfs con nombre y que Timeshift esté configurado en modo Btrfs con un dispositivo de backup. - Crea una instantánea guardia read-only antes de modificar el sistema.
- Instala
timeshifteinotify-toolscuando sea necesario y reutiliza una instalación manual completa degrub-btrfssi el paquete no está disponible mediante APT. - Corrige el comportamiento conocido del analizador de
grub-btrfsque elimina las comas de los comentarios de Timeshift; el generador original se guarda en/var/lib/btrfs-layout/. - Activa el servicio basado en eventos
grub-btrfsdpara snapshots nuevos, eliminados y programados, y genera la configuración inicial de GRUB. - Instala un
/usr/local/bin/timeshift-launcheradministrado. Usa la autenticación existente de Timeshift, espera a que se cierre la GUI y luego actualiza una vez el menú de snapshots de GRUB para incluir comentarios guardados posteriormente sin sondeo periódico. - Desactiva el antiguo
timeshift-grub-btrfs-sync.serviceal actualizar una instalación existente. - Es idempotente y no reinicia el equipo automáticamente.
- Sistema Debian o basado en Debian con
aptysystemd. - Sistema de archivos root ya en un subvolumen Btrfs con nombre.
- Timeshift configurado previamente en modo Btrfs con un dispositivo de backup seleccionado.
- Ejecutar el script como root.
chmod +x setup-timeshift.sh
sudo ./setup-timeshift.shPara una ejecución automatizada sin terminal:
sudo LAYOUT_SCRIPT_ASSUME_YES=1 ./setup-timeshift.shVerifica la integración con:
systemctl status grub-btrfsd
command -v timeshift-launcher
grub-script-check /boot/grub/grub.cfg
grep -n 'Description' /boot/grub/grub-btrfs.cfgCrea un snapshot con timeshift --create --comments "after update", o créalo desde la GUI y guarda después un comentario. Para snapshots de la GUI, cierra Timeshift después de guardar el comentario; el launcher regenera entonces una vez el menú de snapshots de GRUB. Iniciar directamente /usr/bin/timeshift-gtk omite este paso posterior. GRUB arranca los snapshots en modo solo lectura; esto no implementa un rollback automático del sistema.
setup-snapper.sh convierte un servidor Debian, Ubuntu u otro basado en Debian cuyo sistema de archivos raíz ya se ejecuta desde un subvolumen Btrfs con nombre (por ejemplo mediante setup-btrfs.sh arriba) en una configuración de Snapper al estilo SUSE: instantáneas de línea de tiempo automáticas, instantáneas alrededor de cada cambio de paquete apt e instantáneas arrancables directamente desde el menú de GRUB mediante grub-btrfs.
En un sistema Debian (o basado en Debian) cuyo / ya está en un subvolumen Btrfs con nombre, el script:
- Verifica que
/sea Btrfs y se ejecute desde un subvolumen con nombre (p. ej.@); si no, aborta indicando que se ejecute antessetup-btrfs.sh. - Crea antes del primer cambio una instantánea Btrfs read-only del subvolumen raíz actual (p. ej.
@.before-snapper-setup-...) como punto de recuperación manual si la configuración falla. - Instala
snappereinotify-tools(necesario para quegrub-btrfsddetecte nuevas instantáneas) si faltan. - Pide confirmación explícita en una terminal interactiva (escribiendo "ja") antes de cambiar nada. Sin terminal, el script aborta salvo que
LAYOUT_SCRIPT_ASSUME_YES=1esté definido. - Crea la configuración
rootde Snapper (idempotente — se omite si ya existe), lo que crea.snapshotscomo subvolumen Btrfs anidado. - Añade
.snapshotscomo entrada propia en/etc/fstaby lo monta. Lafstabanterior se guarda antes y se restaura automáticamente si fallafindmnt --verifyomount -a. - Establece una política de línea de tiempo al estilo SUSE en
/etc/snapper/configs/root(TIMELINE_CREATE,TIMELINE_CLEANUP,NUMBER_CLEANUPy valores conservadores deTIMELINE_LIMIT_*para hora/día/semana/mes/año). - Instala hooks propios de
apt(DPkg::Pre-Invoke/DPkg::Post-Invoke) que crean un par de instantáneas pre/post en cada cambio de paquete — a diferencia del pluginzyppde openSUSE, Debian/Ubuntu no incluye esta integración, así que el script escribe pequeños scripts auxiliares para ello. - Activa los temporizadores systemd
snapper-timeline.timerysnapper-cleanup.timer. - Instala
grub-btrfssi está disponible en los repositorios APT configurados, configuragrub-btrfsdpara vigilar el directorio/.snapshotsde Snapper y ejecutaupdate-grub(ogrub-mkconfig) para que las instantáneas aparezcan como entradas arrancables de solo lectura en el menú de GRUB. Timeshift no es necesario para este recorrido. Si el paquete no está disponible, la configuración de Snapper continúa sin integración en el menú de GRUB.
Examinar instantáneas, comparar archivos individuales y arrancar en modo solo lectura una instantánea desde el menú de GRUB (grub-btrfs) funcionan con esta configuración si grub-btrfs está disponible. La instantánea de guardia es read-only a propósito y sirve como punto de recuperación manual: arrancar un sistema de rescate, montar el top-level de Btrfs, crear desde ella una nueva instantánea raíz escribible y ajustar de nuevo bootloader/fstab. Una reversión completa del sistema arrancable como la que hace snapper rollback en openSUSE requiere además que root se ejecute desde dentro de un subvolumen .snapshots/<N>/snapshot; esto no ocurre automáticamente con un diseño @ simple.
- Sistema Debian o basado en Debian con
aptysystemd. - Sistema de archivos raíz ya en un subvolumen Btrfs con nombre (si no, ejecutar antes
setup-btrfs.sharriba). - Ejecutar el script como root.
El script instalará los siguientes paquetes si faltan: snapper, inotify-tools, opcionalmente grub-btrfs.
-
Asegurarse de que
/ya se ejecuta desde un subvolumen Btrfs con nombre (versetup-btrfs.sharriba). -
Hacer el script ejecutable y ejecutarlo:
chmod +x setup-snapper.sh sudo ./setup-snapper.sh
Para ejecuciones automatizadas sin terminal:
sudo LAYOUT_SCRIPT_ASSUME_YES=1 ./setup-snapper.sh
-
Verificar:
snapper list-configs snapper create -d test && snapper list && snapper delete <número> systemctl status snapper-timeline.timer snapper-cleanup.timer grub-btrfsd systemctl cat grub-btrfsd.service
En una configuración solo con Snapper, el
ExecStartefectivo debe contenergrub-btrfsd --syslog /.snapshotsy no debe contener--timeshift-auto.setup-snapper.shysetup-timeshift.shgestionan el mismo drop-in; ejecuta el script correspondiente al gestor de snapshots elegido.Instalar/eliminar un paquete pequeño para confirmar que los hooks de
aptcrean un par de instantáneas pre/post, y reiniciar para confirmar que el menú de GRUB muestra un submenú de instantáneas.
Este proyecto está licenciado bajo la GNU General Public License v3.0 o posterior (GPL-3.0-or-later).
Ver el archivo LICENSE para más detalles.