通过GitHub actions发布hugo到私有云服务器

继上次分享的GitHub actions 发布到GitHub pages,收到的反馈还不错,咱们这次也记录了下编写脚本的过程,过程比较坎坷,如果只要结果,请看文章最后几个板块的内容。

准备工作

SSH key 生成

1
2
3
4
ssh-keygen -t rsa -b 4096 -C "$(git config user.email)" -f gh-pages -N ""
# You will get 2 files:
#   gh-pages.pub (public key)
#   gh-pages     (private key)

配置私钥

如果前面读过我的hugo通过Github Action部署到Github Pages文章,那么一定知道怎么去上传公钥,这里我们再重复一下

假设 开发项目为 tianhui.xin
打开tianhui.xin仓库的settings,再点击Secrets,然后添加咱们刚刚生成的私钥,name为ACTIONS_DEPLOY_KEY

Add your private keySuccess

上传公钥服务器

1
2
3
4
5
6
ssh-copy-id appuser@10.10.10.10
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/appuser/.ssh/id_rsa.pub"
The authenticity of host '10.10.10.10 (10.10.10.10)' can't be established.
ECDSA key fingerprint is SHA256:mpM5LP8zLMh/CibV34URdTFbciAJ3fvCG1f9kSD2ITI.
ECDSA key fingerprint is MD5:60:40:77:02:5b:c6:e0:9a:e7:a3:96:bf:10:da:12:1c.
Are you sure you want to continue connecting (yes/no)? yes

输入远程用户的密码后,SSH公钥就会自动上传了.SSH公钥保存在远程Linux服务器的.ssh/authorized_keys文件中

思考

docker镜像每次都是一个新的,SSH在第一次连接都会询问这个一个问题

1
2
3
4
5
6
7
The authenticity of host '10.10.10.10 (10.10.10.10)' can't be established.

RSA key fingerprint is 97:8c:1b:f2:6f:14:6b:5c:3b:ec:aa:46:46:74:7c:40.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '10.10.10.10 (10.10.10.10)' (RSA) to the list of
known hosts.
Enter passphrase for key '/home/appuser/.ssh/id_rsa':

其原因是因为/home/appuser/.ssh目录下的known_hosts不存在对你正要连接的服务器信息,也就是说你是第一次连接;那么我们是不是可以伪造一个呢,喏,你还别说,我还真去把自己电脑上的known_hosts的对应记录复制了一份上去,我简直是个天才,但结果不尽人意,好吧,咱们继续折腾。

幸运的是我在梯子的帮助下,找到了这样一个命令ssh-keyscan,搞起🤕

1
ssh-keyscan -t rsa 10.10.10.10 >> "/home/appuser/known_hosts"

新建job脚本(测试SSH脚本)

主要过程就是测试下在docker环境下如何远程SSH

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
name: aliyun

on:
  push:
    branches:
      - master
jobs:
  build:

    runs-on: ubuntu-latest

    steps:
      - name: checkout
        uses: actions/checkout@master
        with:
          submodules: true
      - name: Setup Hugo
        uses: peaceiris/actions-hugo@v2.2.2
        with:
          hugo-version: '0.59.1'
          extended: true
      - name: Build
        run: hugo --minify
      - name: Deploy
        env:
          ACTIONS_DEPLOY_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }}
          HOST: 10.10.10.10
          USER: appuser
        run: |
          SSH_PATH="$HOME/.ssh"
          mkdir -p $SSH_PATH
          touch "$SSH_PATH/known_hosts"
          echo "$ACTIONS_DEPLOY_KEY" > "$SSH_PATH/id_rsa"
          chmod 700 "$SSH_PATH"
          chmod 600 "$SSH_PATH/known_hosts"
          chmod 600 "$SSH_PATH/id_rsa"
          eval $(ssh-agent)
          ssh-add "$SSH_PATH/id_rsa"
          ssh-keyscan -t rsa $HOST >> "$SSH_PATH/known_hosts"
          ssh -o StrictHostKeyChecking=no -i $SSH_PATH/id_rsa -A -tt $USER@$HOST ls          

执行push,等待CI部署完成,查看log发现已经打印出了服务器的文件文件夹信息,😄

测试结果

最终的job脚本

配置说明

使用只需要关注deploy中的env配置

configdescription
ACTIONS_DEPLOY_KEY连接服务的私钥(在GitHub项目下的setting>Secrets配置)
HOST服务器的IP地址
USER服务器的部署用户,对应的私钥的用户
HOME_PATH登陆服务器后,我们去哪个目录,一般设置为用户目录
DEVELOP_SH_PATH服务器部署脚本(咱们的部署目录还是服务器上执行,不写在job中)
PACKAGE_NAME打包的名称(public.tar.gz),目前只支持这个
DEVELOP_DIR项目部署文件夹
BACKUP_DIR项目的备份文件夹

job文件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
name: aliyun

on:
  push:
    branches:
      - master
jobs:
  build:

    runs-on: ubuntu-latest
    steps:
      - name: checkout
        uses: actions/checkout@master
        with:
          submodules: true
      - name: setup Hugo
        uses: peaceiris/actions-hugo@v2.2.2
        with:
          hugo-version: '0.59.1'
          extended: true
      - name: Build
        run: hugo --minify
      - name: deploy
        env:
          ACTIONS_DEPLOY_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }}
          HOST: 10.10.10.10
          USER: appuser
          HOME_PATH: /home/appuser
          DEVELOP_SH_PATH: /home/appuser/develop.sh
          PACKAGE_NAME: public.tar.gz
          DEVELOP_DIR: tianhui.xin
          BACKUP_DIR: backup
        run: |
          SSH_PATH="$HOME/.ssh"
          mkdir -p $SSH_PATH
          touch "$SSH_PATH/known_hosts"
          echo "$ACTIONS_DEPLOY_KEY" > "$SSH_PATH/id_rsa"
          chmod 700 "$SSH_PATH"
          chmod 600 "$SSH_PATH/known_hosts"
          chmod 600 "$SSH_PATH/id_rsa"
          eval $(ssh-agent)
          ssh-add "$SSH_PATH/id_rsa"
          ssh-keyscan -t rsa $HOST >> "$SSH_PATH/known_hosts"
          cd public
          tar -cf $PACKAGE_NAME *
          scp $PACKAGE_NAME $USER@$HOST:$HOME_PATH
          ssh -o StrictHostKeyChecking=no -i $SSH_PATH/id_rsa -A -tt $USER@$HOST sh $DEVELOP_SH_PATH \
            -d $HOME_PATH/$DEVELOP_DIR -b $HOME_PATH/$BACKUP_DIR -f $HOME_PATH/$PACKAGE_NAME
          exit          

远程服务器操作

新建develop.sh

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#!/bin/sh
set -e

FILE_NAME=`basename $0`

#说明
show_usage="usage:$FILE_NAME [-d develop_path,-b backup_path -f file_path]"

#参数
# 本地仓库目录
opt_develop_path=""

# 备份目录
opt_backup_path=""

# 部署文件
opt_file_path=""


GETOPT_ARGS=`getopt -o d:b:f: -al develop_path:,backup_path:,file_path: -- "$@"`
eval set -- "$GETOPT_ARGS"
#获取参数
while [ -n "$1" ]
do
        case "$1" in
                -d|--develop_path) opt_develop_path=$2; shift 2;;
                -b|--backup_path) opt_backup_path=$2; shift 2;;
				-f|--opt_file_path) opt_file_path=$2; shift 2;;
                --) break ;;
                *) echo $1,$2,$show_usage; break ;;
        esac
done

# 判断参数
if [[ -z $opt_develop_path || -z $opt_backup_path || -z $opt_file_path ]]; then
        echo -e $show_usage
        exit 0
fi

if [ "$opt_develop_path" = "$opt_backup_path" ]; then
  echo 'develop_path eq backup_path'
  exit 0
fi

# 判断部署文件是否存在
if [ ! -f $opt_file_path ]; then
	echo "$opt_file_path file does not exist"
	exit 0
fi

# 判断文件夹是否存在
if [ ! -x $opt_develop_path ]; then
  mkdir $opt_develop_path
fi

# 判断文件夹是否存在
if [ ! -x $opt_backup_path ]; then
  mkdir $opt_backup_path
fi

# 文件夹不是空的
if [ ! "`ls -A $opt_develop_path`" = "" ]; then
  cd $opt_develop_path
  tar -cf $opt_backup_path/$(date +%Y%m%d%H%M).tar.gz $opt_develop_path/*
  rm -rf $opt_develop_path/*
fi
# 解压文件
tar -xf $opt_file_path -C $opt_develop_path

echo "publish success!"

给予执行权限

1
chomd u+x develop.sh

执行结果

一切准备就绪,开始你的奇妙之旅吧,码字不易,有问题请留言交流。

相关文章:

  1. hugo通过Github Action部署到Github Pages