本着极客的精神,一步步琢磨如何实现一键部署前端代码到远程服务器。在写这篇文章的时候,由于自己的无知,并不知道世界上还有 gitlab-ci、travis 和 jenkins 这些持续集成部署的工具存在,但是现在回想起来,自己大抵是一个活在未来的人吧。

目录速览

  1. 前言
  2. 方法介绍
  3. 福利奉献

前言

不知道在什么时候于技术文章中看到一句话:

实现了代码的一键上传及部署

啥,一键部署?大叔我每次部署新的代码,都必须要使用 FileZilla 登录测试或正式服务器,进行旧源码的删除和新源码的上传,作为一位拥有 geek 强迫症的菜鸟已经不能忍受这么不优雅或者说这么 low 的部署方式了!大叔我要革故鼎新,要开辟新的纪元(其实早就有人这么干了吧哈哈,只是自己想到然后实现出来,实在是有点小兴奋)。

公司里面组了两台 aliyun 服务器,一台测试,一台正式,两台服务器吼,多好的资源,不正是可以拿测试服务器来玩玩嘛,不能暴殄天物!所以大家别再抱怨资源少了,有时候的抱怨只是自己不够努力的借口。另外资源也不能太多,做到物尽其用最好,你试试你有N多本想读的书,一分钟换一本的话,你实际收获了多少?

以下命名规则遵循如下:

1
2
3
Linux_SERVER   # Linux 服务器(普通名词)
TEST_SERVER # 测试服务器(公司的)
NORMAL_SERVER # 正式服务器(公司的)

方法介绍

方法肯定有很多种,本人一开始有如下两个想法:

  1. 使用 sh 脚本实现:SSH 远程登录 TEST_SERVER 后进行文件/文件夹的各种操作
  2. 本地 Windows 和远程 Linux 添加 SSH 信任后,以后脚本内面登录,直接进行操作

方法1

我基本上花了 2 天的空闲时间去查找资料和实践,最后没能得手,本 PC 里还装了好多乱七八糟的东西,处女座病症要犯了…
原因是该方法需要在 Windows 上安装 expect,而 expect 的运行要依靠 tcl 包,git bash 中不具备在 Linux 上的查找及安装包的命令,我只好安装了cygwinmingw64+msys,各种恶心,还是没有装载成功,由于最后要求脚本的处理器声明为 #!/usr/bin/expect,expect这个没装好,那就玩不了啦,2 天后放弃了,然后借着强大的处女座病症各种删删删…

方法2

本地 Windows 与远程 Linux 添加 SSH 信任的原理跟本地与 Github 添加 SSH 信任的原理是一样的,一旦添加过后,本地对远程的操作便可以不再使用密码(除了第一次登陆需要以外)。如果之前有同学添加过本地与远程 Github 仓库之间的 SSH 信任的,那本地的 SSH 公钥和秘钥任然使用在 ~/.ssh/ 目录下的 id_rsa.pubid_rsa 文件。

以下为小白步骤:

  1. 打开 git bash,输入:ssh -keygen -t rsa -C "youremailname@youremail.com" 来生成公钥和秘钥,输入邮箱是无关大碍,而且 Github 远程设置时也可以引用,两个钥的文件位置为 ~/.ssh/ 目录下;
    pos of id_rsa & id_rsa.pub
  2. 使用笔记本或 editplus 打开 id_rsa.pub 文件,复制全部内容;
  3. 输入 ssh userNameOfServer@ipOfServer,例如:ssh root@114.xxx.xxx.xxx,然后提示你输入密码,输入完回车即可远程登入;
  4. 远程登入后,查看是否有授权文件,没有则新建:

    1
    2
    $ cd /root/.ssh
    $ touch authorized_keys

    然后在 authorized_keys 文件内粘贴入刚才复制到内存中公钥文件内容,保存;

  5. 登出,然后重新登录,发现就不再需要密码了。

    1
    $ exit
  6. 在项目工程目录下创建shell脚本,例如shellScript.sh,然后填入上传代码功能:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $ touch shellScript.sh
    $ vim shellScript.sh

    # --- 以下为shellScript.sh文件内容 ---
    # 打包生成好待发布的代码后,假设就是文件夹./dist
    # 做备份
    scp root@114.xxx.xxx.xxx:/<存储发布代码的根路径>/dist /<备份服务器中上线代码的根路径>/
    # 删除原上线代码文件夹
    ssh root@114.xxx.xxx.xxx "rm -rf <存储发布代码的根路径>/dist"
    # 上传发布代码
    scp /<准备上线代码的根路径>/dist root@114.xxx.xxx.xxx:/<存储发布代码的根路径>/

至此,一切大功告成,以后执行一个文本就可以进行上传发布要上线的代码了!

注意
步骤 2、3、4 可以简化为:

1
$ scp ~/.ssh/id_rsa.pub root@114.xxx.xxx.xxx:/root/.ssh/authorized_keys

然后输入密码,敲回车即可。

福利奉献

GIFT - 1

打包生成上传部署 的脚本集中为一个脚本,加上命令参数,那么自动化程度将很高,效率杠杠的!
示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/usr/bin/sh

if [[ $# != 0 && $# != 1 ]]
then
echo '参数不符,直接退出'
exit 0
fi

if [ $# == 0 ]
then
echo '================== 测试服务器 ==================='
echo 'genearate / g --打包生成代码'
echo 'deploy / d --部署到指定服务器'
echo 'auto --打包生成代码 并 部署到指定服务器'
echo ''
echo '================== 正式服务器 ==================='
echo 'testN / tN --测试备份代码'
echo 'genearateN / gN --打包生成代码'
echo 'deployN / dN --部署到指定服务器'
echo 'autoN --打包生成代码 并 部署到指定服务器'
echo ''
echo 'Please input the taskName which u want to excute:'
read arg
fi

GIFT - 2

在使用脚本实现自动化部署的同时还可以注意备份一下旧的发布代码,按日期进行备份,shell脚本操作获取本地时间的代码如下:
转换为十进制的原因是,本人的 git bash 获取到的时间总是+0000时区的,并不是+0800东八区(China)的,挣扎无果,只好手动 +8。

1
2
3
4
5
6
7
8
9
10
11
#!/usr/bin/sh

# DATE=$(date +%Y%m%d%H%M%S)
HOUR_TEMP=$(date +%H)
HOUR=$((10#${HOUR_TEMP}+8))
if [ $HOUR -lt 10 ]
then
HOUR="0"+"$HOUR_TEMP"
fi
DATE="$(date +%Y%m%d)""$HOUR""$(date +%M%S)"
echo $DATE