使用 gitcafe pages 更新博客只需要敲几条命令,如果因为博客搬到了阿里云,却没有原来操作方便,那便得不偿失了。
所以就准备在服务器上建个 Git 远程仓库,用 Git Hooks 实现自动部署。

Git Hooks

Git Hooks 就是一些触发特定事件的脚本。比如 commit、push、merge 等等,也区分本地 Hooks 和服务端 Hooks。
我这次使用的是post-receive

当用户在本地仓库执行git-push命令时,服务器上远程仓库就会对应执行git-receive-pack命令,而git-receive-pack命令会调用pre-receive钩子。

这需要在服务器上建立一个 Git 远程仓库,和一个用于获取更新(git pull)的本地仓库。

远程仓库:最原始的版本库,所有的本地仓库就可以克隆这个仓库。就像你在 Github 创建一个项目,这就是一个远程仓库。
本地仓库:这个就是平常的工作目录,容易理解。

总体的流程为:

  1. 本地执行git push
  2. Git 服务器更新并 Hook;
  3. 执行pre-receive脚本,命令为:定位到服务器本地仓库目录,执行git pull

我的 git 已经安装了,Ubuntu 安装很简单:

sudo apt-get install git

创建 git 用户,用来运行 git 服务:

sudo adduser git

用 git 用户运行貌似是约定俗成的事,像 github 一个仓库的 URL 为git@github.com:user/project.git,@ 符号前面的 git 就是运行 git 服务的用户名。

初始化远程仓库:

我的目录名为website,仓库名为blog,以此为例。

cd /website
sudo git init --bare blog.git

远程仓库名以.git结尾。还需要给 git 用户设置该目录的权限:

sudo chown -R git:git blog.git

出于安全考虑,禁用 shell 登录:

vi /etc/passwd

找到这一行:

git:x:1002:1002:,,,:/home/git:/bin/bash

修改为:

git:x:1002:1002:,,,:/home/git:/usr/bin/git-shell

可以使用git-shell,通过ssh使用 git,但无法使用 shell 登录。

创建证书登录,把本地公钥添加到/home/git/.ssh/authorized_keys
不过默认的id_rsa公钥一般都被占用了,可以再建个其他名字,创建.ssh/config区分。

初始化服务器本地仓库:

我是在远程仓库旁边建立的。

cd /website
git clone blog.git

因为是在同一台电脑上,所以克隆直接使用本地路径。这将会在website生成一个名为blog本地仓库。

ls -la

可以看到当前路径下有一个blog.git目录和一个blog目录。

考虑到 git-hooks 运行使用的是 git 用户,也对服务器本地仓库授权:

chown -R git:git blog

设置 hook 执行脚本:

vi blog.git/hooks/post-receive

输入以下内容:

#!/bin/sh
cd /website/blog
git pull origin master

很好理解,就是定位到服务器本地仓库然后拉取更新。

保存后赋予可执行权限:

chmod +x blog.git/hooks/post-receive

现在可以在本地(你的电脑上)进行测试了。

找一个目录,进行版本库克隆:

git clone git@server:/website/blog.git

server 是你的服务器域名或者IP。

因为仓库还没有内容,所以会显示:You appear to have cloned an empty repository. 你克隆了一个空仓库。

现在可以随便创建点东西,push 到远程仓库,然后到/website/blog目录下看看有没有变化。

我在操作的时候遇到一个错误:fatal: Not a git repository: ‘.’

因为 hook 脚本执行了 cd 之后,继续执行 git 语句拉取的时候还是在 hooks 文件夹下,而不是 cd 的文件路径。

修改后的脚本如下:

#!/bin/sh
unset GIT_DIR #还原环境变量
cd /website/blog
git pull origin master

现在已经实现本地到远程服务器的同步了,只差一个 Web 服务器了。

Nginx安装配置

目前我的博客在 gitcafe 上,在 URL 后面随便加点后缀进入 404 页面,可以清楚的看到 nginx/1.8.0 的字样。以后还要玩负载均衡,服务器肯定就选它了。

sudo apt-get install nginx

看了很多文章,发现其中描述的 Nginx 的文件结构都不太一样,看来跟系统环境有关系。
我的目录结构如下,环境是阿里云 Ubuntu 14.04 :

  • 所有的配置文件都在/etc/nginx下,并且每个虚拟主机已经安排在了/etc/nginx/sites-available
  • 启动程序文件在/usr/sbin/nginx
  • 日志放在了/var/log/nginx中,分别是access.logerror.log
  • /etc/init.d/下创建了启动脚本nginx
  • 默认的虚拟主机的目录设置在/usr/share/nginx/html

启动 Nginx :

sudo /etc/init.d/nginx start

默认的服务器配置是 80 端口,如果你没有其他的 Web Server 在运行,打开服务器域名或 IP 应该可以看到Welcome to nginx!

现在定位到配置文件,修改配置:

vi /etc/nginx/nginx.conf

找到server { ... }区域:

server {
listen 80; #端口
server_name localhost yoursite.com; #域名或IP
root /website/blog; #站点根目录
charset utf-8; #文件编码
index index.html index.htm; #首页
error_page 404 /404.html; #404页面
error_page 500 502 503 504 /50x.html; #服务端错误页面
#url访问匹配路径,可以添加多个
location / {
index index.html index.htm;
root /website/blog; #这里可以是绝对路径或者相对路径,基于站点根目录
}
}

可以用一条命令测试配置是否正确:

nginx -t -c /etc/nginx/nginx.conf

重启 Nginx 服务器使配置生效:

/etc/init.d/nginx restart

现在开始部署 Hexo。

Hexo 部署

原来的 Hexo 使用的是 hexo-deployer-git 插件,会在 Hexo 下生成一个 .deploy_git 目录,从这个目录上传到 pages 分支。
现在我觉得不需要这个插件了,可以直接在 public 目录下初始化 git 仓库然后上传。

cd hexo/public
git init
git add -A
git commit -m 'add myBlog'
git remote add origin git@server:/website/blog.git
git push origin master

这时候打开站点,就可以看到博客了。

我的域名还没有备案,之前注册的域名有备案号,需要迁到阿里云。
好像审核期间需要关站,真是麻烦。

参考