一键式部署、更新静态网站

环境

Nginx server: Ubuntu 18.04.4 LTS

生成网站内容

内容编辑

先从gitee下载源代码

git clone https://gitee.com/bruno_gao/hg-tech.io.git

或者

git pull https://gitee.com/bruno_gao/hg-tech.io.git

然后用markdown编辑器对源代码的.md文件进行编辑(增/删/改),我目前使用的是typora,配套ipic自动同步图片到腾讯云COS,如果hugo启动在源代码的根目录,则可以监控到typora编辑文档的变化并实时更新网站内容,做到所改即所见。

另外对于视频如果需要从youtube下载,推荐用youtube-dl

#下载工具
sudo apt install youtube-dl
#配置工具
~ cat ~/.config/youtube-dl/config 
--proxy 127.0.0.1:1087  --write-description --write-info-json --write-annotations --write-sub --write-thumbnail --restrict-filenames -f best+mp4 --write-auto-sub  -o /Users/xxx/Downloads/youtube/%(title)s-%(id)s.%(ext)s
#下载视频,封面以及字幕
youtube-dl https://www.youtube.com/watch\?v\=s8JqcZtvnsM

代码上传

运行下面命令进行代码提交:

git add .
git commit -m "some comments here"
git push -u origin master

使用自己的服务器部署静态网站

安装Hugo

最后安装hugo,执行以下命令

sudo apt install hugo 

可以通过hugo version查看版本来验证是否安装成功,如果安装成功,则会显示正确的版本号。

hugo version
Hugo Static Site Generator v0.64.0-241DB8F7 linux/amd64 BuildDate: 2020-02-04T09:10:23Z

部署网站

在服务器中编译网站,然后编译后的网站代码放在Nginx服务的静态路径上

编译源代码

需要git工具,下载在gitee上面的代码,执行以下命令:

git clone https://gitee.com/bruno_gao/hg-tech.io.git
cd hg-tech.io
hugo serve

Hugo serve命令会编译从github上下载的源码生成html文件并存储在public文件夹

部署到Nginx服务器上:

执行安装nginx命令,如下:

sudo apt install nginx

Nginx配置成功后,需要设置Nginx的配置,配置文件路径为/etc/nginx/sites-available/default,配置的内容如下:

server {
    listen       80;
    server_name  localhost;

    location / {
        root   /data/web;
        index  index.html index.htm;
    }

    error_page  404              /404.html;

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /data/web;
    }
   
   }

安装Nginx服务器成功后,将Jekyll编译的博客静态html文件输出到Nginx服务器上,执行以下的命令:

hugo server --destination=/data/web

启动Nginx服务器,就可以正常的博客网页了,如果需要在浏览器上访问,需要在服务器的安全组件暴露80端口。如果想通过域名访问,需要将域名解析设置指向你的服务器。

非www域名的重定向到www

比如我想访问http://heguang-tech.com/重定向到http://www.heguang-tech.com/上,需要在Nginx的配置文件/etc/nginx/sites-available/default,修改配置以下内容:

listen       80;
    server_name  heguang-tech.com www.heguang-tech.com;


    if ( $host != 'www.heguang-tech.com' ) {
          rewrite "^/(.*)$" http://www.heguang-tech.com/$1 permanent;
         }

支持https

如果需要上https协议,需要在域名所在的服务商申请免费的SSL证书,申请完之后,可以查看Nginx安装SSL证书的教程,并做配置,然后修改nginx的配置文件/etc/nginx/sites-available/default:

server {
        listen       80;
        server_name  www.heguang-tech.com/;
        return 301 https://www.heguang-tech$request_uri;
    }
server {
        listen 443;
        server_name heguang-tech.com;
        return 301 https://www.heguang-tech.com$request_uri;
    }

server {
    listen 443 default_server ssl;
    server_name  www.heguang-tech.com;

    ssl on;
    root html;
    index index.html index.htm;
    ssl_certificate   #your certification
    ssl_certificate_key   #your certificate_key
    ssl_session_timeout 5m;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
     location / {
        root   /data/web;
        index  index.html index.htm;
    }

    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   /data/web;
    }

}

自动化部署

通过设置gitee的webhook可以实现自动化构建和部署:提交代码到gitee仓库,仓库会触发你设置的webhook,会向你设置的webhook地址发送一个post请求,比如我设置的请求是在服务器的跑的一个Nodejs程序,监听gitee webhook的请求,接受到请求后,会执行shell命令。

在gitee上添加wehook, 以https://gitee.com/bruno_gao/hg-tech.io/hooks为例:

这样Webhook就设置成功了,现在在博客所在的服务端去监听gitee Webhook发送的请求,我采用的开源组件去监听gitee-webhook-handler

npm install -g gitee-webhook-handle

安装成功后,在~/codes/blog(按需修改)下新建deploy.js文件:

var http = require('http')
var createHandler = require('gitee-webhook-handler')
var handler = createHandler({ path: '/deploy', secret: '123456' })

function run_cmd(cmd, args, callback) {
  var spawn = require('child_process').spawn;
  var child = spawn(cmd, args);
  var 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) {
  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(6666)
}catch(err){
  console.error('Error:', err.message)
}

上述代码中,指定了nodejs服务的践踏端口为6666,监听了path/incoming,Secret为123456,这和之前gitee Webhook设置的要保持一致。代码run_cmd(‘sh’, [’./deploy.sh’],指定了接受到请求后执行./deploy.sh,deploy.sh文件的代码如下,首先进入到博客的代码文件,拉代码,编译。

echo `date`
cd /home/ubuntu/codes/blog/hg-tech.io
echo start pull from github 
git pull https://gitee.com/<your git>.git
echo start build..
hugo
echo promoting to production..
cp -r public /data/web
echo reloading new changes..
sudo nginx -s reload
echo done..

然后需要使用forever来启动deploy.js的服务,执行命令如下:

sudo npm install forever -g   #安装
$ forever start deploy.js          #启动
$ forever stop deploy.js           #关闭
$ forever start -l forever.log -o out.log -e err.log deploy.js   #输出日志和错误

如果在安装过程中出现下面错误:

image-20200311122822828

请用下面命令来解决:

sudo npm install -g npm@latest 

最后一步,需要在nginx服务器的配置文件,需要将监听的/deploy请求转发到nodejs服务上,配置代码如下:

location = /incoming {
     proxy_pass http://127.0.0.1:6666/deploy;
}

这样,当你提交了文章或者修改的配置到gitee上,gitee通过webhook向你所在的服务器发送请求,服务器接收到请求后执行 sh命令,sh命令包括了重新pull代码和编译代码的过程,这样自动化部署就完成了,你只需提交代码,服务器就触发pull代码和重新编译的动作。

这些信息有用吗?
Do you have any suggestions for improvement?

Thanks for your feedback!