【项目部署】Githooks结合shell脚本实现自动化部署

问题背景

截至目前做了3个和部署相关的项目了。其中有1个是先连接远程桌面,再进行部署的(因为会有内网权限问题);另外2个是直接本地部署到服务器的。

对于直接本地部署到服务器的项目,需要手动执行以下操作:

  1. 登录到服务器
  2. 停止服务器上正在运行的进程
  3. 删除服务器上旧的部署文件(这里是为了保证上传新的部署文件是不会出现问题)
  4. 回到本地
  5. 打包本地项目,生成新的部署文件(比如压缩文件夹或者是构建jar包)
  6. 新的部署文件上传至服务器
  7. 再次登录到服务器
  8. 根据新的部署文件启动服务

可以看到,还是比较繁琐的,也比较机械。由于项目没有写测试,部署后经常会出现一些问题,所以就需要本地修改再进行部署,这样就会反复执行上述所有操作,比较麻烦。而且如果写的是前端项目,可能会在短期内频繁出现改个字号、调个颜色类似这种很小的改动,那重复执行这些枯燥的操作就更会让人觉得无聊了。

资料调研

程序员嘛,总是想着怎么方便怎么弄。那为了省事,我希望以上部署的流程能够在我修改完代码后自动进行,即自动化部署。我查阅了一些资料,主要有两种方案:

  1. 通过jenkins实现自动化部署
  2. 通过脚本实现自动化部署

其中第一种查到的资料比较多,应该算比较主流。但是了解后发现比较麻烦,配置比较复杂、学习成本相对较高,而且我也不需要那么多功能。所以我就采用了第二种方案。

那脚本实现的前提是:这些操作都能用代码实现。很幸运的是,确实都可以:

  1. 登录到服务器:ssh连接服务器
  2. 停止服务器上正在运行的进程:Linux的kill命令
  3. 删除服务器上旧的部署文件:Linux的rm命令
  4. 回到本地:exit退出ssh会话
  5. 打包本地项目,生成新的部署文件zip或者mvn package
  6. 新的部署文件上传至服务器:scp命令
  7. 再次登录到服务器:ssh连接服务器
  8. 根据新的部署文件启动服务:项目的启动命令

总之,每一步都可以通过一行命令实现。

自动化部署脚本

这里我先贴上代码:

#!/bin/bash

# -------------------------------------------------
### 服务器信息
ip="xxx.xxx.xxx.xxx"
username="xxx"
project_path="xxx"

### 脚本
start_process_script="xxx.sh"  # 启动服务的脚本
kill_process_script="xxx.sh"  # 关闭服务的脚本

### 部署文件
jar_file="xxx"

### 本地打包后上传到服务器的文件
uploaded_files="xxx"  

### 本地电脑私钥路径
private_key_path="xxx"



# -------------------------------------------------
### ssh连接到服务器
### 1. 切换到指定目录
### 2. 运行脚本停止jar包进程
ssh -i ${private_key_path} ${username}@${ip} << EOF
  echo "成功连接到服务器."

  cd ${project_path}  # 切换到项目的目录
  bash ${kill_process_script}  # 执行杀死进程的脚本
  
  # 删除旧的部署文件
  if [ -f "${jar_file}" ]; then
    rm -rf ${jar_file} 
  fi
  
  # 断开服务器连接
  exit
  echo "连接已断开."
EOF



# -------------------------------------------------
### 本地打包jar包
mvn clean package
echo "打包完成."

### 将打包的文件上传到服务器
scp -i ${private_key_path} ${uploaded_files} ${username}@${ip}:${project_path}
echo "文件上传成功."


# -------------------------------------------------
### ssh连接到服务器
### 1. 切换到指定目录
### 2. 启动新的jar包进程
ssh -i ${private_key_path} ${username}@${ip} << EOF
  echo "成功连接到服务器."

  cd ${project_path}  # 切换到项目目录
  bash ${start_process_script}  # 通过脚本启动进程
  
  # 断开服务器连接
  exit
  echo "连接已断开."
EOF

echo "自动化部署完成."

这段代码复制改一改应该就能直接用。这里有几个特别说明的部分:

  1. ssh命令后面要写<< EOF,最后要写EOF,这样才能让这段代码在服务器端执行,而不是在本地执行
  2. 为了避免每次ssh都要输入密码,这里把本机的公钥上传到服务器了,同时在使用sshscp命令时指定了私钥路径
  3. 这个脚本比较繁琐,主要是涉及到了3次ssh会话连接:第一次ssh、第二次scp(底层是ssh)、第三次ssh。暂时先没有进行优化,毕竟功能优先

接下来要解决的需求是:如何在我本地修改完代码后自动执行这个脚本?

由于我用了Git管理项目,之前又看到过别人有这样的操作:执行git push之后服务器就自动进行了更新。所以问了一下ChatGPT这是什么操作,最后了解到Githooks可以实现这个功能。

Githooks是什么?

先来看一段介绍(来自:https://githooks.com/):


What are Git Hooks?
Git Hooks are scripts that Git can execute automatically when certain events occur, such as before or after a commit, push, or merge. There are several types of Git Hooks, each with a specific purpose. Pre-commit hooks, for example, can be used to enforce code formatting or run tests before a commit is made. Pre-push hooks can be used to prevent pushes to certain branches or run additional tests before pushing. Post-merge hooks can be used to perform actions after a merge is completed, such as updating dependencies or generating documentation.

These hook scripts are only limited by a developer’s imagination. Some example hook scripts include:

  • pre-commit: Check the commit message for spelling errors.
  • pre-receive: Enforce project coding standards.
  • post-commit: Email/SMS team members of a new commit.
  • post-receive: Push the code to production.

简单来说,就是一些能够在某些特定Git操作发生之前或者之后自动执行的脚本。那这正好满足我的需求。于是我就把脚本写在了post-commit文件里。这样每次git commit后,部署流程就会自动化进行。

Githooks配置

Githooks的所有脚本默认是在项目根目录下的.git/hooks路径里的。可以通过命令git config core.hooksPath <特定路径>修改路径。

总结

本文实现的方案是基于Git的,即项目要先用Git管理起来,然后编写Githooks脚本实现自动化部署。实现完了之后,体验还是非常棒的。每次git commit后都自动部署到服务器,也不需要输入密码。

这次实现所学到的知识点也总结在这里:

  • Githooks钩子脚本
  • shell脚本的一些语法
  • ssh免密登录

你可能感兴趣的:(项目部署,自动化,linux,服务器)