Linode配置NodeJS和Jekyll


配置Ruby环境

  • install rvm:

      % gpg --keyserver hkp://keys.gnupg.net 
      --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB`
    
      % curl -sSL https://get.rvm.io | bash
      % source ~/.rvm/scripts/rvm
    
  • install ruby
    • rvm install ruby_version
  • install jekyll
    • gem install jekyll

配置Nginx反向代理

我们可以使用Nginx作为HTTP web server,令ROOT指向Jekyll的_site下的index.html,配置Nginx 如下:

#root folder
root /home/xxx/_site/;
index index.html index.htm index.md;

启动Nginx,即可测试首页是否能正确显示

配置Nodejs

尽量不要使用apt-get来安装Node.js,如果已经安装了,执行:

%sudo apt-get purge nodejs 
%sudo apt-get autoremove 
%sudo apt-get autoclean
  • Install nvm & node:
% curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash

%nvm list
%nvm ls-remote
%nvm install 10.7.0
%nvm use 10.7.0
%nvm alias default 10.7.0
%node -v
%npm install -g npm
%npm -v
%echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p

配置持续集成环境

Jekyll的持续集成有很多种方式,这里介绍一种使用Node.js作为Server响应Github Webhook的方式。对于什么是Webhook,可参考这里。其大致思路是:

  1. 每当有一个次commit到Github的Jekyll Blog仓库,Github会发送一条POST请求到我们的Server
  2. 这时候Ngxin作为反向代理,将请求路由到内部的Node.js服务上
  3. Node.js收到请求后,执行一段shell脚本,重新build Jekyll blog

因此第一步是要先配置Github的Webhook发送策略,配置方式参考这里。Webhook配置完成后,需要在Nginx配置文件中,指定反向代理路径,参考配置如下:

location /api {
	proxy_http_version 1.1;
	proxy_set_header Upgrade $http_upgrade;
	proxy_set_header Connection 'upgrade';
	proxy_set_header Host $host;
	proxy_cache_bypass $http_upgrade;
	proxy_pass http://127.0.0.1:1234;
}

上述配置会将所有/api的请求路由到http://127.0.0.1:1234;上,因此我们需要写一个Node.js Server来监听这个端口:

const app = express()
//middleware
//body parser
app.use(bodyparser.json())
app.use(bodyparser.urlencoded({extended:false}))

//bunyan log
app.use(function(req,res,next){
    logger.info({
        header: JSON.stringify(req.headers),
        body: JSON.stringify(req.body)
    })
    next()
})

//router
app.use('/api',indexRouter)
app.use('/api/webhook',webhookRouter)

app.listen(config.port,"127.0.0.1", function(){
    logger.info("Server Started!")
})

上述代码中,当收到/api/webhook请求时,需要执行一段shell脚本来拉取最新的commit并重新build Jekyll,shell脚本参考如下:

#!/bin/bash

build(){
    cd ..
    site_dir=`pwd`
    repo_name="***"
    repo_git="***"
    echo "Direcotor: $site_dir"
    if [ ! -d "$repo_name" ]; then
        echo "No repo: $repo_name found in $site_dir"
        echo "Begin cloning..."
        git clone $repo_git || echo "clone failed!"
    fi 
    echo "Found $repo_name in $site_dir"
    cd $repo_name
    echo "Pulling new commits..."
    git pull origin master
    echo "Running jekyll build, this may take a while...."
    JEKYLL_ENV=production jekyll build || "jekyll build failed!"
    if [ "$?" -eq "0" ]; then
        echo "Build Succeed"
    else
        echo "Build Failed!"
        return 1
    fi
    app_dir="$site_dir/site"
    if [ -d $app_dir ]; then
        echo "Found old app folder, delete it."
        rm -rf $app_dir
    else
        mkdir $app_dir
    fi
    echo "Copying new app to site."
    cp -R _site $app_dir
    echo "Done"
}
build

对于上述代码,如果感兴趣,完整的Server的代码在这里(不要忘记给个star哦)。当然,对于Jekyll的CI还有其它的方式,比较轻量的是使用Github自带的服务,可参考Github相关教程。此外还使用Travis CI的方式,这种方式可能会暴露Webhook的secret,比建议使用,更多CI的文档,可参考Jekyll官方文档

Resource