随着软件开发周期的不断加快,特别是前端项目和 Web 应用的快速迭代,手动执行部署过程已经不再适应现代化开发的需求。特别是在一些公司尚未完全实现 Jenkins、Kubernetes 等自动化部署工具的背景下,开发人员依然面临频繁的手动打包、上传文件到服务器以及远程执行部署命令等重复工作,这不仅降低了工作效率,还容易引入人为错误。
为了有效解决这些问题,本文将介绍如何通过一段 Bash 脚本实现自动化部署,简化打包、上传以及部署过程,提高工作效率,并降低人为错误的发生概率。
为什么需要自动化部署?
手动部署往往需要以下几个步骤:
- 本地打包:开发人员需要执行构建命令,如 npm run build,并生成部署文件。
- 文件压缩:将生成的文件打包为一个压缩文件,以便传输和上传。
- 上传到服务器:手动通过 scp 或 rsync 上传文件到服务器。
- 远程执行部署命令:登录到服务器,通过 SSH 执行部署脚本,将上传的文件解压并更新服务。
每个步骤都涉及手动操作,容易出错,也会造成时间浪费。尤其是当项目规模变大,部署频率增加时,手动操作的痛点尤为突出。
自动化部署不仅能节省时间,还能确保部署过程一致性,提高整个团队的工作效率和可靠性。
如何实现自动化部署脚本?
我们将创建一个完整的自动化部署流程,确保每个步骤都能无缝连接、自动化执行,并且处理可能的错误。
对于用脚本实现自动化部署,首选免密登陆,这样更较安全一些。本文中对这种方式不过多赘述,下面我们将用传统的账号密码登陆来实现自动化部署。
本人在macOS系统做了测试,windows系统的小伙伴在下文中提到的工具请自行安装。
1. 环境准备
在自动化部署脚本中,首先需要确保开发环境准备好:
- 安装必要的工具:例如 sshpass,它能让我们在没有交互的情况下,使用用户名和密码进行 SSH 登录。
bash
brew install sshpass
- 检查网络连通性:确保服务器可达,避免因网络问题造成部署失败。
- 验证服务器的 SSH 登录:确保 SSH 连接无误,不必每次都手动验证主机密钥。
2. 构建项目
在现代化的前端开发中,通常会用 npm 或 yarn 来构建项目。在脚本中,我们通过以下命令触发构建过程:
bash
npm run build
这一步确保了最新的代码被打包成可以部署的版本。自动化部署的第一步是确保构建无误,并且生成了最新的 dist 文件。
3. 文件压缩
在大多数部署过程中,通常需要将构建出来的文件压缩成 .zip 文件,以便于上传和传输。通过以下命令实现压缩:
bash
zip -r $remote_zip_file dist
压缩文件使得传输过程更加高效,也能在上传过程中减少文件损坏的风险。
4. 文件上传到服务器
一旦文件压缩完成,下一步是将压缩文件上传到服务器。为了避免手动输入密码,我们使用 sshpass 来实现自动化上传:
bash
sshpass -p "$server_password" scp -o HostKeyAlgorithms=+ssh-rsa -P $server_port $remote_zip_file $server_user@$server_ip:$server_folder
通过 scp 命令,我们将压缩文件上传到目标服务器的指定目录。此时,远程服务器必须已配置好 SSH 服务,并且确保正确设置了 HostKeyAlgorithms,避免出现密钥算法不匹配的问题。
需要注意的是,上述脚本可能会执行异常, 因为若是首次连接未信任的服务器。我们在这里可以用终端执行ssh -o HostKeyAlgorithms=+ssh-rsa -p $server_port $server_user@$server_ip
脚本,输入密码登陆,把这台服务器加入到我们本地的.ssh文件夹中,这一点很重要。
5. 远程执行部署脚本
上传完成后,下一步是远程执行部署命令。例如,在部署前解压文件并执行部署脚本。为了避免手动登录到服务器,我们可以在脚本中直接通过 SSH 执行远程命令:
bash
sshpass -p "$server_password" ssh -o HostKeyAlgorithms=+ssh-rsa -p $server_port $server_user@$server_ip << EOF
echo "当前目录: $(pwd)"
echo "检查 page.sh 是否存在..."
if [ -f "$server_script_folder/page.sh" ]; then
echo "page.sh 文件存在,正在执行部署脚本..."
cd $server_script_folder
bash page.sh
else
echo "page.sh 文件不存在,请检查脚本路径!"
exit 1
fi
EOF
在远程服务器上,我们首先确保 page.sh 部署脚本存在,然后执行部署操作。如果脚本文件不存在,脚本会提前报错并退出,避免后续步骤执行无效。
此处的page.sh
只是我服务器上的部署脚本,大家可根据自身的项目自行修改脚本。
6. 清理临时文件
一旦文件成功上传并部署完毕,我们通常需要清理本地生成的压缩文件,避免占用不必要的磁盘空间:
bash
rm -rf $remote_zip_file
全部脚本
bash
#!/usr/bin/env bash
# 配置项
server_user="your server account"
server_ip="your server ip"
server_password="your server password"
server_port="your server port"
server_folder="your server upload folder"
# 可能不需要
server_script_folder="your script folder"
remote_zip_file="dist.zip"
# 检查 sshpass 是否安装
if ! command -v sshpass &> /dev/null; then
echo "sshpass 未安装,请先安装 sshpass!"
exit 1
fi
# 测试网络连通性
echo "正在测试网络连通性..."
if ! ping -c 4 $server_ip &> /dev/null; then
echo "无法连接到服务器 $server_ip,请检查网络!"
exit 1
fi
echo "网络连通性正常。"
# 测试 SSH 登录
echo "正在测试 SSH 登录..."
if ! sshpass -p "$server_password" ssh -o HostKeyAlgorithms=+ssh-rsa -p $server_port $server_user@$server_ip exit &> /dev/null; then
echo "无法通过 SSH 登录到服务器 $server_ip,请检查账号或密码!"
exit 1
fi
echo "SSH 登录测试成功。"
# 构建项目
echo "正在构建项目..."
npm run build
if [ $? -ne 0 ]; then
echo "构建失败,脚本终止!"
exit 1
fi
echo "构建完成。"
# 压缩文件
echo "正在压缩 dist 文件夹..."
zip -r $remote_zip_file dist
if [ $? -ne 0 ]; then
echo "压缩失败,脚本终止!"
exit 1
fi
echo "压缩完成。"
# 上传文件
echo "正在上传文件到服务器 $server_ip..."
sshpass -p "$server_password" scp -o HostKeyAlgorithms=+ssh-rsa -P $server_port $remote_zip_file $server_user@$server_ip:$server_folder
if [ $? -ne 0 ]; then
echo "文件上传失败,请检查网络或服务器配置!"
exit 1
fi
echo "文件上传完成。"
# 远程部署
# 远程部署脚本根据自己的项目需要自行修改
echo "正在执行远程部署命令..."
sshpass -p "$server_password" ssh -o HostKeyAlgorithms=+ssh-rsa -p $server_port $server_user@$server_ip << EOF
echo "当前目录: $(pwd)"
echo "检查 page.sh 是否存在..."
if [ -f "$server_script_folder/page.sh" ]; then
echo "page.sh 文件存在,正在执行部署脚本..."
cd $server_script_folder
bash page.sh
else
echo "page.sh 文件不存在,请检查脚本路径!"
exit 1
fi
EOF
if [ $? -ne 0 ]; then
echo "远程部署失败,请检查服务器配置!"
exit 1
fi
echo "远程部署完成。"
# 清理本地压缩文件
echo "正在清理本地临时文件..."
rm -rf $remote_zip_file
if [ $? -ne 0 ]; then
echo "清理失败,请手动删除 $remote_zip_file!"
exit 1
fi
echo "清理完成,部署流程结束!"
脚本的优化与增强
为了让自动化部署脚本更加可靠和高效,我们可以考虑以下几个方面的优化:
- 并行化构建和部署:在构建完成后,我们可以将构建、压缩、上传和部署这几个过程并行化,提高效率。例如,可以使用 & 将某些命令放到后台执行,从而减少等待时间。
- 增加错误处理和重试机制:在部署过程中,网络问题或服务器配置问题可能会导致上传失败。可以增加重试机制,确保在失败时自动重试:
bash
retries=3
attempt=0
until sshpass -p "$server_password" scp -o HostKeyAlgorithms=+ssh-rsa -P $server_port $remote_zip_file $server_user@$server_ip:$server_folder; do
((attempt++))
if [ $attempt -ge $retries ]; then
echo "文件上传失败,重试次数已达上限!"
exit 1
fi
echo "上传失败,正在重试 ($attempt/$retries)..."
sleep 5
done
- 动态配置和环境变量
对于生产环境和测试环境,可能需要不同的配置。可以通过配置文件或环境变量来动态切换不同的服务器配置,例如:
bash
server_ip=${DEPLOY_SERVER_IP}
server_password=${DEPLOY_SERVER_PASSWORD}
通过这种方式,避免将敏感信息硬编码到脚本中。
总结
在一些尚未完成 CI/CD 自动化部署的公司环境中,通过自定义 Bash 脚本实现打包、上传、部署的自动化流程是一种非常实用的解决方案。这不仅能够节省大量时间,提高工作效率,还能有效减少人为错误。通过上述脚本,我们完成了构建、压缩、上传、远程执行部署脚本以及清理文件等步骤,帮助开发人员轻松实现自动化部署。
随着团队规模和项目复杂度的增加,逐步过渡到更专业的 CI/CD 工具(如 Jenkins、GitLab CI、Kubernetes 等)将是更高效、更可扩展的长期解决方案。但在实际开发过程中,自动化部署脚本依然是一个极具价值的工具,尤其是对于小型团队或快速开发迭代的场景。