基于 Docker 的自动化备份与镜像更新流程:从手动到自动的运维升级

作为一名长期与 Docker 打交道的运维工程师,我深知数据备份和镜像更新的重要性。曾经因为手动操作失误导致数据丢失,也经历过半夜被叫起来处理生产环境镜像更新的痛苦。经过多次实践和优化,我总结出了一套完整的自动化流程,今天就来分享给大家。
环境准备与基础配置
在开始之前,我们需要准备以下环境:
# 检查 Docker 版本
docker --version
# 创建备份目录
mkdir -p /opt/backups/docker
mkdir -p /opt/scripts/backup
我建议使用 Docker Compose 来管理服务,这样备份和更新都会更加方便。这里以 WordPress 为例:
# docker-compose.yml
version: '3.8'
services:
wordpress:
image: wordpress:latest
container_name: my-wordpress
volumes:
- wordpress_data:/var/www/html
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
depends_on:
- db
db:
image: mysql:8.0
container_name: mysql-db
volumes:
- db_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
volumes:
wordpress_data:
db_data:
自动化备份脚本编写
备份是运维的生命线。我编写了一个脚本来备份容器数据和配置:
#!/bin/bash
# backup-docker.sh
BACKUP_DIR="/opt/backups/docker"
DATE=$(date +%Y%m%d_%H%M%S)
echo "[$(date)] 开始 Docker 备份..."
# 备份 Docker Compose 配置
cp docker-compose.yml $BACKUP_DIR/compose-backup-$DATE.yml
# 备份所有命名卷
for volume in $(docker volume ls -q); do
echo "备份卷: $volume"
docker run --rm -v $volume:/source -v $BACKUP_DIR:/backup alpine
tar czf /backup/${volume}-backup-$DATE.tar.gz -C /source .
done
# 备份容器列表和镜像列表
docker ps -a > $BACKUP_DIR/containers-list-$DATE.txt
docker images > $BACKUP_DIR/images-list-$DATE.txt
echo "[$(date)] 备份完成,文件保存在: $BACKUP_DIR"
在实际使用中,我踩过一个坑:如果卷数据量很大,备份时间会很长。建议在业务低峰期执行,或者使用增量备份策略。
设置定时备份任务
手动备份容易忘记,使用 crontab 设置自动备份:
# 编辑 crontab
crontab -e
# 添加以下行,每天凌晨2点执行备份
0 2 * * * /bin/bash /opt/scripts/backup/backup-docker.sh >> /var/log/docker-backup.log 2>&1
自动化镜像更新与部署
镜像更新是另一个痛点。我使用 Watchtower 来自动监控和更新容器:
# 启动 Watchtower 服务
docker run -d
--name watchtower
-v /var/run/docker.sock:/var/run/docker.sock
containrrr/watchtower
--interval 3600
--cleanup
--label-enable
但是要注意,生产环境直接自动更新有风险。我推荐使用以下更安全的方式:
#!/bin/bash
# update-images.sh
echo "开始检查镜像更新..."
# 拉取最新镜像但不立即更新
docker-compose pull
# 创建新的容器进行测试
docker-compose up -d --force-recreate --no-deps
# 等待服务就绪
sleep 30
# 检查服务状态
if curl -f http://localhost:8080 > /dev/null 2>&1; then
echo "服务测试通过,移除旧容器"
docker-compose down
docker-compose up -d
else
echo "服务测试失败,回滚到旧版本"
docker-compose down
docker-compose up -d
fi
完整的自动化流程整合
将备份和更新流程整合,形成完整的自动化方案:
#!/bin/bash
# auto-update-backup.sh
set -e
echo "=== 开始自动化备份与更新流程 ==="
# 1. 执行备份
/opt/scripts/backup/backup-docker.sh
# 2. 检查并更新镜像
/opt/scripts/backup/update-images.sh
# 3. 清理旧备份(保留最近7天)
find /opt/backups/docker -name "*.tar.gz" -mtime +7 -delete
find /opt/backups/docker -name "*.yml" -mtime +7 -delete
find /opt/backups/docker -name "*.txt" -mtime +7 -delete
echo "=== 自动化流程完成 ==="
监控与告警
自动化不代表可以完全不管。我设置了简单的监控:
#!/bin/bash
# health-check.sh
# 检查容器状态
if ! docker ps | grep -q "Up"; then
echo "警告:有容器异常停止" | mail -s "Docker 容器异常" admin@example.com
fi
# 检查磁盘空间
DISK_USAGE=$(df /opt/backups | awk 'NR==2 {print $5}' | sed 's/%//')
if [ $DISK_USAGE -gt 90 ]; then
echo "警告:备份磁盘空间不足" | mail -s "磁盘空间告警" admin@example.com
fi
经过这套流程的实施,我的运维工作轻松了很多。最重要的是,再也不用担心因为人为疏忽导致的数据丢失或服务中断了。希望这个分享对大家有所帮助!


太实用了!刚部署完,半夜终于能睡个好觉了 😊