Docker 自动化脚本实战:让部署变得简单高效

举报
yd_276803270 发表于 2026/10/22 20:24:09 2026/10/22
【摘要】 ## 一、前言在日常开发和运维工作中,手动执行 Docker 命令不仅繁琐,而且容易出错。通过编写自动化脚本,我们可以将构建、部署、备份等流程标准化,大幅提升工作效率。本文将分享一套实用的 Docker 自动化脚本方案,帮助你快速搭建自己的容器化部署流水线。---## 二、为什么需要 Docker 自动化脚本?| 手动操作痛点       | 自动化脚本优势     ||----------...
## 一、前言

在日常开发和运维工作中,手动执行 Docker 命令不仅繁琐,而且容易出错。通过编写自动化脚本,我们可以将构建、部署、备份等流程标准化,大幅提升工作效率。本文将分享一套实用的 Docker 自动化脚本方案,帮助你快速搭建自己的容器化部署流水线。

---

## 二、为什么需要 Docker 自动化脚本?

| 手动操作痛点       | 自动化脚本优势     |
|--------------------|--------------------|
| 命令冗长易遗忘     | 一键执行,降低门槛 |
| 人为失误风险高     | 流程固定,可重复   |
| 多环境配置混乱     | 环境变量统一管理   |
| 难以追溯操作历史   | 脚本即文档,可版本化 |

---

## 三、核心脚本设计

### 3.1 项目目录结构

```
my-docker-app/
├── docker-compose.yml
├── .env
├── scripts/
│   ├── deploy.sh        # 部署脚本
│   ├── backup.sh       # 备份脚本
│   ├── rollback.sh     # 回滚脚本
│   └── health-check.sh # 健康检查脚本
├── Dockerfile
└── README.md
```

### 3.2 环境变量配置文件 `.env`

```bash
# 项目基础配置
PROJECT_NAME=myapp
IMAGE_REGISTRY=registry.cn-north-1.myhuaweicloud.com
IMAGE_TAG=latest

# 容器运行配置
CONTAINER_PORT=8080
HOST_PORT=80
RESTART_POLICY=always

# 备份配置
BACKUP_DIR=/data/backups
BACKUP_RETAIN_DAYS=7

# 日志配置
LOG_LEVEL=info
LOG_MAX_SIZE=10m
LOG_MAX_FILE=3
```

### 3.3 核心部署脚本 `deploy.sh`

```bash
#!/bin/bash
set -euo pipefail

# ============================================
# Docker 自动化部署脚本
# 功能:构建镜像 → 推送仓库 → 拉取部署 → 健康检查
# ============================================

# 加载环境变量
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
ENV_FILE="$PROJECT_ROOT/.env"

if [[ ! -f "$ENV_FILE" ]]; then
    echo "❌ 错误:未找到 .env 配置文件:$ENV_FILE"
    exit 1
fi

source "$ENV_FILE"

# 日志函数
log_info()  { echo -e "\033[32m[INFO]\033[0m  $(date '+%Y-%m-%d %H:%M:%S') $1"; }
log_warn()  { echo -e "\033[33m[WARN]\033[0m  $(date '+%Y-%m-%d %H:%M:%S') $1"; }
log_error() { echo -e "\033[31m[ERROR]\033[0m $(date '+%Y-%m-%d %H:%M:%S') $1"; }

# 错误捕获
trap 'log_error "部署过程中发生错误,行号: $LINENO"' ERR

# 帮助信息
show_help() {
    cat << EOF
用法: $0 [命令]
命令:
  build      构建 Docker 镜像
  push      # 🤖 告别重复劳动:Docker 脚本与自动化运维实战指南

> 发布日期:2026-10-22
> 标签:Docker、自动化运维、Shell脚本、Python SDK、CI/CD

---

## 前言

在之前的文章中,我们探讨了 Docker 在算法实验和分布式模拟中的妙用。然而,在日常开发和运维中,我们经常会陷入重复劳动的泥潭:清理堆积如山的悬空镜像、手动构建并推送到仓库、在多台机器上重复部署……

“懒惰”是程序员的美德。今天,我们将探讨如何通过 **Shell 脚本、Makefile 和 Python SDK** 将 Docker 操作自动化,打造丝滑的开发与部署体验。

---

## 一、Shell 脚本:日常清理与一键发布

Shell 脚本是最直接、最高效的 Docker 自动化工具。让我们编写一个实用的日常维护脚本。

### 1. 智能清理脚本 (`docker_cleanup.sh`)

开发机上常常堆满了停止的容器和 `<none>` 标签的镜像。手动清理容易误删,写个脚本来搞定:

```bash
#!/bin/bash

# 开启严格模式,遇到错误即退出
set -euo pipefail

echo "🧹 开始清理 Docker 无用资源..."

# 1. 删除所有已停止的容器
STOPPED_CONTAINERS=$(docker ps -aq --filter status=exited)
if [[ -n "$STOPPED_CONTAINERS" ]]; then
    echo "发现停止的容器,正在删除..."
    docker rm $STOPPED_CONTAINERS
else
    echo "✅ 没有停止的容器。"
fi

# 2. 删除悬空镜像 (<none> 标签)
echo "清理悬空镜像..."
docker image prune -f

# 3. 删除未使用的网络和卷 (谨慎操作)
echo "清理未使用的网络..."
docker network prune -f

echo "🎉 Docker 清理完成!"
docker system df # 显示当前磁盘使用情况
```

### 2. 一键构建与推送脚本 (`docker_release.sh`)

在版本发布时,我们需要同时打上 `latest` 和具体版本号的标签,并推送到远程仓库。

```bash
#!/bin/bash
set -euo pipefail

# 配置变量
IMAGE_NAME="my-app"
REGISTRY="registry.example.com"
VERSION=$(date +%Y%m%d%H%M%S) # 以时间戳作为版本号

echo "🚀 开始构建 ${IMAGE_NAME}:${VERSION}..."

# 多架构构建并推送 (需要 buildx)
docker buildx build \
  --platform linux/amd64,linux/arm64 \
  -t ${REGISTRY}/${IMAGE_NAME}:${VERSION} \
  -t ${REGISTRY}/${IMAGE_NAME}:latest \
  --push \
  .

echo "✅ 构建并推送成功!"
echo "镜像地址: ${REGISTRY}/${IMAGE_NAME}:${VERSION}"
```

---

## 二、Makefile:统一团队工作流

当项目变大时,团队成员可能记住不各种冗长的 Docker 命令。`Makefile` 是完美的统一入口。

在项目根目录创建 `Makefile`:

```makefile
# 变量定义
IMAGE_NAME := my-web-app
PORT := 8080

# 默认目标
.PHONY: help
help:
@echo "可用命令:"
@echo "  make build    - 构建 Docker 镜像"
@echo "  make run      - 在本地运行容器"
@echo "  make stop     - 停止并删除容器"
@echo "  make logs     - 查看实时日志"

# 构建镜像
.PHONY: build
build:
docker build -t $(IMAGE_NAME) .

# 运行容器
.PHONY: run
run:
docker run -d --name $(IMAGE_NAME) -p $(PORT):80 $(IMAGE_NAME)

# 停止并清理
.PHONY: stop
stop:
-docker stop $(IMAGE_NAME)
-docker rm $(IMAGE_NAME)

# 查看日志
.PHONY: logs
logs:
docker logs -f $(IMAGE_NAME)
```

**威力所在**:现在,团队成员只需输入 `make build` 或 `make run`,无需关心底层细节,团队协作效率大幅提升。

---

## 三、Python SDK:实现高级自动化逻辑

当需要复杂的逻辑判断(如监控容器状态、根据 CPU 自动扩缩容)时,Shell 脚本显得力不从心。此时,Docker 的 Python SDK 是更好的选择。

首先安装 SDK:`pip install docker`

### 场景:自动健康检查与重启

```python
import docker
import time
import logging

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

client = docker.from_env()

def monitor_and_restart(container_name):
    try:
        container = client.containers.get(container_name)
    except docker.errors.NotFound:
        logging.error(f"容器 {container_name} 不存在,尝试启动...")
        client.containers.run("nginx:latest", name=container_name, detach=True, ports={'80/tcp': 8080})
        return

    # 获取容器状态
    container.reload()
    status = container.status
    logging.info(f"容器 {container_name} 当前状态: {status}")

    if status != 'running':
        logging.warning(f"容器异常停止,正在尝试重启...")
        container.start()
        logging.info("重启成功!")
    else:
        # 检查健康状态 (如果配置了 healthcheck)
        health = container.attrs.get('State', {}).get('Health', {}).get('Status')
        if health == 'unhealthy':
            logging.warning(f"容器健康检查失败,正在重启...")
            container.restart()
            logging.info("重启成功!")

if __name__ == '__main__':
    TARGET_CONTAINER = "my-nginx"
    logging.info("开始自动监控任务...")
    
    while True:
        monitor_and_restart(TARGET_CONTAINER)
        time.sleep(30) # 每 30 秒检查一次
```

通过这种方式,你可以轻松实现一个轻量级的“迷你看门狗”,无需引入庞重的 Kubernetes。

---

## 四、CI/CD 集成:Git Push 即部署

将脚本融入 CI/CD 流水线,是自动化的终极形态。以下是一个 GitHub Actions 的示例,当主分支有代码推送时,自动构建并部署。

在项目下创建 `.github/workflows/docker-deploy.yml`:

```yaml
name: Docker CI/CD

on:
  push:
    branches: [ "main" ]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Code
        uses: actions/checkout@v3

      - name: Log in to Docker Hub
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKER_HUB_USER }}
          password: ${{ secrets.DOCKER_HUB_TOKEN }}

      - name: Build and push
        uses: docker/build-push-action@v4
        with:
          context: .
          push: true
          tags: myrepo/myapp:latest,myrepo/myapp:${{ github.sha }}

      - name: Deploy to Server
        uses: appleboy/ssh-action@v0.1.10
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SSH_KEY }}
          script: |
            docker pull myrepo/myapp:latest
            docker stop my-app || true
            docker rm my-app || true
            docker run -d --name my-app -p 80:80 myrepo/myapp:latest
```

**解析**:这段配置实现了:拉取代码 -> 登录镜像仓库 -> 构建并打上 commit hash 标签 -> 推送 -> SSH 连接到生产服务器 -> 拉取最新镜像并重启容器。全程无人值守。

---

## 总结

从手动敲击命令行,到编写 Shell 脚本,再到 Makefile 统一入口,最后通过 Python SDK 和 CI/CD 实现全自动流水线,这是每个工程师走向高效的必经之路。

回顾本文的自动化武器库:
1. **Shell 脚本**:处理清理、构建等线性任务,简单高效。
2. **Makefile**:封装复杂命令,统一团队开发体验。
3. **Python SDK**:处理需要条件判断、循环监控的复杂逻辑。
4. **CI/CD**:将自动化推向极致,实现代码即部署。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。