Iโll show you how to manage file system snapshots on Alpine Linux! Snapshots are like taking a photo of your files at a specific moment - you can go back to that exact state anytime. Itโs perfect for backups, testing changes, or recovering from mistakes!
๐ค What are File System Snapshots?
A snapshot captures the state of your file system at a specific point in time. Unlike regular backups that copy files, snapshots are instant and use minimal space by only tracking changes. Think of it as a save point in a video game - you can always return to that exact moment!
Why use snapshots?
- Instant backups
- Easy rollback from mistakes
- Test changes safely
- Minimal storage usage
- Quick recovery
๐ฏ What You Need
Before starting, youโll need:
- Alpine Linux installed
- Storage space available
- Root access
- Compatible file system (Btrfs or LVM)
- About 20 minutes
๐ Step 1: Choose Your Snapshot System
Alpine Linux supports multiple snapshot methods:
# Check current file system
df -T
mount | grep "^/dev"
# Option 1: Btrfs (Best for snapshots)
apk add btrfs-progs
# Option 2: LVM snapshots
apk add lvm2 lvm2-extra
# Option 3: ZFS (Advanced)
apk add zfs zfs-lts
# For this guide, we'll focus on Btrfs and LVM
๐ Step 2: Set Up Btrfs Snapshots
If using Btrfs file system:
# Check if using Btrfs
btrfs filesystem show
# Create snapshot directory
mkdir -p /snapshots
# Create your first snapshot
btrfs subvolume snapshot / /snapshots/root-$(date +%Y%m%d-%H%M%S)
# List snapshots
btrfs subvolume list /
# Create read-only snapshot (recommended)
btrfs subvolume snapshot -r / /snapshots/root-backup-$(date +%Y%m%d)
# Verify snapshot
ls -la /snapshots/
๐ Step 3: Set Up LVM Snapshots
For LVM-based systems:
# Check LVM setup
lvdisplay
vgdisplay
# Create snapshot of logical volume
# Syntax: lvcreate -L size -s -n snapshot_name /dev/vg/lv
lvcreate -L 1G -s -n root_snap_$(date +%Y%m%d) /dev/vg0/root
# List snapshots
lvs
# Mount snapshot to access files
mkdir -p /mnt/snapshot
mount /dev/vg0/root_snap_$(date +%Y%m%d) /mnt/snapshot
# Check snapshot usage
lvdisplay /dev/vg0/root_snap_*
๐ Step 4: Automate Snapshots
Create automatic snapshot system:
# Create snapshot script
cat > /usr/local/bin/auto-snapshot.sh << 'EOF'
#!/bin/sh
# Automatic snapshot creation
SNAPSHOT_DIR="/snapshots"
FILESYSTEM="/"
MAX_SNAPSHOTS=10
DATE=$(date +%Y%m%d-%H%M%S)
# Function for Btrfs snapshots
create_btrfs_snapshot() {
echo "Creating Btrfs snapshot..."
btrfs subvolume snapshot -r "$FILESYSTEM" "$SNAPSHOT_DIR/auto-$DATE"
# Clean old snapshots
SNAPSHOTS=$(ls -1 $SNAPSHOT_DIR/auto-* 2>/dev/null | sort -r)
COUNT=$(echo "$SNAPSHOTS" | wc -l)
if [ $COUNT -gt $MAX_SNAPSHOTS ]; then
echo "Removing old snapshots..."
echo "$SNAPSHOTS" | tail -n +$((MAX_SNAPSHOTS + 1)) | while read snap; do
btrfs subvolume delete "$snap"
done
fi
}
# Function for LVM snapshots
create_lvm_snapshot() {
VG="vg0"
LV="root"
SIZE="1G"
echo "Creating LVM snapshot..."
lvcreate -L $SIZE -s -n snap_$DATE /dev/$VG/$LV
# Remove old snapshots
OLD_SNAPS=$(lvs --noheadings -o lv_name | grep "^snap_" | sort | head -n -$MAX_SNAPSHOTS)
for snap in $OLD_SNAPS; do
echo "Removing old snapshot: $snap"
lvremove -f /dev/$VG/$snap
done
}
# Detect and run appropriate snapshot method
if btrfs filesystem show / >/dev/null 2>&1; then
create_btrfs_snapshot
elif lvs >/dev/null 2>&1; then
create_lvm_snapshot
else
echo "No supported snapshot system found!"
exit 1
fi
echo "Snapshot completed: $DATE"
EOF
chmod +x /usr/local/bin/auto-snapshot.sh
# Add to cron for hourly snapshots
echo "0 * * * * /usr/local/bin/auto-snapshot.sh" | crontab -
๐ Step 5: Manage Snapshots
Tools for snapshot management:
# Create snapshot manager
cat > /usr/local/bin/snapshot-manager.sh << 'EOF'
#!/bin/sh
# Snapshot Manager
show_menu() {
echo "๐ธ Snapshot Manager"
echo "=================="
echo "1. List snapshots"
echo "2. Create snapshot"
echo "3. Delete snapshot"
echo "4. Compare snapshots"
echo "5. Restore from snapshot"
echo "6. Snapshot info"
echo "7. Exit"
}
list_snapshots() {
echo -e "\n๐ Available Snapshots:"
if btrfs filesystem show / >/dev/null 2>&1; then
btrfs subvolume list / | grep snapshot
else
lvs | grep snap_
fi
}
create_snapshot() {
echo -n "Enter snapshot name: "
read name
if btrfs filesystem show / >/dev/null 2>&1; then
btrfs subvolume snapshot -r / /snapshots/$name
else
lvcreate -L 1G -s -n $name /dev/vg0/root
fi
echo "โ
Snapshot created: $name"
}
delete_snapshot() {
list_snapshots
echo -n -e "\nEnter snapshot to delete: "
read name
if btrfs filesystem show / >/dev/null 2>&1; then
btrfs subvolume delete /snapshots/$name
else
lvremove -f /dev/vg0/$name
fi
echo "โ
Snapshot deleted: $name"
}
compare_snapshots() {
echo "Comparing snapshots..."
# Add comparison logic here
}
restore_snapshot() {
echo "โ ๏ธ WARNING: This will restore system to snapshot state!"
echo -n "Continue? (y/N): "
read confirm
if [ "$confirm" != "y" ]; then
return
fi
# Add restore logic here
echo "โ
Restore completed"
}
# Main loop
while true; do
show_menu
echo -n "Select option: "
read choice
case $choice in
1) list_snapshots ;;
2) create_snapshot ;;
3) delete_snapshot ;;
4) compare_snapshots ;;
5) restore_snapshot ;;
6) snapshot_info ;;
7) exit 0 ;;
*) echo "Invalid option" ;;
esac
echo -e "\nPress Enter to continue..."
read
clear
done
EOF
chmod +x /usr/local/bin/snapshot-manager.sh
๐ Step 6: Snapshot Best Practices
Implement smart snapshot policies:
# Create snapshot policy configuration
cat > /etc/snapshot-policy.conf << 'EOF'
# Snapshot Policy Configuration
# Retention settings
HOURLY_SNAPSHOTS=24
DAILY_SNAPSHOTS=7
WEEKLY_SNAPSHOTS=4
MONTHLY_SNAPSHOTS=12
# Paths to snapshot
SNAPSHOT_PATHS="/ /home /var"
# Exclude patterns
EXCLUDE_PATTERNS="/tmp /var/tmp /var/cache"
# Snapshot naming
SNAPSHOT_PREFIX="auto"
SNAPSHOT_TYPE="readonly"
EOF
# Advanced snapshot script
cat > /usr/local/bin/smart-snapshot.sh << 'EOF'
#!/bin/sh
# Smart snapshot management
source /etc/snapshot-policy.conf
# Create snapshot with metadata
create_snapshot() {
local path=$1
local type=$2
local name="${SNAPSHOT_PREFIX}-${type}-$(date +%Y%m%d-%H%M%S)"
echo "Creating $type snapshot of $path..."
if btrfs filesystem show $path >/dev/null 2>&1; then
if [ "$SNAPSHOT_TYPE" = "readonly" ]; then
btrfs subvolume snapshot -r $path /snapshots/$name
else
btrfs subvolume snapshot $path /snapshots/$name
fi
# Add metadata
echo "path=$path" > /snapshots/$name.meta
echo "type=$type" >> /snapshots/$name.meta
echo "date=$(date)" >> /snapshots/$name.meta
fi
}
# Rotate snapshots based on policy
rotate_snapshots() {
local type=$1
local keep=$2
echo "Rotating $type snapshots (keeping $keep)..."
# List snapshots of this type
SNAPS=$(ls -1 /snapshots/${SNAPSHOT_PREFIX}-${type}-* 2>/dev/null | sort -r)
COUNT=$(echo "$SNAPS" | wc -l)
if [ $COUNT -gt $keep ]; then
echo "$SNAPS" | tail -n +$((keep + 1)) | while read snap; do
echo "Removing old snapshot: $snap"
btrfs subvolume delete "$snap"
rm -f "${snap}.meta"
done
fi
}
# Main execution
HOUR=$(date +%H)
DAY=$(date +%d)
WEEKDAY=$(date +%w)
# Hourly snapshot
create_snapshot "/" "hourly"
rotate_snapshots "hourly" $HOURLY_SNAPSHOTS
# Daily snapshot at midnight
if [ "$HOUR" = "00" ]; then
create_snapshot "/" "daily"
rotate_snapshots "daily" $DAILY_SNAPSHOTS
fi
# Weekly snapshot on Sunday
if [ "$WEEKDAY" = "0" ] && [ "$HOUR" = "00" ]; then
create_snapshot "/" "weekly"
rotate_snapshots "weekly" $WEEKLY_SNAPSHOTS
fi
# Monthly snapshot on first day
if [ "$DAY" = "01" ] && [ "$HOUR" = "00" ]; then
create_snapshot "/" "monthly"
rotate_snapshots "monthly" $MONTHLY_SNAPSHOTS
fi
EOF
chmod +x /usr/local/bin/smart-snapshot.sh
# Update cron
crontab -l | grep -v auto-snapshot > /tmp/cron.tmp
echo "0 * * * * /usr/local/bin/smart-snapshot.sh" >> /tmp/cron.tmp
crontab /tmp/cron.tmp
๐ Step 7: Snapshot Recovery
Learn to restore from snapshots:
# Create recovery script
cat > /usr/local/bin/snapshot-recovery.sh << 'EOF'
#!/bin/sh
# Snapshot Recovery Tool
# List available snapshots
echo "๐ธ Available Snapshots for Recovery:"
echo "===================================="
if btrfs filesystem show / >/dev/null 2>&1; then
# Btrfs recovery
btrfs subvolume list / | grep snapshot | nl
echo -e "\n๐ To recover a file:"
echo "cp /snapshots/snapshot-name/path/to/file /path/to/destination"
echo -e "\n๐ To rollback entire system:"
echo "1. Boot from rescue media"
echo "2. Mount root filesystem"
echo "3. mv /mnt/root /mnt/root.old"
echo "4. btrfs subvolume snapshot /mnt/snapshots/snapshot-name /mnt/root"
else
# LVM recovery
lvs | grep snap_ | nl
echo -e "\n๐ To recover files from LVM snapshot:"
echo "1. mount /dev/vg0/snapshot-name /mnt/recovery"
echo "2. cp /mnt/recovery/path/to/file /path/to/destination"
echo "3. umount /mnt/recovery"
fi
# Interactive recovery
echo -e "\n๐ Interactive Recovery"
echo -n "Enter snapshot name to browse: "
read snapshot
if [ -n "$snapshot" ]; then
MOUNT_POINT="/mnt/snapshot-recovery"
mkdir -p $MOUNT_POINT
if btrfs filesystem show / >/dev/null 2>&1; then
# Browse Btrfs snapshot
echo "Snapshot contents:"
ls -la /snapshots/$snapshot/
else
# Mount LVM snapshot
mount /dev/vg0/$snapshot $MOUNT_POINT
echo "Snapshot mounted at: $MOUNT_POINT"
echo "Browse with: cd $MOUNT_POINT"
fi
fi
EOF
chmod +x /usr/local/bin/snapshot-recovery.sh
๐ Step 8: Monitor Snapshot Usage
Track snapshot space usage:
# Create monitoring script
cat > /usr/local/bin/snapshot-monitor.sh << 'EOF'
#!/bin/sh
# Monitor snapshot usage
echo "๐ Snapshot Usage Report"
echo "======================="
echo ""
# Btrfs snapshots
if btrfs filesystem show / >/dev/null 2>&1; then
echo "๐ Btrfs Snapshots:"
# Overall usage
echo "Total filesystem usage:"
btrfs filesystem df /
echo -e "\n๐ธ Snapshot sizes:"
for snap in /snapshots/*; do
if [ -d "$snap" ]; then
SIZE=$(btrfs filesystem du -s $snap 2>/dev/null | tail -1 | awk '{print $2}')
echo " $(basename $snap): $SIZE"
fi
done
fi
# LVM snapshots
if lvs >/dev/null 2>&1; then
echo -e "\n๐ LVM Snapshots:"
# Show snapshot usage
lvs -o lv_name,lv_size,data_percent,snap_percent | grep snap_
# Warning for full snapshots
FULL_SNAPS=$(lvs --noheadings -o lv_name,snap_percent | grep snap_ | \
awk '$2 > 80 {print $1}')
if [ -n "$FULL_SNAPS" ]; then
echo -e "\nโ ๏ธ WARNING: Snapshots near capacity:"
echo "$FULL_SNAPS"
fi
fi
# Disk space check
echo -e "\n๐พ Overall Disk Usage:"
df -h | grep -E "^/dev|^Filesystem"
# Snapshot count
echo -e "\n๐ Snapshot Statistics:"
if btrfs filesystem show / >/dev/null 2>&1; then
TOTAL=$(ls -1 /snapshots/ 2>/dev/null | wc -l)
HOURLY=$(ls -1 /snapshots/auto-hourly-* 2>/dev/null | wc -l)
DAILY=$(ls -1 /snapshots/auto-daily-* 2>/dev/null | wc -l)
WEEKLY=$(ls -1 /snapshots/auto-weekly-* 2>/dev/null | wc -l)
MONTHLY=$(ls -1 /snapshots/auto-monthly-* 2>/dev/null | wc -l)
echo " Total snapshots: $TOTAL"
echo " Hourly: $HOURLY"
echo " Daily: $DAILY"
echo " Weekly: $WEEKLY"
echo " Monthly: $MONTHLY"
fi
EOF
chmod +x /usr/local/bin/snapshot-monitor.sh
# Add monitoring to cron
echo "0 6 * * * /usr/local/bin/snapshot-monitor.sh | mail -s 'Snapshot Report' [email protected]" | crontab -
๐ฎ Practice Exercise
Try managing snapshots:
- Create a test directory
- Take a snapshot
- Modify files
- Restore from snapshot
# Create test environment
mkdir -p /test-data
echo "Original content" > /test-data/file1.txt
echo "Important data" > /test-data/file2.txt
# Take snapshot
btrfs subvolume snapshot -r / /snapshots/before-test
# Modify files
echo "Modified content" > /test-data/file1.txt
rm /test-data/file2.txt
# Check differences
diff /test-data/file1.txt /snapshots/before-test/test-data/file1.txt
# Restore files
cp /snapshots/before-test/test-data/* /test-data/
# Verify restoration
cat /test-data/file1.txt
cat /test-data/file2.txt
๐จ Troubleshooting Common Issues
Snapshot Full
Handle full snapshots:
# Check LVM snapshot usage
lvdisplay | grep -A10 "snap_"
# Extend snapshot size
lvextend -L +1G /dev/vg0/snap_name
# Or merge and recreate
lvconvert --merge /dev/vg0/snap_name
lvcreate -L 2G -s -n new_snap /dev/vg0/root
Cannot Delete Snapshot
Fix deletion issues:
# Btrfs snapshot busy
lsof | grep /snapshots/snapshot-name
fuser -vm /snapshots/snapshot-name
# Force unmount
umount -f /snapshots/snapshot-name
# Delete read-only snapshot
btrfs property set /snapshots/snapshot-name ro false
btrfs subvolume delete /snapshots/snapshot-name
Performance Impact
Minimize snapshot overhead:
# Limit snapshot count
MAX_SNAPSHOTS=5
# Use read-only snapshots
btrfs subvolume snapshot -r / /snapshots/name
# Monitor performance
iostat -x 1
๐ก Pro Tips
Tip 1: Snapshot Before Updates
Always snapshot before changes:
# Pre-update snapshot
cat > /usr/local/bin/pre-update-snapshot.sh << 'EOF'
#!/bin/sh
echo "Creating pre-update snapshot..."
/usr/local/bin/auto-snapshot.sh
echo "Snapshot created. Proceeding with update..."
apk upgrade
EOF
chmod +x /usr/local/bin/pre-update-snapshot.sh
Tip 2: Remote Snapshots
Send snapshots to backup server:
# Send Btrfs snapshot
btrfs send /snapshots/snapshot-name | \
ssh backup@server "btrfs receive /backups/"
# Incremental send
btrfs send -p /snapshots/previous /snapshots/current | \
ssh backup@server "btrfs receive /backups/"
Tip 3: Snapshot Verification
Verify snapshot integrity:
# Check snapshot health
btrfs scrub start /snapshots/
btrfs scrub status /snapshots/
# Compare checksums
find /snapshots/snapshot-name -type f -exec md5sum {} \; > snapshot.md5
md5sum -c snapshot.md5
โ Best Practices
-
Regular snapshots
# Hourly for active systems # Daily for stable systems
-
Test recovery procedures
# Practice restoration monthly # Document recovery steps
-
Monitor space usage
# Set up alerts for full snapshots # Clean old snapshots automatically
-
Use descriptive names
# Good: before-kernel-upgrade-5.15 # Bad: snapshot1
-
Secure snapshots
# Read-only snapshots # Restrict access permissions
๐ What You Learned
Fantastic work! You can now:
- โ Create file system snapshots
- โ Automate snapshot creation
- โ Manage snapshot retention
- โ Restore files from snapshots
- โ Monitor snapshot usage
Your data is now protected with snapshots!
๐ฏ Whatโs Next?
Now that you understand snapshots, explore:
- Incremental backup strategies
- Snapshot replication
- Disaster recovery planning
- Advanced Btrfs/ZFS features
Keep your data safe! ๐ธ