手摸手,带你实现代码自动部署

为何?

为何要实现自动部署?javascript

在2个月的时间里,一直都在忙着整理博客,每个程序员都有一个博客梦(固然也不排除有些是没有的),我前后使用过各类博客系统:
php

这些都由于前先后后的缘由,我没有采用,而是本身写了一个博客系统:vue-blog-generater【请容许我再求一波star】点击这里查看说明文档html

为何呢?由于我须要一个本身对其高度熟悉的系统,这样有什么问题,我都知道问题出在哪,由于以前的这些系统,固然很好,可是不管是主题的编辑,仍是代码的部署以及自定义,这些都不能知足个人要求。vue

话说回来,当我实现好了基础功能和页面以后,我开心了好一下子,而后把一些还有意义的博文转移过来,这就涉及到了发布和部署。java

咱们都知道一个vue-cli生成的项目,一般打包的目录都是dist,那么我实际上须要挂载到服务器上的代码就是这个dist中的代码。node

那按照常理,整个文章的更新流程应该是这样:
react

  1. 新建文件,编写markdown博文
  2. npm run build 编译到dist
  3. dist的文件上传到对应的代码仓库dist
  4. 将当前生成器的文件同步上传到对应代码仓库main
  5. 登陆服务器,git clone dist仓库到指定的位置

看到了吧,只是更新一篇文章,却须要这么多步骤,是否是以为很麻烦呢?麻烦就对了,在这里咱们就是来解决这个麻烦的。nginx

如何作?

我明白了为何要作自动部署,可是我从哪下手呢?git

作一件事情以前,咱们要理清楚思路,有哪些步骤呢?其实很是简单:程序员

  1. 新建文件,编写markdown博文【这一步是跑不掉的】
  2. npm run build 编译到dist,执行build.js中判断config.js中是否配置了dist的远程仓库地址。
    若是配置了就对当前项目的dist目录,进行git初始化,同时将总体代码上传到Main仓库这里默认不配置,Main仓库至关于本地仓库关联的远程仓库
  3. 给本地dist目录关联远程仓库,并把代码推送到指定的dist对应的远程仓库中。
  4. 服务器进行配置,当接受到托管平台发送的POST请求时,作出对应的响应:拉取远程dist仓库的master分支而且强制覆盖本地的master分支

具体实现?

咱们先来看看在第2,3个所说的内容怎么实现。

  • 准备工做:安装须要的库
    shell 帮助咱们在nodejs中执行命令
    chalk 丰富打印信息
//安装shell
yarn add shell --save
yarn add chalk --save
复制代码
  • 咱们在build.js中设计一个函数autoUpdate,来帮助咱们提交main仓库和咱们的dist仓库的更新,咱们先实现更新main仓库:请注意:这里须要使用await确保代码的执行顺序
const config = require('../config')
const shell = require('shelljs')

async function autoUpdate() {
  console.log(chalk.cyan(
    `Start to upload whole project to coding.net`
  ))
  if (!shell.which('git')) {
    //向命令行打印git命令不可用的提示信息
    shell.echo('Sorry, this script requires git');
    //退出当前进程
    shell.exit(1);
  }
  // 推送当前目录[main 目录]的代码
  await shell.exec('git add .')
  await shell.exec(`git commit -m '${config.commitMessage}'`).code
  await shell.exec('git push origin master -f');
  console.log(chalk.green(
    `main dir-> succeed`
  ))
}
复制代码
  • @/config/index.js中配置 dist远程仓库 相关的属性的值
module.exports = {
   ...
   distOriginSSh: 'git@github.com:xxx/xxx-blog-xxx.git',
   ...
}
复制代码
  • autoUpdate中添加提交dist仓库的更新的代码:请注意:这里须要使用await确保代码的执行顺序
//进入到dist目录下
  await shell.cd('dist');
  //执行 git init
  await shell.exec(config.initLocal)
  //删除本地的dist已经对应的远程仓库
  await shell.exec(config.deleteRemote)
  //添加目标远程仓库到dist
  await shell.exec(`git remote add origin '${config.distOriginSSh}'`)
  //提交
  await shell.exec('git add .')
  let code = await shell.exec(`git commit -m '${config.commitMessage}'`).code
  if (code !== 0) {
    await shell.echo('Error: Git commit failed');
    await shell.exit(code);
  } else {
    await shell.exec('git push origin master -f');
    //chalk 这个库是为了丰富打印信息的
    console.log(chalk.green(
      `dist-> succeed`
    ))
  }
复制代码

实现了本地上传到远程仓库,那么接下来咱们须要去作几件事,来实现步骤4:
这里默认你已经在服务器上完成了对dist代码的部署

  1. 在本身的服务器上启动一个服务,监听POST的请求,若是肯定这个请求是通知咱们须要更新服务器上对应dist目录对应的源码的话,执行对应的git命令来更新。
  2. 配置远程仓库的hooks,在监听到咱们的push请求时,就会自动POST一个请求到咱们配置的hooks对应的地址中。这个地址也就是咱们在服务器上启动的服务地址。

Okay,知道了要作什么,那咱们就开始吧。首先在服务器上启动一个node server,咱们新建一个server.js,而且进入到编辑状态

touch server.js
//若是你安装了vim
vim server.js
//若是没有安装vim,能够用vi
vi server.js
//进入文件后,咱们能够按a健进入 insert状态
复制代码

能够参考个人server.js进行配置 请注意,须要你本身配置端口和路径,我已经去除了我本身的配置

var http = require('http')
  , exec = require('exec')

// 配制你的端口号
const PORT = XXX
  , PATH = './xxx'
//PATH:你的dist目录的路径,相对于server.js所在的目录而言。
var deployServer = http.createServer(function(request, response) {
  if (request.url.search(/deploy\/?$/i) > 0) {

    var commands = [
      'cd ' + PATH,
      'git fetch --all',
      'git reset --hard origin/master',
      'git pull'
    ].join(' && ')

    exec(commands, function(err, out, code) {
      if (err instanceof Error) {
        response.writeHead(500)
        response.end('Server Internal Error.')
        throw err
      }
      process.stderr.write(err)
      process.stdout.write(out)
      response.writeHead(200)
      response.end('Deploy Done.')

    })

  } else {

    response.writeHead(404)
复制代码

编辑完成后,而后咱们先按下esc而后输入:wq!保存文件。而后node server.js启动一个服务。可是你又会发现,node server.js这样启动的服务会在一段时间后自动中止,因此咱们须要来用一个守护进程的工具来守护咱们的服务,推荐你们使用forever

#安装
npm install forever -g
#启动
forever server.js
复制代码

尚未结束,咱们还须要在nginx配置文件中设置一个代理,将对应子域名代理到咱们刚刚配置的端口上。这样作的缘由是由于我只有一个域名···

你可能会问什么是子域名,好比我有一个一级域名dendoink.com那么我能够在解析的时候多添加一条新记录xxx.dendoink.com,这个就是子域名,他一样能够访问到咱们域名对应的服务器。

若是你使用的也是nginx来管理服务,那能够参考我下面的配置

server {
    listen       80;
    # 配置你的子域名
    server_name  xxx.你的域名.com;

    #charset koi8-r;
    access_log  /var/log/nginx/githook.dendoink.com.access.log  main;
    
    # 这里是重点
    location / {
        proxy_pass http://127.0.0.1:1024;
    }
    #error_page 404 /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    # proxy_pass http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    # root html;
    # fastcgi_pass 127.0.0.1:9000;
    # fastcgi_index index.php;
    # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
    # include fastcgi_params;
    #}

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    # deny all;
    #}
}
复制代码

这样配置好之后咱们就能够经过外部访问到咱们定义好的服务啦。只须要把这个地址加入到对应的githook的配置中【具体的hook配置参考你的托管平台教程】。

是否是很简单呢?有任何问题能够掘金和我联系,或者邮件 dendise7en@gmail.com

另外求一波关注和star -> 看这里,最美博客系统~
另外求一波关注和star -> 看这里,最美博客系统~
另外求一波关注和star -> 看这里,最美博客系统~


特别声明:题图来源unsplash

相关文章
相关标签/搜索