构建自动化 Docker 部署脚本:完整的初学者指南

发布: (2025年12月10日 GMT+8 05:53)
6 min read
原文: Dev.to

Source: Dev.to

介绍

你是否曾好奇专业开发者是如何自动将应用部署到服务器的?在本篇完整指南中,你将一步步创建一个强大的 Bash 脚本,自动化整个基于 Docker 的应用部署过程。阅读完本文后,你将拥有一个能够:

  • 克隆 Git 仓库
  • 搭建远程服务器环境
  • 构建并部署 Docker 容器
  • 将 Nginx 配置为反向代理
  • 验证部署是否成功
  • 处理清理和日志管理

最棒的是:即使你刚踏上 DevOps 之路,也能理解每一步的细节!

什么是自动化部署,为什么需要它?

在早期的 Web 开发中,部署应用意味着手动将文件复制到服务器、安装依赖并手动配置一切。这个过程:

  • 耗时 – 单次部署可能需要数小时
  • 易出错 – 很容易忘记某个步骤或配置错误
  • 不可复用 – 难以两次完全相同地部署
  • 不可扩展 – 想象一下为 10 个不同的应用重复此过程!

自动化部署通过脚本统一、可靠地执行所有部署步骤,解决了上述问题。

理解部署工作流

部署工作流

在深入代码之前,先来看一下部署期间的大致流程:

  1. 本地机器 运行部署脚本。
  2. 脚本 从 Git 克隆你的应用代码。
  3. 脚本 通过 SSH 连接到远程服务器。
  4. 脚本 在服务器上安装 Docker 和 Nginx。
  5. 脚本 构建 Docker 镜像并运行容器。
  6. 脚本 配置 Nginx 将流量路由到你的应用。
  7. 脚本 验证一切是否正常工作。

前置条件

知识要求

  • Linux 命令行基础
  • Git 版本控制
  • 对 Docker 的基本了解(我们会边走边解释)

技术需求

  • 一台 Linux/macOS 机器(或 Windows 上的 WSL)
  • 一台远程服务器(AWS EC2、DigitalOcean 等)
  • 对服务器的 SSH 密钥访问权限
  • 包含应用代码的 Git 仓库

提示:如果你对 SSH 密钥不熟悉,可以把它们想象成一种使用加密密钥而非文本密码的安全认证方式。

部署脚本的 7 个阶段

部署阶段

我们的部署脚本被划分为七个独立阶段。下面详细介绍每个阶段。

阶段 0.5 – 初始化与收尾工作

功能:设置日志、错误处理以及清理功能。

安全特性

#!/usr/bin/env bash

set -o errexit   # Exit on any error
set -o nounset   # Exit on undefined variable
set -o pipefail  # Exit if any command in a pipe fails
  • errexit:一旦任何命令失败,立即停止脚本。
  • nounset:捕获变量名拼写错误。
  • pipefail:确保管道中的错误不会被隐藏。

日志系统

TIMESTAMP="$(date +%Y%m%d_%H%M%S)"
LOGDIR="./logs"
LOGFILE="${LOGDIR}/deploy_${TIMESTAMP}.log"

log() {
  printf "%s [%s] %s\n" "$(date '+%Y-%m-%d %H:%M:%S')" "$1" "$2" | tee -a "${LOGFILE}"
}

为每次部署创建带时间戳的日志文件,便于排查问题。

清理模式

脚本提供 --cleanup 参数,可删除所有已部署的容器、镜像和配置——适用于全新开始的场景。

./deploy.sh --cleanup

注意:清理模式会删除服务器上 所有 Docker 容器和镜像。请务必先备份重要数据。

阶段 1 – 收集参数并进行基本校验

功能:通过交互式提示收集部署所需的全部信息。

收集的信息

  • Git 仓库 URL(例如 https://github.com/yourusername/your-app.git
  • 个人访问令牌 (PAT)(用于私有仓库,安全输入)
  • 分支名称(默认 main
  • SSH 细节——用户名、主机/IP、私钥路径
  • 应用端口(例如 Node.js 用 3000,其他常见用 8080

示例交互

Git repository URL: https://github.com/john/awesome-app.git
Branch name: main
Remote SSH username: ubuntu
Remote SSH host/IP: 54.123.45.67
Path to local SSH private key: ~/.ssh/deploy-key.pem
Application internal container port: 3000

输入校验示例

case "${APP_PORT}" in
  ''|*[!0-9]* ) die 12 "Invalid port";;
esac

确保端口为数字,防止后续错误。

阶段 2 – 仓库克隆与验证

功能:下载代码并验证与服务器的连通性。

工作区创建与克隆

WORKDIR="./workspace_${TIMESTAMP}"
mkdir -p "${WORKDIR}"

git clone -b "${BRANCH}" "${GIT_REPO_URL}" "${WORKDIR}/repo"

创建带时间戳的工作区目录并克隆指定分支。

私有仓库的 HTTPS 认证

# Inject PAT into the URL securely
AUTH_URL="$(echo "${GIT_REPO_URL}" | sed -E "s#https://#https://${GIT_PAT}@#")"
git clone -b "${BRANCH}" "${AUTH_URL}" "${WORKDIR}/repo"

SSH 仓库的认证

GIT_SSH_COMMAND="ssh -i ${SSH_KEY_PATH} -o StrictHostKeyChecking=no" \
  git clone -b "${BRANCH}" "${GIT_REPO_URL}" "${WORKDIR}/repo"

Docker 设置检测

if [ -f "${WORKDIR}/repo/Dockerfile" ]; then
  log "INFO" "Found Dockerfile."
elif [ -f "${WORKDIR}/repo/do
Back to Blog

相关文章

阅读更多 »

什么是 DevOps?

引言 如果在网上搜索“什么是 DevOps?”,你会找到许多复杂的定义。在本文中,我们将从基础解释 DevOps。DevOps = De...

Dockerfile:CMD 与 ENTRYPOINT

Ubuntu 镜像中的默认 CMD 官方 Ubuntu 镜像定义了一个默认命令:Dockerfile 中的 CMD '/bin/bash' 当你运行容器并提供参数时,...