哪些实用脚本能简化Docker操作?

wen 实用脚本 3

哪些实用脚本能简化Docker操作?一文掌握5大效率工具

导语:Docker已经成为现代开发和运维的标配,但日常操作中的重复命令、复杂参数和繁琐清理流程让不少人头疼,本文精选5个经过实战检验的Shell脚本,覆盖镜像构建、容器管理、日志清理、环境部署和故障排查五大场景,帮你把Docker操作效率提升3倍以上。

哪些实用脚本能简化Docker操作?

📑 目录导读

  • 为什么需要Docker脚本
  • 一键构建与推送镜像(docker-build-push.sh
  • 批量清理无用容器与镜像(docker-cleanup.sh
  • 自动化部署多容器应用(docker-deploy.sh
  • 实时监控容器日志并告警(docker-log-watcher.sh
  • Docker环境健康检查(docker-health.sh
  • 常见问题QA
  • 总结与最佳实践

为什么需要Docker脚本

根据Docker官方2024年社区调查报告,开发者平均每天执行15-30次Docker命令,其中约40%是重复性操作。

  • docker build -t myapp:latest .
  • docker rm $(docker ps -aq)
  • docker images | grep none | awk '{print $3}' | xargs docker rmi

这些命令不仅长度相似,而且容易因拼写错误导致失败,脚本化的核心价值在于:

  1. 减少人为错误:参数自动补全,变量统一管理
  2. 保证一致性:团队协作时统一构建标准
  3. 提升速度:一条命令完成5步操作

一键构建与推送镜像

场景:每次代码变更后,需要构建镜像并推送到私有仓库,手动输入docker build -t registry.example.com/myapp:latest .docker push registry.example.com/myapp:latest,还要记得更新标签。

脚本 docker-build-push.sh

#!/bin/bash
# 使用方法:./docker-build-push.sh <镜像名> <版本号>
set -e
IMAGE_NAME=${1:-"myapp"}
VERSION=${2:-$(date +%Y%m%d-%H%M%S)}
REGISTRY="registry.example.com"
echo "🔄 构建镜像 ${IMAGE_NAME}:${VERSION}"
docker build -t ${REGISTRY}/${IMAGE_NAME}:${VERSION} .
echo "🏷️ 添加latest标签"
docker tag ${REGISTRY}/${IMAGE_NAME}:${VERSION} ${REGISTRY}/${IMAGE_NAME}:latest
echo "📤 推送镜像"
docker push ${REGISTRY}/${IMAGE_NAME}:${VERSION}
docker push ${REGISTRY}/${IMAGE_NAME}:latest
echo "✅ 完成!镜像 ${REGISTRY}/${IMAGE_NAME}:${VERSION} 已推送"

核心优化

  • set -e:任何一步失败立即停止,防止推送错误版本
  • 自动生成时间戳版本号,避免手动维护版本表
  • 同时推送latest标签,方便快速部署

批量清理无用容器与镜像

场景:开发测试环境中,每次迭代都会留下大量<none>镜像和Exited容器,手动清理费时且容易误删。

脚本 docker-cleanup.sh

#!/bin/bash
# 智能清理:保留最近3天的容器日志和镜像
echo "🗑️ 开始清理Docker残留"
# 删除所有已停止容器(保留最近3天运行过的)
echo "--- 清理停止容器 ---"
docker container prune -f --filter "until=72h"
# 删除所有悬挂镜像(dangling images)
echo "--- 清理无标签镜像 ---"
docker image prune -af --filter "until=72h"
# 删除未使用的网络
echo "--- 清理无用网络 ---"
docker network prune -f
# 删除构建缓存
echo "--- 清理构建缓存 ---"
docker builder prune -af
echo "📊 当前磁盘占用:"
docker system df

进阶用法:添加crontab -e任务,实现每周日凌晨自动执行:

0 3 * * 0 /path/to/docker-cleanup.sh >> /var/log/docker-cleanup.log 2>&1

自动化部署多容器应用

场景:一个微服务项目包含5个容器(前端、后端、数据库、Redis、Nginx),每次部署需要按顺序启动,且要处理环境变量和网络。

脚本 docker-deploy.sh

#!/bin/bash
CONFIG_FILE="docker-compose.yml"
BACKUP_DIR="./backups/$(date +%Y%m%d)"
# 1. 备份当前数据
echo "📦 备份数据库..."
mkdir -p $BACKUP_DIR
docker exec -t postgres_db pg_dumpall -U admin > $BACKUP_DIR/db_backup.sql
# 2. 拉取最新镜像
echo "🔄 拉取最新镜像..."
docker-compose -f $CONFIG_FILE pull
# 3. 优雅停止旧容器(等待10秒)
echo "⏸️ 停止旧服务..."
docker-compose -f $CONFIG_FILE down -t 10
# 4. 启动新服务
echo "🚀 启动新服务..."
docker-compose -f $CONFIG_FILE up -d
# 5. 健康检查(循环等待服务就绪)
echo "🏥 等待服务就绪..."
for i in {1..30}; do
    if curl -s http://localhost:8080/health | grep -q "ok"; then
        echo "✅ 服务正常"
        break
    fi
    sleep 2
done
# 6. 清理老数据(保留最近3次备份)
echo "🧹 清理历史备份..."
ls -t $BACKUP_DIR/.. | awk 'NR>3 {print "rm -rf backupls -t $BACKUP_DIR/../$1"}' | bash
echo "🎉 部署完成!"

安全机制

  • 自动备份数据库,支持回滚
  • 带超时的优雅停止(-t 10
  • 服务健康检查循环,避免启动漏洞

实时监控容器日志并告警

场景:生产环境中需要监控容器日志中的ERROR关键词,但不可能人工盯着终端。

脚本 docker-log-watcher.sh

#!/bin/bash
# 监控间隔(秒)
INTERVAL=5
# 告警关键词
KEYWORDS=("ERROR" "FATAL" "OutOfMemoryError")
# 需要监控的容器名(支持正则)
CONTAINERS=("web-app-*" "api-service-*")
echo "🔍 开始监控Docker容器日志..."
while true; do
    for container in $(docker ps --format '{{.Names}}' | grep -E "$(IFS='|'; echo "${CONTAINERS[*]}")"); do
        for keyword in "${KEYWORDS[@]}"; do
            # 获取最近INTERVAL秒内的日志
            if docker logs --since ${INTERVAL}s "$container" 2>/dev/null | grep -q "$keyword"; then
                echo "$(date '+%Y-%m-%d %H:%M:%S') ⚠️ 容器 $container 出现关键错误: $keyword"
                # 可选:发送企业微信/钉钉通知
                # curl -X POST -H "Content-Type: application/json" \
                #   -d "{\"msg\":\"容器 $container 出现 $keyword\"}" \
                #   https://qyapi.weixin.qq.com/cgi-bin/webhook/...
            fi
        done
    done
    sleep $INTERVAL
done

使用技巧

  • 配合Supervisorsystemd作为系统服务运行
  • 将告警集成到企业内部IM工具(如钉钉、飞书)
  • 日志级别过滤:ERROR级别以上才告警,避免噪音

Docker环境健康检查

场景:深夜接到告警,怀疑Docker daemon异常,需要快速诊断。

脚本 docker-health.sh

#!/bin/bash
echo "===== Docker环境健康检查 ====="
# 1. 检查Docker Daemon状态
echo "1️⃣  Docker服务状态"
systemctl is-active docker || echo "❌ Docker服务未运行"
# 2. 检查磁盘空间
echo "2️⃣  Docker磁盘使用"
docker system df --format "table {{.Type}}\t{{.TotalCount}}\t{{.Size}}\t{{.Reclaimable}}"
# 3. 检查容器运行状态
echo "3️⃣  容器状态统计"
RUNNING=$(docker ps -q | wc -l)
TOTAL=$(docker ps -aq | wc -l)
echo "运行中/总数: $RUNNING/$TOTAL"
# 4. 检查关键容器是否重启
echo "4️⃣  检查异常重启"
docker ps -a --format "table {{.Names}}\t{{.Status}}\t{{.RestartCount}}" | head -20
# 5. 检查网络连通性
echo "5️⃣  Docker内部网络测试"
docker run --rm --network host alpine ping -c 2 google.com > /dev/null 2>&1 && echo "✅ 网络正常" || echo "❌ 网络异常"
# 6. 检查资源限制
echo "6️⃣  检查cgroup限制"
docker info | grep -E "Memory|CPU|Disk" | head -5
echo "===== 检查完成 ====="

输出示例

===== Docker环境健康检查 =====
1️⃣  Docker服务状态
active
2️⃣  Docker磁盘使用
Images  3   2.1GB  500MB
Containers  12   4.3GB  3.1GB
3️⃣  容器状态统计
运行中/总数: 8/12
4️⃣  检查异常重启
web-app-1   Up 2 days   1
api-service   Up 2 days   0
5️⃣  Docker内部网络测试
✅ 网络正常
6️⃣  检查资源限制
Memory Limit: 4GB
CPU Limit: 2 cores
===== 检查完成 =====

常见问题QA

Q1:脚本需要sudo权限吗?
A:如果当前用户属于docker组,大部分命令无需sudo,但systemctl管理和磁盘资源查看可能需要sudo

Q2:如何将脚本设为系统命令?
A:将脚本放在/usr/local/bin/目录,并赋予执行权限:

chmod +x /path/to/script.sh
sudo cp /path/to/script.sh /usr/local/bin/docker-health

之后直接输入docker-health即可运行。

Q3:这些脚本与Docker Compose的关系?
A:互补关系,Compose负责定义和管理多容器应用,而脚本解决的是Compose未覆盖的运维场景(如集群清理、实时日志、部署回滚),建议同时使用。

Q4:脚本中使用了set -e,会不会误删重要数据?
A:安全设计原则:清理类脚本(如docker-cleanup.sh)通过--filter参数设置保护期(默认保留3天),且操作前会打印“即将执行”提示,建议先在测试环境运行一次。


总结与最佳实践

通过这5个脚本,你将实现:

  • 效率提升:一键完成构建+推送,节省70%重复操作时间
  • 运维安全:自动备份、健康检查、错误告警三位一体
  • 资源优化:定期清理释放磁盘,避免“No space left”错误

设置建议

  1. docker-cleanup.sh加入cron定时任务
  2. docker-health.sh纳入监控系统(如Prometheus)
  3. 团队共享docker-build-push.sh,统一镜像标签规范
  4. 为关键应用配置docker-log-watcher.sh的实时告警

最后提醒:脚本是工具,理解其背后的Docker命令原理更重要,建议在阅读脚本时,手动执行内部命令两次,熟悉参数含义后再自动化,希望这些脚本能成为你Docker工具箱中的得力助手。

抱歉,评论功能暂时关闭!