Como todo operador de servidor novato yo había hecho un script que sincronizaba el servidor con rsync y lo guardaba en una carpeta por día del més.
Esto me permitió por un tiempo largo tener un historial de los ultimos 30 días de ejecución del servidor, lo cual sirve para diagnosticar problemas o restaurar copias si ocurriese algun problema grave.
Sobre todo antes de tener un SSD en el servidor que tenía toda la carpeta del servidor cargada en un ramdisk para incrememntar la perfo ya que minecraft hace demasiados commits a disco.
Naturalmente a lo que el servidor creció esto se hizo inviable hasta el punto de ocupar 660GiB!
Me ví contra la espada y la pared ya que necesitaba alguna manera de mantener un historial de cambios sin hacer copias de todos los archivos del servidor de una manera que fuese fácil de navegar sin ocupar cantidades absurdas de espacio.
¿Compresión? Si bien es posible escribir un programa que comprima y descomprima al vuelo sin tocar el disco para editar las nuevas versiones cada día del més esto resulta ser un nivel de complegidad poco razonable para mi tiempo disponible.
¿Un programa que guarde los cambios por sí solo? Si bien esto es un approach un poco más razonable escribir un programa que haga esto implica guardar registros, de metadatos, fechas, y sumas criptográficas o verificaciones binarias, un dolor de cabeza en el que no me quiero meter en este momento. Además: ya estoy trabajando en otro programa distintu cuyos objetivos son hacer algo por el estilo.
Así que te preguntarás ¿Cómo resolví este problema?
Recientemente adquirí un nuevo disco para el servidor ya que necesito espacio para otros proyectos.
Y mientrás removía un disco pequeño del Array y preparaba el nuevo para entrar al array, delibrerando que formatos de sistema de archivos usar fué cuándo me dí cuenta!
Sería genial poder utilizar BTRFS para el sistema de archivos así podría soportar snapshots de forma nativa! Y el sistema de arvhivos de mi array de almacenamiento es EXT4 el cual se puede convertir a BTRFS, Pero luego de un poco de investigación concluí que para mi caso de uso BTRFS no es la mejor opción, requiero de la sólida confiabilidad de EXT4.
Fue entonces cuando se me ocurrió: todos los sys admin sabemos Linux tiene esta hermosa filosofía donde todo es un archivo! ¿Porqué no? simplemente: creo un archivo vacío dentro de mi sistema de archivos EXT4 y lo formateo como un sistema de archivos BTRFS y lo monto en el LXC que ejecuta mis backups.
Y te preguntarás ¿Porqué no hice esto en primer lugar? Pués resulta que no se puede elejir el formato de un LXC ya que este es un simple sandbox no un sistema operativo, entonces; nunca se me ocurrió elejir el formato del almacenamiento del LXC.
En el resto de este artículo voy a cubrir cómo lograr esto en Proxmox (el cual es una distribución basada en debian)
Primero crea un archivo vacío
touch myBtrfsDrive.img
Nota que .img no es necesario esto es linux no windows, lo escribimos así para nosotros saber que es el archivo.
Expandimos el archivo en nuestro sistema
truncate -s 100G myBtrfsDrive.img
Formateamos el archivo como un sistema de arvhicos btrfs
mkfs.btrfs -s 4K -n 64K -L "My Awesome Virtual Drive" ./myBtrfsDrive.img
Seteamos el tamaño de bloque a 4Kb porque ese es el tamaño físico de los sectores del disco donde estoy creando este archivo, ajusta este valor de acuerdo a los datos de smartctl.
-n 64K es el minimo tamaño de bloque para cada archivo, ajusta esto de acuerdo a tu aplicación.
-L le dá un nombre al sistema de archivos lo cual siempre está cool!
La salida de btrfs debería mostrarnos que nuestro nuevo disco virtual formateado tiene el espacio disponible que seteamos con truncate:

Crea 2 directorios donde montar el disco virtual
mkdir montado-main
mkdir montado
Montamos el disco en el segundo directorio
sudo mount -o compress=zstd:15 ./myBtrfsDrive.img ./montado
La opcion de montaje compress=zstd:15 setea la compresión zip al máximo de ratio, los valores válidos son de -15 a 15, si no deseas montarlo con compresión ignora la sección de "-o compress=zstd:15" entera.

Como lo montamos con sudo el directorio será del usuario root.
correjimos esto si es necesario con sudo chown $USER:$USER -R ./montado
Si nos colocamos en el directorio y ejecutamos un df -h deberías observar que tiene el tamaño que seteaste con truncate.

Ahora vamos a crear 2 subvolúmenes de btrfs para nuestro backup.
- @Main para guardar el estado actual
- @Snapshots para guardar nuestras snapshots
btrfs subvolume create @Snapshots
btrfs subvolume create @Main

Volvemos al directorio padre, ahora vamos a montar el subvolumen @Main en nuestro directorio montado-main para copiar los archivos allí.
Esto técnicamente no es necesario ya que se puede montar el directorio @Main directamente en el LXC, la ventaja es que esto nos permite montar el subvolumen con diferentes opciones de montaje.
sudo mount -o subvol=@Main,compress=zstd:15 ./myBtrfsDrive.img ./montado-main
Las opciones de montaje se separan con "," la opcion de montaje subvol=@Main le dice a mount que queremos montar el subvolumen @Main.
Notese que estamos usando "@" al principio de los subvolumenes; esto no es requerido es simplemente una convención para que sepamos que es un subvolumen.
si nos situamos en el directorio podremos ver que es nuestra montura de antes.

Si creamos un archivo lo veremos en ambas monturas.
![]()

Ahora debemos hacer esta montura permanente creando un servicio con systemd.
para ello primero necesitamos unun script que monte el archivo, en mi caso hice esto:
#!/bin/bash
sudo fuser -km /media/bigboy01/Nextcloud/imgBackUps
umount /media/bigboy01/Nextcloud/imgBackUps
mount -o compress=zstd:15 /media/bigboy01/Nextcloud/backedUpContainers.img /media/bigboy01/Nextcloud/imgBackUps
Edita las rutas para que sigan con tu setup, fuser es usado para matar los procesos que esten cargados usando esa montura de manera que el script nunca falle en forzosamente desmontar y remontar al ejecutarlo.
Ahora creamos el Unitnfile en /etc/systemd/system/monturas.service
[Unit]
Description=Mounts file systems at /root/scripts/mounts
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
ExecStart=/root/scripts/mounts
[Install]
WantedBy=multi-user.target
reemplaza la ruta de tu ExecStart con la ruta absoluta del script que acabas de crear.
Ahora debemos re cargar la lista de servicios y habilitar el servicio
systemctl daemon-reload
recuerda que el nombre del servicio es el nombre del archivo .service que creaste. Ahora lo habilitamos:
systemctl enable monturas
Antes de reiniciar ejecuta el servicio manualmente para verificar que se monta correctamenre.
systemctl start monturas
Reinicia tu sistema Linux y asegurate que tu disco virtual queda montado.
Ahora solo queda montar el directorio en el LXC, esta es la parte que es específica para Proxmox.
para crear el punto de montaje primero obtén la ruta absoluta del directorio montado-main

En mi caso: /home/reiikz/Escritorio/montado-main
Ahora edita tu archivo de configuración LXC localizado en /etc/pve/lxc/<id de tu contenedor>.conf
Recuerda apagar el contenedor antes de comenzar!
Agrega una linea con el siguiente texto:
mp<numero de montaje (debe ser único)>:<ruta absoluta del host>,mp=<ruta absoluta dentro del contenedor>,size=0T
En mi caso queda:
mp5:/home/reiikz/Escritorio/montado-main,mp=/respaldo,size=0T
Enciende el contenedor.
Lo siguiente es actualizar el dueño del directorio en el sistema host ya que esto no es posible desde el LXC.
Los LXC en proxmox suman 100000+id para los id de grupo y de usuario.
Por ejemplo si mi usario que necesita escribir al directorio tiene id 1000 la id del sistema host se convierte en 101000
Para obtener la id puedes usar el comando id
id $USER
o
id <username>
![]()
![]()
Eso lo ejecutas en el contenedor desde donde quieres escribir al disco virtual y desde el usuario el cual debería tener permiso.
Ahora sabiendo el uid y gid sumas 100000 a esos numero y usas para cambiar el dueño en el sistema host, en mi caso 101000
sudo chown -R <uid>:<gid> <ruta absoluta del punto de montaje en el host>
en mi caso queda
sudo chown -R 101000:101000 /home/reiikz/Escritorio/montado-main
And we're done con el setup de archivos! ya puedes hacer backups a tu sistema de archivos btrfs virtual!
Lo siguiente es hacer un pequeño script en el sistema host que tome snapshots de tu sistema de archivos periodicamente con el intervalo que tu quieras.
Aquí te dejo un script de ejemplo que hace snapshots de btrfs cada día y guarda los ultimos 29 días de snapshots
#!/bin/bash
lastDay="$(date "+%d" -d @$(($(date "+%s")-86400*29)))"
today="$(date "+%d")"
# Usage takeSnapshot <src subvolume> <dest subvolume>
function takeSnapshot {
local src="$1"
local dest="$2/$today"
local old="$2/$lastDay"
[ -e "$dest" ] && btrfs subvolume delete "$dest"
btrfs subvolume snapshot -r "$src" "$dest"
[ -e "$old" ] && btrfs subvolume delete "$old"
}
takeSnapshot "/home/reiikz/Escritorio/montado/@Main" "/home/reiikz/Escritorio/montado/@Snapshots"
Si quieres agregar más monturas puedes usar con más snapshots puedes agregar más lineas con
takeSnapshot "<Subvolumen principal>" "<Subvolumen donde guardo mis snapshots>"
El ejemplo usa mis rutas! cambialas apra las tuyas.
Notese que estoy haciendo referencia a los subvolumenes en la montura "montado" no "montado-main" que es la que usamos para el LXC.