# Vuepress 部署到阿里云 ## 需求 最近计划把自己所学的的知识整理一遍,以加深影响和方便以后工作中查询,本来打算用 express + vue + mysql 自己开发个博客系统,但一方面没有太多的时间来折腾,另一方面又想省事点(其实就是懒,哈哈...)。 刚好最近 Vuepress 又发布了 1.x 版本,就花了点时间过了一遍[官方文档](https://v1.vuepress.vuejs.org/zh/),发现比较符合我的需求,但在文档中关于 Vuepress 部署的说明个人感觉说的不是很全面,大多都是部署到 github/gitlab 第三方平台的说明,但我又想部署到自己的阿里云的服务器上(花钱买了不用太可惜了),在网上搜索了发现很少有关于 Vuepress 部署到个人云服务器上的文章,于是就花了两天时间自己动手尝试部署到阿里云,同时做一下记录。 ## 思路 因为懒,想省事,所以想在本地写好文章好直接 push 到服务器上,然后自动打包发布,这个过程大概就叫自动部署吧。 1. 首先在阿里云服务器上安装 Nginx,用作 web 服务器,好像有点大材小用,但为了防止以后自己在服务器上面加个别的什么东西,干脆先装上。 2. 既然要自动部署肯定会用到 git ,不管是 push 还是 pull 都会用到,先装上。 3. 当 pull 了代码后需要 npm 打包,肯定要用到 Nodejs,所以先装上。 4. 既然装了 Nodejs,就干脆用 pm2 是用来跑 webhook 服务,webhook 在本地代码 push 到 git(gitee/github) 上后自动拉取代码到阿里云服务器,这时在 Linux 写一个自动打包和发布的 sh 脚本就完事了。 下面开始进入正题 > ps:以下操作是基于 CentOS 7.x 版本以上的 ## 安装 Nginx ### 1. 安装 gcc 安装 nginx 需要先将官网下载的源码进行编译,编译依赖 gcc 环境,如果没有 gcc 环境,则需要安装 ```sh yum install gcc-c++ ``` ### 2. 安装 PCRE pcre-devel PCRE(Perl Compatible Regular Expressions) 是一个 Perl 库,包括 perl 兼容的正则表达式库。nginx 的 http 模块使用 pcre 来解析正则表达式,所以需要在 linux 上安装 pcre 库,pcre-devel 是使用 pcre 开发的一个二次开发库。nginx 也需要此库。 ```sh yum install -y pcre pcre-devel ``` ### 3. 安装 zlib zlib 库提供了很多种压缩和解压缩的方式, nginx 使用 zlib 对 http 包的内容进行 gzip ,所以需要在 Centos 上安装 zlib 库。 ```sh yum install -y zlib zlib-devel ``` ### 4. 安装 OpenSSL OpenSSL 是一个强大的安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及 SSL 协议,并提供丰富的应用程序供测试或其它目的使用。 nginx 不仅支持 http 协议,还支持 https(即在 ssl 协议上传输 http),所以需要在 Centos 安装 OpenSSL 库。 ```sh yum install -y openssl openssl-devel ``` ### 5. 安装 Nginx 先到 [Nginx](https://nginx.org/en/download.html) 官方找需要的版本,当前最高版本是 nginx-1.17.0,右键复制下载地址开始安装 ```sh wget -c https://nginx.org/download/nginx-1.17.0.tar.gz ``` 解压 ```sh tar -zxvf nginx-1.17.0.tar.gz cd nginx-1.17.0 ``` 配置(推荐使用默认配置) ```sh ./configure ``` 编译安装 ```sh make make install ``` 查找安装路径: ```sh whereis nginx ``` ### 6. 启动、停止 Nginx ```sh cd /usr/local/nginx/sbin/ ./nginx ./nginx -s stop ./nginx -s quit ./nginx -s reload ``` > ./nginx -s quit: 此方式停止步骤是待 Nginx 进程处理任务完毕进行停止。 > ./nginx -s stop: 此方式相当于先查出 Nginx 进程 id 再使用 kill 命令强制杀掉进程。 查询 nginx 进程: ```sh ps aux|grep nginx ``` ### 7. 重启 Nginx 先停止再启动,对 Nginx 进行重启相当于先停止再启动,即先执行停止命令再执行启动命令。 ```sh ./nginx -s quit ./nginx ``` 重新加载配置文件,当修改 `nginx.conf` 配置文件修改后,要想让配置生效需要重启 Nginx,使用 `-s reload` 不用先停止 Nginx 再启动 Nginx 即可将配置信息在 Nginx 中生效,如下: ```sh ./nginx -s reload ``` ### 8. 开机自启动 即在 rc.local 增加增加一行启动代码 `/usr/local/nginx/sbin/nginx` ```sh vi /etc/rc.local ``` 设置执行权限 ```sh chmod 755 rc.local ``` > 以上内容参考:https://www.cnblogs.com/kaid/p/7640723.html ### 9. 问题 当安装完 Nginx 并启动后,遇到无法正常浏览(如:404 找不到页面)时,首先检查 Linux 防火墙 80 端口是否允许访问或者 http 服务是否启动。 Linux 防火墙相关命令: 如果你的系统上没有安装防火墙,请使用命令安装 ```sh # 安装firewalld 防火墙 yum install firewalld # 开启服务 systemctl start firewalld.service # 关闭防火墙 systemctl stop firewalld.service # 开机自动启动 systemctl enable firewalld.service # 关闭开机制动启动 systemctl disable firewalld.service # 查看状态 firewall-cmd --state # running 表示运行 # 在不改变状态的条件下重新加载防火墙 firewall-cmd --reload # 启用某个服务 firewall-cmd --zone=public --add-service=https # 临时 firewall-cmd --permanent --zone=public --add-service=https # 永久 # 开启某个端口 firewall-cmd --permanent --zone=public --list-services # 服务空格隔开 例如 dhcpv6-client https ss firewall-cmd --permanent --zone=public --list-ports # 端口空格隔开 例如 8080-8081/tcp 8388/tcp 80/tcp # 删除置的规则 firewall-cmd --permanent --zone=public --remove-rich-rule="rule family="ipv4" source address="192.168.0.4/24" service name="http" accept" # 检查设定是否生效 iptables -L -n | grep 21 # 查询服务的启动状态 firewall-cmd --query-service http firewall-cmd --query-service tcp ``` 如果防火墙配置没有问题,检查阿里云服务器安全配置 1. 进入 ECS 实例,找到“安全组配置”进入 ![阿里云安全组配置](/public/uploads/2019/11/28/1574902948313568.png "阿里云安全组配置") 2. 点击“配置规则“ ![阿里云安全组配置-点击“配置规则“](/public/uploads/2019/11/28/1574902961951915.png "阿里云安全组配置-点击“配置规则“") 3. 添加安全组规则,按提示操作即可 ![阿里云安全组配置-添加安全组规则](/public/uploads/2019/11/28/1574902974929174.png "阿里云安全组配置-添加安全组规则") 到此 Nginx 应该就可以正常访问使用了 ## 安装 git 安装 git 是为了从 gitee 上拉取代码,而不是配置一个 git 服务器,而是安装了 git 的客户端。 原本我是准备把 git 服务器也搭起来的,后来想了一下,鸡蛋不能放到一个篮子里,万一什么时候服务器让自己玩坏了,代码就全没了,所以我这里是把代码放到 gitee 上的,然后阿里云拉取 gitee 上的代码。 1. **使用 yum 源在线安装** ```sh yum install git ``` 2. **生成公钥** ```sh # 生成公钥 cd ~ ssh-keygen -t rsa # 复制公钥 ,生成的公钥在 .ssh 目录下,.开头的文件夹都是隐藏的 cd .ssh vi id_rsa.pub # 复制全部内容 ``` 3. **在 gitee 上添加公钥** 进入你的 gitee 个人中心 -> SSH 公钥,把刚在阿里云上生成的公钥添加进去 4. **gitee 新建一个项目** 这个项目就是你的 Vuepress 项目 5. **在阿里云上新建一个目录用来拉取 gitee 上的项目**, 如: ```sh mkdir /opt/www # 这个目录就是用来放项目的 ``` 6. **测试** ```sh ssh -T git@gitee.com Welcome to Gitee.com, yourname! # 返回,说明正常 ``` 7. **git pull 你的项目** 第一次是需要手动 clone 项目的,如果没有问题的话,这个时候应该可以 clone 到 gitee 上的项目了 ```sh git clone git@gitee:/gitee用户名/gitee项目名 ``` 第一次 clone 完项目后是需要 `npm install` 一下的,因为一般情况下,项目是不包含 node_modules 这个目录的,而项目打包时是需要 node_modules 的。 ## 安装 Nodejs 1. **下载 nodejs 安装包** 在 [淘宝源](https://npm.taobao.org/mirrors/node/) 或 [node 官方](https://nodejs.org/dist/) 中找到需要的对应版本链接,这里我使用了淘宝源来安装 ```sh wget https://npm.taobao.org/mirrors/node/v12.4.0/node-v12.4.0.tar.gz ``` 2. **解压** ```sh # 解压 tar -xvf node-v12.4.0.tar.gz # 安装相关插件 cd node-v12.4.0 sudo yum install gcc gcc-c++ # 在安装 nginx 的时候已经安装过,可以不装 ``` 3. **进行默认配置并编译,编译时间会比较长,大概 20 几分钟的样子** ```sh ./configure make ``` 4. **编译完成后开始安装** ```sh sudo make install ``` 5. **验证** ```sh node -v ``` > 如果需要切换多版本 nodejs 的话可以安装 nvm ## 安装 PM2 > PM2 是 node 进程管理工具,可以利用它来简化很多 node 应用管理的繁琐任务,如性能监控、自动重启、负载均衡等,而且使用非常简单。 安装 pm2 方便管理 nodejs 服务 ```sh npm install -g pm2 # 安装 pm2 pm2 start webhook.js # 启动 pm2 pm2 monit # 可以通过此命令查看服务的状态 ``` 下图是 pm2 服务状态界面 ![pm2](/public/uploads/2019/11/28/1574903023063647.png "pm2") ## WebHook 引用 Gitee 对 WebHook 的介绍: > 码云 WebHook 功能是帮助用户 push 代码后,自动回调一个设定的 http 地址。 > 这是一个通用的解决方案,用户可以自己根据不同的需求,来编写自己的脚本程序(比如发邮件,自动部署等)。 这里我们借用 WebHook 的特性来实现当本地 push 代码到 Gitee 后,服务器自动 pull Gitee 上的代码。 1. **安装 gitee-webhook-handler** ```sh npm install gitee-webhook-handler --save ``` 2. **在服务器上创建 webhook 服务** ```sh cd /opt vi webhook.js # 创建 webhook node 服务 ``` webhook.js ```js let http = require('http') let createHandler = require('gitee-webhook-handler') let handler = createHandler({ path: '/webhooks_push', secret: '123456' }) // post 所需要用到的秘钥 function run_cmd(cmd, args, callback) { let spawn = require('child_process').spawn let child = spawn(cmd, args) let resp = '' child.stdout.on('data', function(buffer) { resp += buffer.toString() }) child.stdout.on('end', function() { callback(resp) }) } handler.on('error', function(err) { console.error('Error:', err.message) }) handler.on('Push Hook', function(event) { // 这个地方就是 GitHub 和 Gitee 不一样的地方,需要注意 console.log( 'Received a push event for %s to %s', event.payload.repository.name, event.payload.ref ) run_cmd('sh', ['./deploy.sh'], function(text) { console.log(text) }) // 需要执行的脚本位置 }) try { http .createServer(function(req, res) { handler(req, res, function(err) { res.statusCode = 404 res.end('no such location') }) }) .listen(3000, () => { console.log('running') }) // 服务监听的端口,可以自行修改 } catch (err) { console.error('Error:', err.message) } ``` 3. **创建 deploy.sh 脚本** 这个脚本可以参考 [Vuepress 官方的脚本写法](https://v1.vuepress.vuejs.org/zh/guide/deploy.html#github-pages) ```sh #!/bin/bash # 进入要 pull 的目录 cd /opt/www # 开始 pull git pull git@gitee.com:用户名/项目名 # 确保脚本遇到的错误 set -e # 打包生成静态文件 npm run build # 拷贝到 nginx/html 目录下, # 我这里是把整个 dist 目录复制到 nginx/html 目录下, # 需要到修改 nginx.conf 文件中 location / {} 中 root 的值 cp -r /opt/docs/.vuepress/dist/ /usr/local/nginx/html ``` 4. **gitee 上添加 webhook** 进入 gitee 上你的项目管理 -> WebHooks 设置,添加 post 地址和密钥 ![webhook](/public/uploads/2019/11/28/1574903125391875.png "webhook") 上图红框里的内容分别对应 webhook.js 中的 `let handler = createHandler({ path: '/webhooks_push', secret: '123456' })` 5. **测试** 添加完成后添加测试,如果返回结果 `{"ok":true}` 表示 webhook 可以正常使用了 ![webhook-test](/public/uploads/2019/11/28/1574903139810136.png "webhook-test") ## 总结 对于大多数的前端开发人员来说,很多时候的工作都是和 Linux 无关的,但现在前端开发所涉及的知识面越来越广,运维、部署也已经是前端人员所需要掌握的知识点之一。 对于陌生领域,大部分人总是具有抵触心理的,包括我自己在内,第一次在 Linux 上操作的时候也是抗拒的,但经过一次实际操作后,发现也不是一项不能完成的任务,虽然在做部署的时候可能做的不是很完善,但只要迈出了第一步,一切都会迎刃而解的。