There are steps to make Hexo works well with caddy, github webhooks and service script write by python3.
Why not nginx, because I know well about it, I think, and now I want to try caddy.
Why not git to deploy it? This is the way to use git for deployment. But it was outdated or I think, use webhooks and caddy maybe the pop and better way than that.
This is not as common use for webhooks, the main idear for easy to write hexo blog is follow:
One github’s repository cloned at your local system: Only write your md files at there. Two folders at VPS to clone your md files and generate by hexo for deploy.
Advantage: Write blog so easy, just write down and push to github. Generate at server, so you never need install hexo to your local system, so you can write and push anywhere have git installed Generate at server, so it will stable and faster than local.
Disadvantage: Many settings and preparations at VPS.
My System environment:
- Local: Windows 10
- VPS: Ubuntu 18.04 LTS
OK, let’s GO!
Outline:
- Preparation for your host: git
- Preparation for your VPS: git, Node.js, Hexo, webhook scripts
- Install and config Caddy to your VPS
My Tree:
- LocalMachine:
blog/blog_md- for blogs write.
- VPS:
/var/www/blog- for generated files public~/blog- Init by hexo,we generate here.~/blog_static- git clone from repository, the repository is used for push and target webhooks.~/blog_static/blog_md- subfolder of repository, contains blog md files.~/webhook-server.py- listen for webhook.~/webhook.sh- call by webhook-server.py for deploy.
# 1. VPS Preparations
This step is the preparation for using github webhook.
1.1. Install git and node.js
Git is very simple and nothing to say, simply say Node.js.
Run the command below to show a list of versions available for download and install the last LTS version:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash
nvm ls-remote
nvm install 10.16.0
nvm on # or nvm use 10.16.0
node -v
Return: v10.16.0
1.2. Install Hexo on VPS
npm install -g hexo-cli
npm install hexo-server -g
cd <blog folder>
hexo init
If error occur ERROR Local hexo not found in <blog folder>, run:
npm install hexo --save
Then:
npm install
If occur: found 1 moderate severity vulnerability, run:
npm audit fix --force
Then:
hexo init
1.3. Github hooks
1.3.1. Add webhook at respository where your md files placed
- Payload URL resemble:
http://huifeng.me:123/webhook - Content type: the default content type of
application/jsonis fine.
1.3.2. Write a python webhook-server.py:
1st Way authenticate the hook conveniently (Recommend)
A easy way for enable secret: GitHub Webhook (micro) Framework It also can do anything about webhooks, but documents is so poor.
Environment Prepare:
sudo apt install python3-pip
pip3 install flask
pip3 install github_webhook
My final webhook-server.py (run as python3):
import os
from github_webhook import Webhook
from flask import Flask
app = Flask(__name__) # Standard Flask app
webhook = Webhook(app, endpoint="/testendpoint", secret='testsecret') # Defines '/postreceive' endpoint
@app.route("/") # Standard Flask endpoint
def hello_world():
return "Hello, World!"
@webhook.hook() # Defines a handler for the 'push' event
def on_push(data):
#print("Got push with: {0}".format(data))
print(os.popen("sh ~/webhook.sh").read())
if __name__ == "__main__":
try:
port_number = int(sys.argv[1])
except:
port_number = 8888
app.run(host="0.0.0.0", port=port_number, debug=False)
Key settings:
-
If code is
webhook = Webhook(app, endpoint="/testendpoint", secret='testsecret'):- Payload URL setting is resemble: http://huifeng.me:8888/testendpoint
- Secret setting is
testsecret
-
If with no secret setting:
webhook = Webhook(app, endpoint="/testendpoint")
-
If nothing defined yourself, code is
webhook = Webhook(app):- Default way:
/postreceive - Without secret verification.
- Default way:
2nd Way without authenticate but simple (Optional)
Without authenticate but easy, a way to study but suggust not use in Ops.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import json
import os
import traceback
from flask import Flask, request
app = Flask(__name__)
@app.route('/webhook', methods=['POST'])
def update():
if request.method == 'POST':
try:
print request.headers
print request.json
print os.popen("sh ~/webhook.sh").read()
except:
print traceback.format_exc()
return json.dumps({"msg": "error method"})
if __name__ == '__main__':
try:
port_number = int(sys.argv[1])
except:
port_number = 8888
app.run(host="0.0.0.0", port=port_number, debug=False)
You can enable secret by yourself(Optional choise) or jump to 1st Way: Give the abilitiy to authenticate the hook by sercet. we can modify the python code above, the core is:
import hmac
header_signature = request.META.get('HTTP_X_HUB_SIGNATURE')
signature = header_signature.split('=')
mac = hmac.new('YOUR GITHUB WEBHOOK SECRET'.encode('utf-8'), request.body, hash_type).hexdigest()
if hmac.compare_digest(mac, signature):
print os.popen("sh ~/webhook.sh").read()
But, the code above need test, not the final code to run, just a thought!
1.3.3. Write a shell webhook.sh:
#!/usr/bin/env bash
cd ~/blog_static
git pull https://github.com/wedojava/Blog.git
rm -rf ~/blog/source/_posts/*
cp -rp ~/blog_static/blog_md/* ~/blog/source/_posts/
cd ~/blog
hexo clean
hexo generate
rm -rf /var/www/blog/*
cp -rp ~/blog/public/* /var/www/blog/
1.3.4. Run in background:
nohup python webhook-server.py &
Don’t warry, you can read logs in file nohup where webhook-server.py located.
If your server’s environment is not suitable, run the command follow:
sudo apt install python-pip
pip install request flask
I suggest test before run in background,you can run the command below to assess the return lines:
python webhook-server.py
# 2. Install and config Caddy to your VPS
2.1. Directory and permissions prepare
Reference: https://caddyserver.com/docs
Reference:https://github.com/caddyserver/caddy/tree/master/dist/init/linux-systemd
Main idea: Give website folder appropriate ownership and permission, so if git pushed, python script can catch the webhook event and load shell script to pull, move etc.
(If your VPS not setted default)Set up the user, group, and directories that will be needed:
sudo groupadd -g 33 www-data
sudo useradd \
-g www-data --no-user-group \
--home-dir /var/www --no-create-home \
--shell /usr/sbin/nologin \
--system --uid 33 www-data
Create caddy folder and give it appropriate ownership and permissions:
sudo mkdir /etc/caddy
sudo chown -R root:root /etc/caddy
sudo mkdir /etc/ssl/caddy
sudo chown -R root:www-data /etc/ssl/caddy
sudo chmod 0770 /etc/ssl/caddy
Place your caddy configuration file (“Caddyfile”) in the proper directory and give it appropriate ownership and permissions:
sudo cp /path/to/Caddyfile /etc/caddy/
sudo chown root:root /etc/caddy/Caddyfile
sudo chmod 644 /etc/caddy/Caddyfile
Create the home directory for the server and give it appropriate ownership and permissions:
sudo mkdir /var/www
sudo chown www-data:www-data /var/www
sudo chmod 755 /var/www
Let’s assume you have the contents of your website in a directory called ‘blog’. Put your website into place for it to be served by caddy:
sudo mkdir /var/www/blog
sudo chown -R <youruser>:<yourgroup> /var/www/blog
sudo chmod -R 755 /var/www/blog
2.2. Config Caddyfile
DIffer from other service, for caddy you can make config file first to ensure which plugin is necessary, after config the file, caddy install option will also becoming your mind, you can study how to set it by caddy offical doc: https://caddyserver.com/docs
/etc/caddy/Caddyfile may resembles below:
huifeng.me {
root /var/www/blog
tls yourusername@gmail.com
index index.html
# minify
gzip
log /var/www/access.log {
rotate_size 50 # Rotate a log when it reaches 50 MB
rotate_age 90 # Keep rotated log files for 90 days
rotate_keep 20 # Keep at most 20 rotated log files
rotate_compress # Compress rotated log files in gzip format
}
limits {
header 100KB
body /download 100MB
}
errors /var/www/error.log {
# 404 404/index.html
rotate_size 50 # Rotate a log when it reaches 50 MB
rotate_age 90 # Keep rotated log files for 90 days
rotate_keep 20 # Keep at most 20 rotated log files
rotate_compress # Compress rotated log files in gzip format
}
}
2.3. Install via script
This step requires root privileges, so:
su
curl https://getcaddy.com | bash -s personal http.cache,http.minify
exit
Enable Caddy as service:
Notice!
If you assume the following:
- that you want to run caddy as user
www-dataand groupwww-data - caddy binary in the system wide binary directory:
/usr/local/bin/caddy - your caddy configuration file (“Caddyfile”) in the proper directory
/etc/caddy/Caddyfile - your caddy tls(Letsencrypt-issued certificates) want to write in:
/etc/ssl/caddy
please preceed:
# 从 github 下载 systemd 配置文件
sudo curl -s https://raw.githubusercontent.com/mholt/caddy/master/dist/init/linux-systemd/caddy.service -o /etc/systemd/system/caddy.service
sudo systemctl daemon-reload # 重新加载 systemd 配置
sudo systemctl enable caddy.service # 设置 caddy 服务自启动
sudo systemctl status caddy.service # 查看 caddy 状态
Else:
edit /etc/systemd/system/caddy.service to set your right user, group, and so on.
# 3. Some Tips:
If you use caddy, sometimes, web is blank, also viewed by source, maybe, your
Caddyfilehave something wrong or your vps cannot support some feature well, so, comment out line by line and test. For me, I commentedminify,extwhile the blank page occured, and it fixed.
About Github hooks, if python and shell is allright, but still cannot works well, try to change github setting of webhooks, set
Payload URLashttp://your-urlnothttps.
EOF
Thanks for https://www.jianshu.com/p/75274647c4b0