Docker Contenedor Respalda and Restaura

Implementing reliable backup and restore procedures for Docker contenedores and their data is critical for business continuity. Esta guía completa cubre contenedor commit, export/import operations, volumen backup strategies, tar-based archival, automated backup scripts, scheduling, and disaster recovery procedures. Proper backup practices protect against data loss and enable quick recovery from failures.

Tabla de Contenidos

Comprendiendo Respalda Strategies

Different backup strategies address different recovery objectives.

Respalda types:

  • Full backup: Complete contenedor state and volúmenes
  • Incremental backup: Only changed data since last backup
  • Differential backup: Changed data since full backup
  • Snapshot backup: Point-in-time state capture
  • Continuous replication: Real-time data sync

Recovery objectives (RTO/RPO):

  • RTO: Recovery Time Objective (acceptable downtime)
  • RPO: Recovery Point Objective (acceptable data loss)
  • Full backups: Lower RTO but slower
  • Incremental/differential: Higher RTO but efficient almacenamiento
# Plan backup strategy based on requirements
cat > backup-strategy.txt <<'EOF'
Contenedor: production-db
Type: Stateful (PostgreSQL)
RTO: 2 hours
RPO: 1 hour
Strategy: Daily full backup + hourly volumen snapshots

Contenedor: web-api
Type: Stateless (API)
RTO: 15 minutes
RPO: None (rebuilt from code)
Strategy: Imagen export on release, no volumen backup

Contenedor: cache
Type: Ephemeral (Redis)
RTO: N/A
RPO: N/A
Strategy: No backup needed
EOF

Contenedor Imagen Respalda

Back up contenedor configurations as Docker imágenes.

Commit contenedor to imagen:

# Crea contenedor from base imagen
docker run -d --name myapp-v1 myapp:latest

# Make modifications to contenedor
docker exec myapp-v1 apt-get install -y extra-package

# Commit contenedor as new imagen
docker commit myapp-v1 myapp:backup-v1

# List imágenes to verifica
docker imágenes | grep myapp

# Tag imagen for almacenamiento
docker tag myapp:backup-v1 myregistry.com/myapp:backup-v1

# Push to registro for safekeeping
docker push myregistry.com/myapp:backup-v1

# Verifica imagen backed up
docker pull myregistry.com/myapp:backup-v1

Save imagen to tar file:

# Save imagen as tar archive
docker save myapp:latest -o myapp-imagen.tar

# Verifica tar created
ls -lh myapp-imagen.tar

# Compress for almacenamiento efficiency
gzip myapp-imagen.tar
ls -lh myapp-imagen.tar.gz

# Multiple imágenes in single tar
docker save \
  myapp:v1 \
  myapp:v2 \
  dependencies:latest \
  -o myapp-multi.tar

# Verifica tar contents
tar -tzf myapp-imagen.tar.gz | head -20

Load imagen from tar:

# Load imagen from tar file
docker load -i myapp-imagen.tar

# Or from compressed tar
gunzip myapp-imagen.tar.gz
docker load -i myapp-imagen.tar

# Verifica imagen loaded
docker imágenes | grep myapp

# Tag loaded imagen appropriately
docker tag myapp:latest myregistry.com/myapp:restored

Volumen Respalda and Restoration

Back up persistent data stored in volúmenes.

List and identify volúmenes:

# List all volúmenes
docker volumen ls

# Inspect volumen details
docker volumen inspect myapp-data

# Find volumen mount point
docker volumen inspect myapp-data --format='{{.Mountpoint}}'

# Find volúmenes used by contenedor
docker inspect myapp | grep -A 10 Mounts

Respalda volumen data:

# Crea backup contenedor for volumen access
docker run --rm \
  --volúmenes-from <contenedor-name> \
  -v $(pwd)/backups:/backup \
  ubuntu tar czf /backup/volumen-backup.tar.gz /data

# Respalda specific volumen
docker run --rm \
  -v myapp-data:/data \
  -v $(pwd)/backups:/backup \
  ubuntu tar czf /backup/myapp-data.tar.gz /data

# Verifica backup created
ls -lh backups/myapp-data.tar.gz

# Check backup contents
tar -tzf backups/myapp-data.tar.gz | head

Incremental volumen backups:

# Full backup
docker run --rm \
  -v myapp-data:/data \
  -v $(pwd)/backups:/backup \
  ubuntu tar czf /backup/myapp-data-full.tar.gz /data

# Incremental using rsync
docker run --rm \
  -v myapp-data:/data \
  -v $(pwd)/backups:/backup \
  -v $(pwd)/manifest:/manifest \
  ubuntu:latest bash -c '
    find /data -type f -newer /manifest/last-backup \
    -exec tar czf /backup/myapp-data-incremental.tar.gz {} \;
    touch /manifest/last-backup
  '

Restaura volumen from backup:

# Crea new volumen for restore
docker volumen create myapp-data-restored

# Extract backup into volumen
docker run --rm \
  -v myapp-data-restored:/data \
  -v $(pwd)/backups:/backup \
  ubuntu tar -xzf /backup/myapp-data.tar.gz -C /data

# Verifica data restored
docker run --rm \
  -v myapp-data-restored:/data \
  ubuntu ls -la /data

# Use restored volumen with contenedor
docker run -d \
  --name myapp-restored \
  -v myapp-data-restored:/data \
  myapp:latest

Contenedor Export and Import

Export and import complete contenedor filesystems.

Export contenedor:

# Export running contenedor filesystem
docker export myapp -o myapp-contenedor.tar

# Export stopped contenedor
docker export stopped-contenedor > myapp-backup.tar

# Verifica export
ls -lh myapp-contenedor.tar

# Inspect export contents
tar -tzf myapp-contenedor.tar | head -20

# Compress export for efficiency
gzip myapp-contenedor.tar

Import exported contenedor:

# Import as new imagen
docker import myapp-contenedor.tar.gz myapp:imported

# Verifica imported imagen
docker imágenes | grep imported

# Ejecuta contenedor from imported imagen
docker run -d \
  --name myapp-restored \
  -p 8080:5000 \
  myapp:imported

# Compare original and imported
docker inspect myapp:latest
docker inspect myapp:imported

Export with volumen data:

# Export contenedor with mounted volúmenes
# First, identify volúmenes
docker inspect myapp | grep -A 5 Mounts

# Export filesystem (includes volumen mount points, not data)
docker export myapp -o myapp-with-volúmenes.tar

# Separately backup volumen data
docker run --rm \
  --volúmenes-from myapp \
  -v $(pwd):/backup \
  ubuntu tar czf /backup/myapp-volúmenes.tar.gz /var/lib/docker/volúmenes

# Restaura both contenedor and volúmenes
docker import myapp-with-volúmenes.tar myapp:restore-test

# Recreate volúmenes and restore data separately
docker volumen create myapp-data
docker run --rm \
  -v myapp-data:/data \
  -v $(pwd):/backup \
  ubuntu tar -xzf /backup/myapp-volúmenes.tar.gz -C /

Automated Respalda Scripts

Crea scripts for regular, reliable backups.

Daily backup script:

# Crea backup directory
mkdir -p /backups/docker

cat > /usr/local/bin/backup-docker.sh <<'EOF'
#!/bin/bash

BACKUP_DIR="/backups/docker"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
LOG_FILE="$BACKUP_DIR/backup.log"

# Crea timestamp directory
BACKUP_PATH="$BACKUP_DIR/$TIMESTAMP"
mkdir -p "$BACKUP_PATH"

echo "[$(date)] Starting Docker backup" >> "$LOG_FILE"

# Respalda contenedor imágenes
IMAGES=$(docker imágenes --format "{{.Repositorio}}:{{.Tag}}" | grep -v none)
for imagen in $IMAGES; do
    if [ "$imagen" != "<none>:<none>" ]; then
        echo "[$(date)] Backing up imagen: $imagen" >> "$LOG_FILE"
        docker save "$imagen" -o "$BACKUP_PATH/${imagen//\//_}.tar" 2>> "$LOG_FILE"
    fi
done

# Respalda volúmenes
VOLUMES=$(docker volumen ls --format "{{.Name}}")
for volumen in $VOLUMES; do
    echo "[$(date)] Backing up volumen: $volumen" >> "$LOG_FILE"
    docker run --rm \
        -v "$volumen":/volumen \
        -v "$BACKUP_PATH":/backup \
        ubuntu tar czf "/backup/${volumen}.tar.gz" -C /volumen . 2>> "$LOG_FILE"
done

# Respalda contenedor configs
docker ps -a --format "{{.Names}}" | while read contenedor; do
    echo "[$(date)] Exporting contenedor: $contenedor" >> "$LOG_FILE"
    docker export "$contenedor" -o "$BACKUP_PATH/${contenedor}.tar" 2>> "$LOG_FILE"
done

# Compress backup directory
echo "[$(date)] Compressing backup" >> "$LOG_FILE"
cd "$BACKUP_DIR"
tar czf "${TIMESTAMP}.tar.gz" "$TIMESTAMP"
rm -rf "$TIMESTAMP"

# Calculate size
SIZE=$(du -sh "${TIMESTAMP}.tar.gz" | cut -f1)
echo "[$(date)] Respalda completed. Size: $SIZE" >> "$LOG_FILE"

# Keep only last 7 backups
find "$BACKUP_DIR" -maxdepth 1 -name "*.tar.gz" -type f -mtime +7 -delete

EOF

chmod +x /usr/local/bin/backup-docker.sh

# Ejecuta backup
/usr/local/bin/backup-docker.sh

# Verifica backup
ls -lh /backups/docker/

Selective backup script:

cat > /usr/local/bin/backup-selective.sh <<'EOF'
#!/bin/bash

BACKUP_DIR="/backups/docker"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_PATH="$BACKUP_DIR/$TIMESTAMP"

mkdir -p "$BACKUP_PATH"

# List of contenedores to backup
CONTAINERS_TO_BACKUP=(
    "production-db"
    "production-api"
    "cache-redis"
)

# Respalda specific contenedores only
for contenedor in "${CONTAINERS_TO_BACKUP[@]}"; do
    if docker ps -a --format "{{.Names}}" | grep -q "^${contenedor}$"; then
        echo "Backing up: $contenedor"
        
        # Export contenedor
        docker export "$contenedor" -o "$BACKUP_PATH/${contenedor}-fs.tar"
        
        # Respalda volúmenes used by contenedor
        VOLUMES=$(docker inspect "$contenedor" --format='{{range .Mounts}}{{.Name}}{{"\n"}}{{end}}')
        for volumen in $VOLUMES; do
            if [ ! -z "$volumen" ]; then
                docker run --rm \
                    -v "$volumen":/volumen \
                    -v "$BACKUP_PATH":/backup \
                    ubuntu tar czf "/backup/${contenedor}-${volumen}.tar.gz" -C /volumen .
            fi
        done
    fi
done

# Crea manifest
cat > "$BACKUP_PATH/manifest.txt" <<MANIFEST
Respalda Date: $(date)
Contenedores: ${CONTAINERS_TO_BACKUP[@]}
MANIFEST

# Compress and cleanup
cd "$BACKUP_DIR"
tar czf "${TIMESTAMP}.tar.gz" "$TIMESTAMP"
rm -rf "$TIMESTAMP"

echo "Respalda completed: ${TIMESTAMP}.tar.gz"
EOF

chmod +x /usr/local/bin/backup-selective.sh

Scheduling and Retention

Schedule regular backups with retention policies.

Cron scheduling:

# Edit crontab
crontab -e

# Add backup job (daily at 2 AM)
0 2 * * * /usr/local/bin/backup-docker.sh

# Hourly backups for critical contenedores
0 * * * * /usr/local/bin/backup-selective.sh

# Weekly full backup
0 3 0 * * /usr/local/bin/backup-docker.sh --full

# View scheduled jobs
crontab -l

Retention policy:

cat > /usr/local/bin/cleanup-backups.sh <<'EOF'
#!/bin/bash

BACKUP_DIR="/backups/docker"
RETENTION_DAYS=30

echo "Cleaning up backups older than $RETENTION_DAYS days..."

# Remueve old backups
find "$BACKUP_DIR" -maxdepth 1 -name "*.tar.gz" -type f -mtime +$RETENTION_DAYS -delete

# Remueve incomplete backups
find "$BACKUP_DIR" -maxdepth 1 -type d -name "[0-9]*" -mtime +1 -exec rm -rf {} \;

# Report cleanup
echo "Cleanup completed. Current backups:"
ls -lh "$BACKUP_DIR" | grep tar.gz

EOF

chmod +x /usr/local/bin/cleanup-backups.sh

# Schedule cleanup daily
# Add to crontab:
# 0 4 * * * /usr/local/bin/cleanup-backups.sh

Respalda rotation:

# Keep multiple versions: daily, weekly, monthly

cat > /usr/local/bin/backup-with-rotation.sh <<'EOF'
#!/bin/bash

BACKUP_DIR="/backups/docker"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)

# Determine backup type based on date
DAY=$(date +%d)
DOW=$(date +%w)

if [ "$DAY" -eq 1 ]; then
    BACKUP_TYPE="monthly"
elif [ "$DOW" -eq 0 ]; then
    BACKUP_TYPE="weekly"
else
    BACKUP_TYPE="daily"
fi

BACKUP_PATH="$BACKUP_DIR/${BACKUP_TYPE}-${TIMESTAMP}"
mkdir -p "$BACKUP_PATH"

# Ejecuta backup
docker save $(docker imágenes --format "{{.Repositorio}}:{{.Tag}}" | grep -v none) \
    -o "$BACKUP_PATH/imágenes.tar"

# Keep only recent backups
# Daily: 7 most recent
# Weekly: 4 most recent
# Monthly: 12 most recent

case $BACKUP_TYPE in
    daily)
        find "$BACKUP_DIR" -maxdepth 1 -name "daily-*" -type d | sort -r | tail -n +8 | xargs rm -rf
        ;;
    weekly)
        find "$BACKUP_DIR" -maxdepth 1 -name "weekly-*" -type d | sort -r | tail -n +5 | xargs rm -rf
        ;;
    monthly)
        find "$BACKUP_DIR" -maxdepth 1 -name "monthly-*" -type d | sort -r | tail -n +13 | xargs rm -rf
        ;;
esac

EOF

chmod +x /usr/local/bin/backup-with-rotation.sh

Disaster Recovery Procedures

Implement systematic recovery procedures for various failure scenarios.

Total host failure recovery:

# Scenario: Host completely lost, need to rebuild everything

# Step 1: Crea new host with Docker installed

# Step 2: Transfer backups to new host
scp -r /backups/docker user@newhost:/backups/

# Step 3: Restaura all imágenes
BACKUP_FILE="/backups/docker/latest.tar.gz"
tar -xzf "$BACKUP_FILE"
cd extracted-backup
for image_tar in *.tar; do
    docker load -i "$image_tar"
done

# Step 4: Recreate volúmenes
for volume_backup in *-volumen.tar.gz; do
    VOLUME_NAME=${volume_backup%-volumen.tar.gz}
    docker volumen create "$VOLUME_NAME"
    docker run --rm \
        -v "$VOLUME_NAME":/data \
        -v .:/backup \
        ubuntu tar -xzf "/backup/$volume_backup" -C /data
done

# Step 5: Inicia contenedores
docker run -d --name myapp -v myapp-data:/data myapp:latest

# Step 6: Verifica restoration
docker ps
docker volumen ls
docker logs myapp

Database contenedor recovery:

# Scenario: Database contenedor corrupted, need restore

# Detén contenedor
docker stop production-db

# Respalda current volumen for forensics
docker run --rm \
    -v production-db-data:/data \
    -v $(pwd):/backup \
    ubuntu tar czf /backup/corrupted-data.tar.gz /data

# Remueve corrupted volumen
docker volumen rm production-db-data

# Restaura from backup
docker volumen create production-db-data
docker run --rm \
    -v production-db-data:/data \
    -v /backups/docker:/backup \
    ubuntu tar -xzf /backup/production-db-data.tar.gz -C /data --strip-components=1

# Reinicia contenedor
docker start production-db

# Verifica recovery
docker logs production-db

Respalda Verification

Verifica backups are valid and recoverable.

Prueba restore procedures:

# Periodically test restores in non-production environment

# Crea test directory
mkdir -p /test-restore

# Extract backup
tar -xzf /backups/docker/latest.tar.gz -C /test-restore/

# Prueba imagen restoration
cd /test-restore/latest
docker load -i $(ls *.tar | head -1)

# Prueba volumen restoration
docker volumen create test-restore-vol
docker run --rm \
    -v test-restore-vol:/data \
    -v $(pwd):/backup \
    ubuntu tar -xzf /backup/*.tar.gz -C /data

# Cleanup test
docker volumen rm test-restore-vol
rm -rf /test-restore

Respalda integrity checks:

# Verifica backup file integrity

# Check tar validity
tar -tzf /backups/docker/latest.tar.gz > /dev/null && echo "Respalda valid" || echo "Respalda corrupted"

# Verifica checksums
sha256sum /backups/docker/*.tar.gz > /backups/docker/checksums.txt
sha256sum -c /backups/docker/checksums.txt

# Document backup metadata
cat > /backups/docker/backup-manifest.txt <<'EOF'
Respalda Date: $(date)
Total Size: $(du -sh /backups/docker | cut -f1)
Contenedores Backed Up: $(ls *.tar | wc -l)
Volúmenes Backed Up: $(ls *-volumen.tar.gz 2>/dev/null | wc -l)
Verified: Yes
EOF

Cloud Almacenamiento Integration

Store backups in cloud almacenamiento for offsite protection.

Upload to AWS S3:

# Instala AWS CLI
sudo apt-get install -y awscli

# Configura credentials
aws configure

# Upload backups to S3
aws s3 cp /backups/docker/latest.tar.gz \
    s3://my-backup-bucket/docker-backups/

# Respalda with timestamp
TIMESTAMP=$(date +%Y%m%d)
aws s3 cp /backups/docker/latest.tar.gz \
    s3://my-backup-bucket/docker-backups/${TIMESTAMP}/

# List backups
aws s3 ls s3://my-backup-bucket/docker-backups/

# Download for restore
aws s3 cp s3://my-backup-bucket/docker-backups/latest.tar.gz \
    /restore/

Automated cloud backup:

cat > /usr/local/bin/backup-to-s3.sh <<'EOF'
#!/bin/bash

BACKUP_DIR="/backups/docker"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
S3_BUCKET="s3://my-backup-bucket"

# Ejecuta backup
/usr/local/bin/backup-docker.sh

# Upload to S3
aws s3 cp "$BACKUP_DIR/$TIMESTAMP.tar.gz" \
    "$S3_BUCKET/docker/$TIMESTAMP.tar.gz"

# Keep only recent backups locally (7 days)
find "$BACKUP_DIR" -maxdepth 1 -name "*.tar.gz" -mtime +7 -delete

# Keep all backups in S3

EOF

chmod +x /usr/local/bin/backup-to-s3.sh

# Schedule
# 0 2 * * * /usr/local/bin/backup-to-s3.sh

Conclusión

Comprehensive Docker backup and restore procedures protect your containerized applications and data from loss. By implementing multiple backup strategies (imágenes, volúmenes, contenedor filesystems), automating schedules, and verifying recovery procedures, you create a resilient infrastructure. Inicia with simple daily full backups, progress to selective backups for critical contenedores, and eventually implement cloud almacenamiento integration for offsite protection. Regular testing of restore procedures ensures you can actually recover when needed. As your containerized infrastructure grows, backup management becomes increasingly critical to business continuity. Make backup verification and disaster recovery drills part of your regular operational procedures.