I used dropbox to sync my blog posts so that I can write my blog anywhere, instead of logging on to my vps. But dropbox’s instant sync makes it hard to control post event. Github is a great version control tool, if server side can automatically pull changed posts when pushing events happened on other device, then the github push event is kind of like posting your blogs to remote server. This should be a better way to using hexo. Luckily github’s webhooks service makes this possible to implement.

Server side


On the vps server side, first thing is init your post directory as a Git repository.

1
2
3
4
cd your_post_direcotry
git init
git add .
git commit -m 'First commit'

Second write a PHP to excute github pull, this php file is called by Github webhooks service.

1
2
3
4
<?php
$results = shell_exec("git pull");
echo "<pre>$results</pre>"
?>

This php program is very simple, but it actually does the pull trick, and you can read the response from the github page to see if pull excuted properly. As pull excution is called by apache service, so we should change the folder owner to www-data and make php excutable.

1
2
chown -R www-data:www-data you_post_directory
chmod u+x githubpull.php

Then push post folder to remote repository on you github. Also you should create an empty repository on your github page.

1
2
git remote add origin remote_repository_URL
git push origin master

Then on your hexo blog folder, you should let hexo to monitor your post changes by using hexo generate. Here I also use screen to let it run on the background.

1
2
screen -S hexo
hexo generate --watch

Final thing to do on vps server side is to create an apahce vhost to let this php can be called from outside. Below is a simple example, you should configure you dns profider to let this ServerName accessible.

1
2
3
4
5
6
7
<VirtualHost *:80>
ServerName blogpost.yourdomain.me
ServerAdmin xxxx@gmail.com
DocumentRoot /var/www/html/blog/source/_posts/
ErrorLog ${APACHE_LOG_DIR}/error_post.log
CustomLog ${APACHE_LOG_DIR}/access_post.log combined
</VirtualHost>

Github side


On Github web page, the only thing to do is to add a webhook. Github webhooks are under setting page, like image below.
Setting

Click on add webhook, shows next panel, you can leave other things by default, and fill in your githubpull.php address in payload URL, this URL is called when a push event happened. Then it’s done.
Webhook

Test


Then you can test it on your local machine. Just clone the repository to your local machine, make some changes or add a post, then push it to remote, you should see that your site is being updated simutaneusly.

1
2
3
4
5
git clone remote_repository_url local_post_dir
Add a new post
git add .
git commit -m 'add new post'
git push

SSH key configuration


Above methods can only work on public repository, but it’s obviously not a good idea making your blog posts a public repository that everyone can mess with. But when you change to private repository, the pull action cannot be performed due to lack of password, we need to add ssh keys to github settings.

First we should generate ssh keys, since this php programm is called by apache, so we should generate ssh keys for www-data user.

1
2
3
4
sudo mkdir /var/www/.ssh
sudo chown -R apache:apache /var/www/.ssh/
sudo -Hu apache ssh-keygen -t rsa # choose "no passphrase"
sudo cat /var/www/.ssh/id_rsa.pub

Then add above SSH keys to your github account. Then we should change remote repository on the server to SSH style.

1
2
cd git_dir
git remote set-url origin git@github.com:USERNAME/REPOSITORY.git

After this, we should perform git pull once manually, because there is a promote message to ask if you accept the keys when first time use. If we don’t perform git pull once manually, the auto-pull script will never perform successfully.

To do


This php program is too simple, should add some functions to let it only respond to github webhook post, for example we can parse the json posted by github to verify this post request is from github.


Comments