各种部署方式

静态博客的部署方式多种多样,免费部署资源非常多。

如果DNS支持多线路,还可以设置多路负载均衡!

注意:这些免费的部署都没法做ICP备案,或者国内CDN套着备案。不过,都免费了,你还要求那么多?

部署方式费用限制难易度多域名
Github0 $100G/M简单单域名
VPS约2~5$/M看购买套餐复杂支持
Vercel0 $100G/M简单支持
Netlify0 $100G/M简单支持
Cloudflare pages0 $简单支持
Gitlab0 $简单支持(?)

详细对比

特性GitHubGitLabNetlifyVercelCloudFlareFirebaseRender
Build Limit10/hourNone3/Minute32/hour500/monthNot ApplicableUnlisted
Build Time to Error10 minutes3 Hours15 minutes30 minutesUnlistedNot Applicable120 minutes
Build Time per MonthNA400 Minutes300 Minutes6000 MinutesUnlistedNot ApplicableUnlisted
Concurrent Builds🤷‍♂️YesOneOneOneNot ApplicableUnlisted
Deploy LimitsNANoNot Applicable100/DayUnlistedNot ApplicableUnlisted
Deploy PreviewsNoNoYesYesYesYesYes
Serverless FunctionsNoNoYesYesYesYesNot for free
Invocations/Month125k/per site/mo100GB hours/mo100k/day125k/mo
Duration Allowed10s10s10ms540s
DNS ManagementNoNoYesYesYesNoNo
HTTPS AvailableYesYesYesYesYesYesYes
Bandwidth/Month100GB/MoNo limit100GB/Mo100GB/MoNo Limit10GB/Mo100GB/Mo
Site Limit1GB10GB100GB12.5K Files20K Files10GBNone listed
Default URLgithub.iogitlab.ionetlify.appvercel.apppages.devweb.app and firebaseapp.comonrender.com
# of Team MembersUnlimitedUnlimitedOneOneUnlimitedUnlimited
Team SSO AvailableYesYesYesNot for FreeUnlistedYesNo
# of UsersYesYes1000/site/monthNoNoYesPlanned
User SSO Available[Yes]YesNot for freeNoNoYes
Form Submissions/MonthNoNo100NoYes and NoNoYes - via Formspree integration
AnalyticsNoNot YetNot for freeFree is only good for 1 dayYesYesNo
Split A/B TestingNoNoYesNoNoYesNo
Allowed for Business UseNoYesYesNo for hobbyYesYesYes

Github可以通过同样代码仓库,多个仓库同时部署,不同仓库设置不同的域名来支持多域名!

Tips: Github有每个账户1000个仓库限制,每个仓库大小超过1G,就会被人工审查!所以撸羊毛可以,注意仓库个数和大小限制!

GitHub Pages

  • 优点:简单方便
  • 缺点:国内速度慢,直连CNAME会泄露GitHub用户名,免费版私有仓库无法使用

Netlify

控制台无法访问。

  • 部署方式:GitHub、GitLab、BitBucket仓库自动拉取以及本地CLI直接推送。

  • 速度:较GitHub Pages要快,但是稳定性差上不少,部分时候可能直接出现无法访问。

  • 自定义域名:多个。

  • 限制:
    对于每个账户:

  • 优点:pr单独部署,速度还可以,有免费的serverless
  • 缺点:直连CNAME会泄露分配域名
  • 对比Vercel,Netlify在国内的速度确实要比Vercel慢很多,但前者有许多后者没有的服务或插件,比如Algolia、表单等等

Cloudflare Pages

  • 部署方式:GitHub仓库。

  • 速度:与GitHub Pages相似。

  • 自定义域名:最多10个;

  • 限制:

Vercel

  • 部署方式:与Netlify相同,支持GitHub、GitLab、BitBucket仓库自动拉取以及本地CLI直接推送。

  • 速度:在所有方案中最快且最稳定。

  • 自定义域名:多个。

  • 限制:

    • 每日可构建100次,但每小时不超过32次。
    • 单个Git仓库支持连接3个Vercel项目。
    • 每次构建时长最多45min。每月总计不超过100h。
    • 每月带宽100G。
      详情可见:https://vercel.com/docs/platform/limits
  • 优点:pr单独部署,速度快,CNAME无隐私问题,有免费的serverless
  • 缺点:嗯,免费的能做到这样还指望啥?

Cloudflare CDN

Cloudflare CDN本身并非博客托管服务,但是可以与上文任意一个服务进行搭配。

使用CF CDN时访问速度大多数时候较快,遇高峰期将减速。总体来说速度不如Vercel。稳定性尚可,但曾出现过无法访问的情况。

最主要的是将获得非常多的扩展功能,如HSTS、访问限制,以及HTTP/3等前沿网络技术。他们对IETF的跟进是很快的。同时还会获得DDoS清洗、网站分析等服务。

注意,套上CF CDN之后,可能访问速度会下降,例如Vercel,CF pages

最佳方法是使用Vercel+CF Partner?不过现在能用的CF Partner几乎没有了

gcore CDN

gcore

每月 1000G 免费流量!
免费节点在中国访问速度比 cloudflare 更快

jsDelivr CDN

官网

  • 支持 HTTPS,支持 HTTP2,提供 SRI
  • 网宿、Fastly、Stackpath、Cloudflare Business Plan
  • 非常丰富的国内节点
  • 非常丰富的海外节点
  • 全球的速度都非常优秀
  • cdn.jsdelivr.net,NS1 和 Rage4 主从 DNS
  • 便捷性:★★★★★

jsDelivr 支持从 NPM、GitHub Tag 和 WordPress SVN 上抓取文件并分发,大大降低了开发者使用的难度——直接发个 Release 就可以用了。jsDelivr 每个月会被调用上百亿次,服务 620+ TB 的流量,意味着如果你不是通过 jsDelivr 加载较为热门的库,那么缓存命中率是不会太理想的。

公用库采用jsDelivr加速,自定义修改的js,css使用自己的部署服务

其它CDN测评

VPS

一句话,VPS的超能力就是有钱。配置更好的服务器速度更快,对国内外来说,地理位置最理想的是香港VPS。当然,价格也是相当感人!

  • 优点:钱越多,速度越快。自定义性最高,想做什么服务都可以
  • 缺点:很花钱,网站较大时考虑这个。不够稳定,要稳定性就要多点部署,需要自己维护服务器

RackNerd VPS 推荐

目前个人能找到的最便宜的 VPS 服务商: racknerd VPS

双11,或者6.18 活动价更优惠!几年前买的一个 1核1G 的,一年不到10刀!现在已经绝版了,并且后续每年循环账单续费没有涨价!

如果你发现了更便宜的服务商,务必留言告诉我!

Hexo Docker 本地部署

在最前面的篇章介绍了Hexo Docker 环境的使用方法。具体使用方法见本文系列Hexo Docker 环境篇

优点:本地使用可定制化成都更高

缺点:必须要有Docker 环境。异地使用麻烦,除非ssh,vpn等远程链接方法。

Hexo Docker VPS 部署

和 Hexo Docker 本地部署基本一样,最后反向代理设置域名。

具体参考 Hexo Docker 环境篇

Hexo IPFS 部署

全面拥抱 web 3.0。静态部署 hexo blog!

本节待完善!

4everland

https://4everland.org/

私有部署 IPFS

hexo 插件 hexo-deployer-ipfs

Docker 配置 IPFS

Hexo+IPFS搭建个人免服务器独立博客

Docker linuxserver/ipfs

Docker private-network-ipfs 利用 Docker 搭建 IPFS 私有网络

IPFS在windows平台下的安装与简单使用

Win10 配置IPFS

IPFS是点对点协议InterPlanetary File System的简称,它是一个面向全球的、点对点的分布式版本文件系统,试图将所有具有相同文件系统的计算设备连接在一起。
近日,IFPS宣布了一个未来web发展计划,它用基于内容的地址替代基于域名的地址,也就是用户寻找的不是某个地址而是储存在某个地方的内容,不需要验证发送者的身份,而只需要验证内容的哈希,通过这样可以让网页的速度更快、更安全、更健壮、更持久。IPFS表示,IPFS未来将替代HTTP(以及其他的许多东西)。

2.1 安装IPFS

至官网下载对应版本,一路安装即可,win10系统,下载对应zip解压后,将ipfs.exe添加到%PATH%。
测试是否安装成功:ipfs help
出现 USAGE:
ipfs - Global p2p merkle-dag filesystem.

即可。

2.2 启动本地IPFS节点

第一步:先初始化IPFS
ipfs init
第二部:打开节点
ipfs daemon
此时,你可以在http://localhost:5001/webui,打开自己的操作台。

2.3 将Hexo博客部署到IPFS节点上

Hexo是一个静态博客生成器,执行hexo generate后,会在博客目录生成/Public目录,该目录即为全部博客内容
执行 ipfs add -r public
得到:added QmXJJm7aydK22eF1BdKVozcXH5Ltm8ZwbFHo3c36hi9qUx public
QmXJJm7aydK22eF1BdKVozcXH5Ltm8ZwbFHo3c36hi9qUx即为博客网站的site_hash,你可以通过任意运行IPFS的节点访问,如:http://localhost:8080/ipfs/$SITE_HASH,也可以通过官方运行的节点访问:http://gateway.ipfs.io/ipfs/$SITE_HASH。

2.4 绑定独立域名

刚才,我们通过ipfs add,将博客发布到了IPFS运行的区块链节点上,但复杂的site_hash并不友好,我们可以使用IPNS技术,通过绑定独立域名来实现与现有的网站访问并无任何不一样的体现。我们假设你已经有一个可以正常使用的域名,如aa.com,没有域名的可以到任意域名服务商初购买。
首先,我们将网站发布
执行 ipfs name publish QmXJJm7aydK22eF1BdKVozcXH5Ltm8ZwbFHo3c36hi9qUx
得到 Published to QmV61ui6H9qX3126yGH846dPkMgSe7SZcDxrVwm2gxTidu: /ipfs/QmXJJm7aydK22eF1BdKVozcXH5Ltm8ZwbFHo3c36hi9qUx
记住QmV61ui6H9qX3126yGH846dPkMgSe7SZcDxrVwm2gxTidu为你的peerid,该hash是保持不变的。
那好,我们现在只需要将aa.com解析到上述地址即可,添加TXT记录为dnslink=/ipns/QmV61ui6H9qX3126yGH846dPkMgSe7SZcDxrVwm2gxTidu,同时将域名A记录指向任意ipfs节点的ip,如gateway.ipfs.io
现在访问aa.com,你是不是发现已经可以正常访问你刚才生成的博客了。当然,在没有优化之前,访问会很慢,但可以打开。
由于IPNS还不稳定,你可以在http://ipfs.io/ipfs/QmeaNWtacNyWZxEphYCdVmF6bcMg7Bjn6e5sGdK6fr1nMx 查看本页面。

将Hexo部署到VPS实现自动发布

搭建流程

  1. 服务器环境配置,安装Git、Nginx配置、创建git用户
  2. 本地hexo初始化
  3. 使用Git自动部署并发布博客

服务器环境搭建

  • 安装Git和NodeJS(Centos环境)
yum install git
# 安装NodeJS 
curl --silent --location https://rpm.nodesource.com/setup_5.x | bash -
  • 创建git账号
adduser git
chmod 740 /etc/sudoers
vim /etc/sudoers
  • 添加内容
    找到
## Allow root to run any commands anywhere
root    ALL=(ALL)     ALL
  • 添加以下内容
git     ALL=(ALL)     ALL
  • 保存退出并改回权限
chmod 400 /etc/sudoers
  • 设置git账号密码
sudo passwd git
  • 使用su git切换到git用户,再执行下列操作:
# 切换到git用户目录
cd /home/git
# 创建.ssh文件夹
mkdir ~/.ssh
# 创建authorized_keys文件并编辑
vim ~/.ssh/authorized_keys
# 如果你还没有生成公钥,那么首先在本地电脑中执行 cat ~/.ssh/id_rsa.pub | pbcopy生成公钥
# 再将公钥复制粘贴到authorized_keys
# 保存关闭authorized_keys后,修改相应权限
chmod 600 ~/.ssh/authorized_keys
chmod 700 ~/.ssh
  • 然后可以通过本地Git Bash执行ssh命令测试是否可以免密登录
ssh -v git@服务器ip地址

这样git用户就添加好了。

Tips: 将公钥拷贝到服务器的~/.ssh/authorized_keys文件中方法有如下几种:

  1. 将公钥通过scp拷贝到服务器上,然后追加到~/.ssh/authorized_keys文件中,这种方式比较麻烦。scp -P 22 ~/.ssh/id_rsa.pub user@host:~/。
  2. 通过ssh-copy-id程序,就是我演示的方法,ssh-copyid user@host即可
  3. 可以通过cat ~/.ssh/id_rsa.pub | ssh username@host "mkdir ~/.ssh; cat >> ~/.ssh/authorized_keys",这个也是比较常用的方法,因为可以更改端口号。
  • 安装Nginx
  • 准备工作
    首先由于nginx的一些模块依赖一些lib库,所以在安装nginx之前,必须先安装这些lib库,这些依赖库主要有g++、gcc、openssl-devel、pcre-devel和zlib-devel 所以执行如下命令安装
yum install gcc-c++
yum install pcre pcre-devel
yum install zlib zlib-devel
yum install openssl openssl--devel

Ubuntu系统安装命令如下:

sudo apt-get install libpcre3 libpcre3-dev
sudo apt-get install zlib1g-dev
sudo apt-get install openssl libssl-dev
  • 安装Nginx
    安装之前,最好检查一下是否已经安装有nginx
find -name nginx

如果系统已经安装了nginx,那么就先卸载

yum remove nginx

然后开始安装
首先进入/usr/local目录

cd /usr/local

从官网下载最新版的nginx

wget -c https://nginx.org/download/nginx-1.14.2.tar.gz 

(注:版本号可更改,去官网查看最新版本号修改即可)

解压nginx压缩包

tar -zxvf nginx-1.14.2.tar.gz

会产生一个nginx-1.14.2 目录,这时进入nginx-1.14.2 目录

cd  nginx-1.14.2

接下来安装,使用–prefix参数指定nginx安装的目录,make、make install安装

./configure

(默认安装在/usr/local/nginx,推荐使用默认设置)

make

make install

如果没有报错,顺利完成后,最好看一下nginx的安装目录

whereis nginx

(where和is要连这些,中间没有空格)

  • 启动和停止nginx
cd /usr/local/nginx/sbin/
./nginx 
./nginx -s stop
./nginx -s quit
./nginx -s reload
./nginx -s quit: 此方式停止步骤是待nginx进程处理任务完毕进行停止。
./nginx -s stop: 此方式相当于先查出nginx进程id再使用kill命令强制杀掉进程。

查询nginx进程:

ps aux | grep nginx

  • 重启 nginx
  1. 先停止再启动(推荐):
    对 nginx 进行重启相当于先停止再启动,即先执行停止命令再执行启动命令。如下:
./nginx -s quit
./nginx
  1. 重新加载配置文件:
    当 nginx 的配置文件 nginx.conf 修改后,要想让配置生效需要重启 nginx,使用 -s reload 不用先停止 nginx 再启动 nginx 即可将配置信息在 nginx 中生效,如下:
./nginx -s reload

启动成功后,在浏览器可以看到如下页面:

  • 开机自启动

即在rc.local增加启动代码就可以了。

vim /etc/rc.local

增加一行

/usr/local/nginx/sbin/nginx

到这里,nginx安装完毕,启动、停止、重启操作也都完成。

建立git裸库

# 回到git目录
cd /home/git
# 使用git用户创建git裸仓库,以blog.git为例
git init --bare blog.git

检查用户组权限

我们的git裸仓库已经建立好了,离成功又近了一步。为了以防万一,我们要检查一下之前的blog.git、.ssh、blog目录的用户组权限是否都为git:git

# 还记得/var/www/吗?这是之前配置nginx时,我们自己选定的网站根目录,请依据你自己的设置更改,如果没有的话自己
ll -a /www/wwwroot/hexo
ll -a /home/git/

如果有哪个不是,执行下面相应的命令后再查看

sudo chown -R git:git /www/wwwroot/hexo
sudo chmod -R 755 /www/wwwroot/hexo
sudo chown git:git -R /home/git/blog.git

使用git-hooks同步网站根目录

简单来说,我们使用一个钩子文件:post-receive,每当git仓库接收到内容的时候,就会自动调用这个钩子,把内容同步到网站根目录。
在git用户下执行:

# 新建一个post-receive文件并编辑
vim ~/blog.git/hooks/post-receive

在里面输入以下内容,注意修改为自己的设置:

#!/bin/bash
set -e
GIT_REPO=/home/git/blog.git
TMP_GIT_CLONE=/tmp/blog
PUBLIC_WWW=/www/wwwroot/hexo
rm -rf ${TMP_GIT_CLONE}
git clone -b main $GIT_REPO $TMP_GIT_CLONE
cd $TMP_GIT_CLONE
#for b in `git branch -r | grep -v -- '->'`; do git branch --track ${b##origin/} $b; done
#git checkout main
rm -rf ${PUBLIC_WWW}/*
cp -rf ${TMP_GIT_CLONE}/* ${PUBLIC_WWW}
echo "update web done!"
#ls -al ${PUBLIC_WWW}
rm -rf ${TMP_GIT_CLONE}

保存退出后,执行以下赋予这个文件可执行权限。

chown -R git:git ~/blog.git/hooks/post-receive
chmod +x ~/blog.git/hooks/post-receive

好了,以上就是服务器端需要配置的内容。我们还差最后一步就可以完成整个部署了!

修改配置文件nginx.conf

修改上面的配置文件:

vim /usr/local/nginx/conf/nginx_config

然后修改其中两个部分,如下所示:

然后重启nginx,方法见nginx安装部分。

配置本地Hexo的_config.yml

非常简单,只需要找到本地Hexo博客的站点配置文件_config.yml,找到以下内容并修改:

deploy: 
  type: git
  repo: git@你的服务器IP:/home/git/blog.git
  branch: master

保存后,剩下的就是Hexo的日常操作了,这里就不赘述了,写完文章后,在你的本地博客根目录执行以下命令:

hexo c && hexo g -d

就可以实现线上博客的自动更新了!一切搞定!

webhook部署

adnanh/webhook

上面这个仓库支持在你的VPS 快速建立一个webhook 接口。然后利用 github webhook 通知你的 VPS 来拉取最新的代码部署

对于 webhook 来说,可以自己写一个脚本来接受信息,思路很简单,运行一个 HTTP Server,监听服务器的某个端口,如果有消息传递过来,那么就运行事先写好的脚本,来完成 webhook 的功能即可。

webhook流程

安装 webhook

这里推荐三种安装方法,使用其中一种方法即可,github 下载速度可能很慢,推荐使用系统源安装的方式

法一:使用系统源的安装方式

如果是 Ubuntu 系统,可以直接使用下面的命令进行安装:

$ sudo apt-get update
$ sudo apt-get install webhook

法二:使用 github 下载

webhook 的 release 链接,找到对应的选项 webhook-linux-amd64.tar.gz 右键复制链接 ,当前最新版本链接为

// 下载对应的软件
$ wget https://github.com/adnanh/webhook/releases/download/2.8.1/webhook-linux-amd64.tar.gz
// 解压进入
$ tar -zxf tar -zxf webhook-linux-amd64.tar.gz && cd webhook-linux-amd64/
$ ./webhook

法三:Golang 环境下安装

首先安装 Golang 环境(这里略过),然后安装 webhook,这里注意需要已经设置了 GOPATH

// 安装对应的工具
$ go get github.com/adnanh/webhook
// 安装完成之后可以在 $GOPATH/bin 下找到对应的执行文件
$ echo $GOPATH
/root/go
$ ls /root/go/bin
webhook
// 将路径写入到 shell 可以直接执行
$ vi ~/.bash_profile
// 在文件最后一行加入对应内容
export PATH="/root/go/bin:$PATH"
// 更新文件使其生效
$ source ~/.bash_profile
// 测试命令是否已经成功安装,得到输出说明安装完成
$ webhook

配置 webhook

我们的 hooks.json 文件现在看起来是这样的:

[
  {
    "id": "redeploy-webhook",
    "execute-command": "/var/scripts/redeploy.sh",
    "command-working-directory": "/var/webhook"
  }
]

注意:如果您更喜欢 YAML 格式,等价的 hooks.yaml 文件如下:

- id: redeploy-webhook
  execute-command: "/var/scripts/redeploy.sh"
  command-working-directory: "/var/webhook"

您现在可以使用以下命令运行 webhook:

$ /path/to/webhook -hooks hooks.json -verbose

它将在默认端口 9000 上启动,并为您提供一个 HTTP 终端:

http://yourserver:9000/hooks/redeploy-webhook

更多配置参数

webhook/docs/Webhook-Parameters.md at master · adnanh/webhook (github.com)

Usage of webhook:
  -cert string
        path to the HTTPS certificate pem file (default "cert.pem")
  -cipher-suites string
        comma-separated list of supported TLS cipher suites
  -debug
        show debug output
  -header value
        response header to return, specified in format name=value, use multiple times to set multiple headers
  -hooks value
        path to the json file containing defined hooks the webhook should serve, use multiple times to load from different files
  -hotreload
        watch hooks file for changes and reload them automatically
  -http-methods string
        globally restrict allowed HTTP methods; separate methods with comma
  -ip string
        ip the webhook should serve hooks on (default "0.0.0.0")
  -key string
        path to the HTTPS certificate private key pem file (default "key.pem")
  -list-cipher-suites
        list available TLS cipher suites
  -logfile string
        send log output to a file; implicitly enables verbose logging
  -nopanic
        do not panic if hooks cannot be loaded when webhook is not running in verbose mode
  -pidfile string
        create PID file at the given path
  -port int
        port the webhook should serve hooks on (default 9000)
  -secure
        use HTTPS instead of HTTP
  -setgid int
        set group ID after opening listening port; must be used with setuid
  -setuid int
        set user ID after opening listening port; must be used with setgid
  -template
        parse hooks file as a Go template
  -tls-min-version string
        minimum TLS version (1.0, 1.1, 1.2, 1.3) (default "1.2")
  -urlprefix string
        url prefix to use for served hooks (protocol://yourserver:port/PREFIX/:hook-id) (default "hooks")
  -verbose
        show verbose output
  -version
        display webhook version and quit
  -x-request-id
        use X-Request-Id header, if present, as request ID
  -x-request-id-limit int
        truncate X-Request-Id header to limit; default no limit

实战

# pwd
/www/docker/webhook

# tree .
.
├── bin
│   └── webhook
├── xxx
└── webhook-linux-amd64.tar.gz

2 directories, 2 files

利用 uuidgen 生成随机 ID

# uuidgen
ecbfc10e-6b2d-4d32-98da-bdd2c3c29fc7

hooks.yaml

- id: redeploy-hblog-xxxxx-7e86-4f24-8667-23xxxxxxx1
  execute-command: "/www/docker/webhook/github-webhooks/depHblog.sh"
  command-working-directory: "/www/wwwroot/blog.17lai.site"

depHblog.sh

#!/bin/sh

# 创建临时目录
temp_dir='/www/docker/webhook/tmp/hexoblog'
dst_dir='/www/wwwroot/blog.17lai.site'
repo_url='https://github.com/appotry/hexo.git'
data_dir=''

# 在这里进行你的操作,例如复制文件、下载内容等


# 检查目标目录是否存在 .git 目录
if [ -d "$temp_dir/.git" ]; then
    # 如果存在 .git 目录,则执行 git pull 命令进行更新
    echo "Repository already cloned. Performing git pull..."
    cd "$temp_dir"
    git pull origin main  # 如果使用了默认的主分支名字为 main
    git reset --hard origin/main
else
    # 如果不存在 .git 目录,则执行 git clone 命令进行克隆
    rm $temp_dir -rf
    echo "Cloning repository into $temp_dir..."
    git clone --progress -v --depth 1 "$repo_url" "$temp_dir"
fi


echo "rsync 目录同步"

# -a:表示以归档模式同步,保留文件的所有属性,包括权限、时间戳等。
# -v:表示详细模式,显示同步过程中的详细信息。
# --delete:表示删除目标目录中源目录没有的文件。
rsync --delete -r --exclude='.git' --link-dest="$dst_dir" ${temp_dir}/${data_dir} ${dst_dir}

echo "设置文件权限"
chown www:www ${dst_dir}/${data_dir}  -R

vim depHblog.sh
chmod +x depHblog.sh
curl -X POST https://xxxx.17lai.site/hooks/redeploy-hblog-xxxx8fa-7e86-4f24-8667-23axxxx
# 运行测试
su root

/www/docker/webhook/bin/webhook -hooks /www/docker/webhook/github-webhooks/hooks.json -verbose -port <通信端口>

/www/docker/webhook/bin/webhook -hooks /www/docker/webhook/github-webhooks/hooks.yaml -verbose -port 18xxx

后台运行

nohup webhook -hooks /usr/local/bin/github-webhooks/hooks.json -verbose -port <通信端口> &

反向代理

宝塔面板 go 项目

go project webhook

调用

curl -X POST https://xxx.17lai.site/hooks/redeploy-hblog-xxxa-7e86-4f24-8667-2xxxx3xx

上面命令测试成功之后就可以正式和 github 仓库关联起来了

github webhooks

Rsync同步部署静态文件方法

使用rsync同步

本地生成静态文件后rsync同步到vps网页目录,lnap使用宝塔配置,这里只需要一个nginx。

# rsync [options] from_dir to_dir
# 替换这里的ip为你的服务器ip
rsync -avzP  /home/17lai.blog  root@8.8.8.8:/www/wwwroot/hexo

Hexo Github Action 自动部署

准备

  1. Hexo 博客源码的仓库,在 GitHub 上。
  2. ssh 密钥,参考文章:Windows 下利用 Git 生成 SSH KEY 并配置到 GitHub

步骤

  1. 为需要部署的平台添加密钥
  2. 修改 _config.yml 中的 deploy 配置
  3. 在 GitHub 上设置 Secrets
  4. 创建 GitHub Action

为需要部署的平台添加密钥

按照之前的教程,只要你之前成功将 Hexo 的博客部署到 GitHub 上,那你电脑在 ~/.ssh 目录下一定有以下三个文件:

  • id_rsa:私钥
  • id_rsa.pub:公钥
  • known_hosts:记录对所有用户都可信赖的远程主机的公钥

id_rsa.pub(公钥)添加到不同平台中即可,参考文章:Windows 下利用 Git 生成 SSH KEY 并配置到 GitHub

下面是不同平台添加的地址:

修改 _config.yml 中的 deploy 配置

请使用 ssh (即以 git@ 开头的 clone 链接) 的连接方式,根据直接的实际地址填写。

deploy:
  - type: git
    repo:
      github: git@github.com:Sitoi/Sitoi.github.io.git
      coding: git@e.coding.net:Sitoi/Sitoi.git
      gitee: git@gitee.com:sitoi/sitoi.git
      gitlab: git@gitlab.com:Sitoi/sitoi.gitlab.io.git
    branch: master

在 GitHub 上设置 Secrets

  1. 进入到你在 GitHub 上面的源码仓库

  2. 点击右上角的 Settings

Settings

Settings

  1. 点击左侧的 Secrets

  2. 点击右上角的 New secret

New secret

New secret

  1. Name 中输入 HEXO_DEPLOY_PRI,在 Value 中填入 id_rsa(私钥)的全部内容

Add secret

Add secret

创建 GitHub Action

  1. 点击项目上方的 Action 按钮

Action

Action

  1. 点击 set up a workflow yourself 创建 Workflow

Workflow

Workflow

  1. 修改 main.yaml 的内容

Create Workflow

Create Workflow

根据实际情况修改成你自己的内容

  • Git 推送使用的用户名:git config –global user.name ‘your name’:
  • Git 推送使用的邮箱:git config –global user.email name@email.com
  • Hexo 的版本:npm i hexo@4.1.1 -g
name: Hexo CI

on:
  push:
    branches:
      - butterfly

jobs:
  butterfly-build:

    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [10.x]

    steps:
      - uses: actions/checkout@v1
      - name: Use Node.js 10.x
        uses: actions/setup-node@v1
        with:
          node-version: '10.x'
      - name: env prepare
        env:
          HEXO_DEPLOY_PRI: ${{ secrets.HEXO_DEPLOY_PRI }}
        run: |
          mkdir -p ~/.ssh/
          echo "$HEXO_DEPLOY_PRI" > ~/.ssh/id_rsa
          chmod 600 ~/.ssh/id_rsa
          ssh-keyscan github.com >> ~/.ssh/known_hosts
          ssh-keyscan gitlab.com >> ~/.ssh/known_hosts
          ssh-keyscan e.coding.net >> ~/.ssh/known_hosts
          ssh-keyscan gitee.com >> ~/.ssh/known_hosts
          git config --global user.name 'sito'
          git config --global user.email '133397418@qq.com'
          npm i
          npm i hexo@4.1.1 -g
      - name: gen
        run: |
          hexo clean
          hexo generate
          hexo deploy

下面这个部署脚本功能更加完善,解决了文章更新时间问题

.github/workflows/deploy.yml

name: Hexo Deploy

on:
  push:
    branches:
      - master
  workflow_dispatch:

jobs:
  build:
    permissions:
      contents: write
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 0
      - name: Use Node.js 18
        uses: actions/setup-node@v2
        with:
          node-version: 18
          cache: yarn
      - name: Install Dependencies
        run: yarn install
      - name: Fix File Modify Date
        run: |
          git ls-files | while read filepath; do touch -d "$(git log -1 --format='@%ct' $filepath)" "$filepath" && echo "Fixed: $filepath"; done
      - name: Build Site
        run: |
          export TZ='Asia/Shanghai'
          yarn build
      - name: Deploy to GitHub Pages
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: public
          cname: 17lai.site
      - name: Setup Deploy Private Key
        env:
          HEXO_DEPLOY_KEY: ${{ secrets.HEXO_DEPLOY_KEY }}
        run: |
          mkdir -p ~/.ssh/
          echo "$HEXO_DEPLOY_KEY" > ~/.ssh/id_rsa
          chmod 600 ~/.ssh/id_rsa
          ssh-keyscan blog.17lai.site >> ~/.ssh/known_hosts
      - name: Deploy to VPS
        run: yarn deploy
  1. 将你的源码推送到 GitHub 上,你的博客一会就会自动更新了。

Hexo Gitlab CI/CD自动部署

啥都不说,直接上代码,请参考 Gitlab 官方项目 Gitlab hexo

更多关于 Gitlab CICD 介绍,请看下面文章

CI/CD与Git Flow与GitLab

vercel 部署

jsdelivr被封了,怎么办?vercel 部署可以加速访问

为什么使用 vercel

  • 国内 Github Pages 速度较慢。
  • vercel 速度快且能够自定义域名,能实现和 Github Pages 一样的效果

vercel 官方地址:vercel.com/

如何部署

  • 首先注册一个账号
  • 注册成功后进入页面,点击 News Project

img

  • 然后通过绑定的 github 或者 gitlab 导入需要部署的项目

img

  • 如果导入的项目是打包好的静态页,在 Build and Output Settingsoverride 都勾上,表示不执行它的默认命令。

img

  • 点击 deployed 进行部署,如果部署失败可以查看报错信息是不是上一步的某些选项没有覆盖。部署成功后会进入如图所示的界面

img

如何自定义域名

vercel 自定义域名

  • 下面演示如何自定义域名,默认情况下部署成功后 vercel 会给你生成一个默认的域名,如果想要修改成自己的域名可将域名名称修改成自己的。
  • 当选择修改成自己的域名名称后,vercel 会检查域名指向的 DNS 对不对,如果不对的话会提示你域名的 DNS 应该如何配置,按照 vercel 提示的 DNS 信息

在自己的域名的 DNS 配置中进行配置,如图

img

配置多个域名

对其他新增的域名选择重定向到自己的主域名即可

vercel 多域名配置

自定义Header缓存时间

vercel.com/docs

使用Vercel必备配置,本地缓存加速访问!

vercel.json

{
  "headers": [
    {
      "source": "/sw.js",
      "headers": [
        {
          "key": "Cache-Control",
          "value": "public, max-age=0, must-revalidate"
        }
      ]
    },
    {
      "source": "(.*)",
      "headers": [
        {
          "key": "Cache-Control",
          "value": "public, s-maxage=86400, max-age=86400"
        }
      ]
    }
  ]
}

Vercel自定义404

learn how to customize the 404 page.

cloudflare Pages 部署

jsdelivr被封了,怎么办?cloudflare Pages 部署可以加速访问

强烈推荐!

全球CDN,静态加速,可以说是最佳部署方案!就是有每日100000次请求限制!可以使用dnspod多线路负载均衡来帮助分流。

官网 cloudflare 首先注册一个账号

cloudflare

cloudflare page 连接 github

cloudflare page 选择仓库

cloudflare page 自定义域名

错过了CloudFlare Partner的时代,官方的CloudFlare for SaaS也提供了一种更灵活的CNAME接入方式

https://blog.cloudflare.com/zh-cn/waf-for-saas-zh-cn/

Cloudflare访问速率限制

我们一直不怕网站内容被爬走,但怕服务器被疯狂的爬虫爬垮,所以希望能限制恶意爬虫速度,而又不影响用户访问和搜索引擎爬虫抓取,这是个两难的事情。不过 Cloudflare 提供了 DNS 级别控制的速率限制!

Rate limiting rules 各计划的速率限制额度

计划规则数操作操作持续时间请求期间
免费1阻止1 分钟或 1 小时10 秒钟或 1 分钟
Pro10阻止、旧版 CAPTCHA、JS 质询、托管质询或记录1 分钟或 1 小时10 秒钟或 1 分钟
Business15阻止、旧版 CAPTCHA、JS 质询、托管质询或记录1 分钟、1 小时或 24 小时10 秒钟、1 分钟或 10 分钟
企业100阻止、旧版 CAPTCHA、JS 质询、托管质询或记录可以输入 10 秒到 86400 秒(24 小时)范围内的任何时间长度可以输入 10 秒到 3600 秒(1 小时)范围内的任何值。

设置方法

该功能是防御 CC 强有效的功能,可以从【安全性】-【WAF-】【速率限制规则】进入配置页面。

Cloudflare速率限制设置

针对免费用户来说可以配置的参数比较少,主要实现的是同个 IP(10 秒内请求数>n)时对其返回 429 阻止访问。如图填写 / 可对 zone 下所有域名进行保护,正常情况下 n 建议设置为 50-100,资源更多的站点可以考虑适当放大(以不影响正常访问为准)。

  • 在“安全性” - “WAF” - “防火墙规则”中添加排除跳过速率限制只能老版本的速率限制有效,但新版本的速率限制无效,可以采取在“安全性” - “WAF” - “工具”中添加IP 访问规则,将常见的AS15169(Google)、AS8075(Microsoft)等IP段设置为“允许”,这些IP就不会受到速率限制的影响;
  • 所有版本都在过滤条件中增加了Verified Bot,可以让通过验证的好爬虫跳过速率限制,设置截图如下:

Cloudflare速率限制规则设置

CORS跨域问题

CloudFlare 解决 CORS 跨域问题

cloudflare cors

nginx 解决 CORS

nginx配置文件中添加:

#跨域
add_header 'Access-Control-Allow-Origin' '*'; 
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';
add_header 'Access-Control-Allow-Headers' 'Content-Type';

以 token 方式部署到 Github

deploy:
  type: git
  repo:
    github:
      url: <repository url>
      branch: [branch]
      token: ''
  message: [message]
  name: [git user]
  email: [git email]
  extend_dirs: [extend directory]
  ignore_hidden: false # default is true
  ignore_pattern: regexp  # whatever file that matches the 

travis 自动部署配置

travis是第三方CICD服务,比action更加强大,下面只是参考,请查阅travis 文档,并结合自己的环境修改!

sudo: false
language: node_js
node_js:
- 10.16.3
cache: npm
branches:
  only:
  - master # build master branch only

env:
  global:
  - GIT_USER: appotry
  - HEXO_BACKUP_REPO: github.com/appotry/hexo-backup.git
  - HEXO_THEME_REPO: github.com/appotry/hexo-theme-matery.git
  - GITHUB_PAGES_REPO: github.com/appotry/hexo.github.io.git
  - APPOTRY_REPO: github.com/appotry/hexo.git

before_install:
- export TZ='Asia/Shanghai'
- npm install hexo -g
- npm install gulp-cli -g

install:
- npm install

script:
- git clone https://${HEXO_THEME_REPO} themes/next
- git clone https://${GIT_USER}:${GITHUB_TOKEN}@${HEXO_BACKUP_REPO} hexo-backup
- mv hexo-backup/source .
- rm -rf source/private
- npm run build

after_success:
- git config --global user.name "appotry"
- git config --global user.email "email@qq.com"
- git clone https://${GIT_USER}:${GITHUB_TOKEN}@${GITHUB_PAGES_REPO} voidking
- unalias cp
- cp -rf public/. 17lai.blog
- cd 17lai.blog
- git add .
- git commit -m "Travis CI Auto Builder"
- git push --force --quiet "https://${GIT_USER}:${GITHUB_TOKEN}@${GITHUB_PAGES_REPO}" master:master

利用 GitLab 实现 Hexo 博客的 CI/CD

Portainer 提供了对服务在线更新的 WebHook,所以基于 GitLab 自带的 CI/CD 功能实现 Hexo 博客的持续部署,就非常轻松了。

CI/CD 其实本质上是一套流程,流程规则可以自行定义。在本文研究的主题下,流程分为三步:第一步是编译 Hexo 博客并生成静态文件;第二步是将静态文件打包成可提供 Web 服务的镜像;第三步则是通过 Portainer 的钩子触发服务更新。

.gitlab-ci.yml

stages:
  - compile
  - build
  - deploy

# CONTAINER_RELEASE_IMAGE 根据自己的仓库名修改
variables:
  DOCKER_HOST: tcp://docker:2375
  DOCKER_DRIVER: overlay2
  CONTAINER_RELEASE_IMAGE: registry.gitlab.com/xxx/xxx:latest

compile:
  stage: compile
  image: node:lts-alpine
  script:
    - npm install
    - ./node_modules/hexo/bin/hexo generate
  artifacts:
    paths:
      - public/
    expire_in: 20 minutes

build:
  stage: build
  image: docker:stable
  services:
    - docker:dind
  script:
    - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN registry.gitlab.com
    - docker info
    - docker build -f ./Dockerfile -t $CONTAINER_RELEASE_IMAGE public
    - docker push $CONTAINER_RELEASE_IMAGE

# 根据自己的钩子修改下方的 URL
deploy:
  stage: deploy
  script:
    - curl https://xxx.xxx.xxx/api/webhooks/xxx -X POST

为了保证服务更新的成功率,可以在 deploy 环节加个错误判断和重试次数,具体的看 GitLab 官方文档即可。

下面给出我的 Dockerfile 文件,供参考。

FROM nginx:alpine

COPY . /usr/share/nginx/html

RUN chmod 777 /usr/share/nginx/html -R \
    && sed -i 's/#error_page  404/error_page  404/' /etc/nginx/conf.d/default.conf

部署图床

有很多上传图片的方法,如果使用第三方服务,不知道什么时候就跑路了。所以还是自己部署图床比较稳妥

github pages

使用git 管理图片仓库。picgo + github 上传,保存图片,github pages 或者 vercel,netlify,cloudflare pages来作为网络访问。

vercel 托管github上面的图片仓库。 每月免费100G流量。 还有netlify托管,github托管,都有每月免费100G流量使用dns分流,采用DNS 权重自动分流每月就有300G免费流量了。

300G流量,足够每天几千PV访问量了

npm托管

还有一个完全不要钱的方案。图片使用npm包管理,上传到npm仓库,各个npm镜像仓库就都是你的图床了。没有流量限制,就怕什么时候npm封闭你的账号 O(∩_∩)O哈哈~

本文假设您已有 NPM 账号、GitHub 账号。

下面是一个使用GithubAction和NPM搭建自动转换webp图床的完整教程

准备工作

新建仓库

新建一个 GitHub 仓库,公开或是私人都可以,此处不再赘述。

在 Git 仓库中新建 rawimg/.gitkeepwebpimg/.gitkeep 两个文件。

获取令牌

登录 https://npmjs.com ,点击右上角的头像,进入 Access Token

img

点击页面中的 Generate New Token 获取新的令牌。

img

选择 Automation,点击 Generate Token 生成令牌。

img

将生成的令牌复制下来。

进入 GitHub 仓库,点击 Settings

img

点击菜单栏中的 Secrets

img

点击 New repository secret 新建一个 Secret。

img

Secret Name 为 NPM_TOKEN,Value 是你的 NPM 令牌,点击 Add secret 添加。

img

在仓库中新建 package.json 文件,参考如下:

{
  "name": "ocoke-osg",
  "version": "0.0.0",
  "description": "Somewhere to save the file from @oCoke",
  "author": "YFun(@oCoke)"
}

图片转换与发布

为了方便多端写作,我使用 GitHub 临时存储所需的图片,GitHub Action 发布 NPM 包。

WebP 可以大大缩减图片的尺寸,我们还可以借助 GitHub Action 在发布前自动转换。

name: NPM & WebP

# 在 Release 发布时 或手动执行

on:
  release:
     types:
       - published

  workflow_dispatch:

jobs:
  publish-npm:
    runs-on: ubuntu-latest
    # Clone 仓库
    steps:
      - name: Checkout
        uses: actions/checkout@v2
        with:
          ref: master
      # 安装 Node.js    
      - name: Setup Node
        uses: actions/setup-node@v1
        with:
          node-version: "12.x"
          registry-url: https://registry.npmjs.org/
        
      # rawimg/ 作为原始图片存储,webpimg/ 作为压缩图片存储处,最后合并。
      # 安装相关插件,转换图片。
      - name: Install & Convert
        run: |
          npm install -g webp-batch-convert
          cwebp-batch --in rawimg --out webpimg -q 75 -quiet
          mv webpimg/*.webp rawimg/
          
      # 发布 NPM 包
      - name: Publish Package
        run: |
          git config --global user.email "icolabot@e.yfun.top"
          git config --global user.name "iColaBot"
          npm version patch
          npm publish
        env:
          NODE_AUTH_TOKEN: ${{secrets.npm_token}}
          
      # 删除 rawimg/ 和 webpimg/ 下的所有文件
      - name: Delete Files
        run: |
          rm -rf webpimg/*
          rm -rf rawimg/*
          touch webpimg/.gitkeep
          touch rawimg/.gitkeep
          
      - name: Push
        run: |
          git add -A
          git commit -m "Publish"
          git push origin master

使用

上传

将图片文件上传至仓库的 rawimg/ 文件夹下即可。

当然也可以使用 PicGo / UPic / HexoPlusPlus 等工具上传。

发布

在 GitHub 中新建 Release,将自动修改版本号并发布 NPM 包,无需手动修改 package.json

img

img

访问

推荐的镜像
https://cdn.jsdelivr.net/npm/  # jsDelivr
https://unpkg.zhimg.com/ # 知乎
https://code.bdstatic.com/npm/ # 百度 (不推荐)
https://shadow.elemecdn.com/npm/ # 饿了么
https://unpkg.com/ # Unpkg

镜像推荐选择访问速度快的,比较稳定的,拉取速度快的。

我选择的是 jsDelivr,国内外速度都很优秀。

链接

以 jsDelivr 为例,原图链接为:

https://cdn.jsdelivr.net/npm/[package-name]@[version]/rawimg/[filename].[suffix]

WebP 图片链接为:

https://cdn.jsdelivr.net/npm/[package-name]@[version]/rawimg/[filename].webp
[值]说明
package-nameNPM 包的名称 (package.json 文件中 name 的值)
version当前版本 (package.json 文件中 version 的值,通常需要在发布 Release 1 分钟后更新)
filename文件名
suffix文件后缀名

vps自建图床

lychee , chevereto 等免费图床工具有很多。就是需要自己配置vps

下面是一个 docker compose 创建Lychee图床的示例

version: "3"
services:
  mariadb:
    image: lscr.io/linuxserver/mariadb:latest
    container_name: lychee_mariadb
    restart: always
    volumes:
      - /path/to/mariadb/data:/config
    environment:
      - MYSQL_ROOT_PASSWORD=rootpassword
      - MYSQL_DATABASE=lychee
      - MYSQL_USER=lychee
      - MYSQL_PASSWORD=dbpassword
      - PGID=1000
      - PUID=1000
      - TZ=Europe/London
  lychee:
    image: lscr.io/linuxserver/lychee:latest
    container_name: lychee
    restart: always
    depends_on:
      - mariadb
    volumes:
      - /path/to/config:/config
      - /path/to/pictures:/pictures
    environment:
      - DB_CONNECTION=mysql
      - DB_HOST=mariadb
      - DB_PORT=3306
      - DB_USERNAME=lychee
      - DB_PASSWORD=dbpassword
      - DB_DATABASE=lychee
      - PGID=1000
      - PUID=1000
      - TZ=Europe/London
    ports:
      - 80:80

DNSPOD 多线路负载均衡

DNSPOD官网 console.dnspod.cn

dnspod

dnspod 多线路负载均衡

dnspod对cname数目有限制。

这里使用权重来分配各条线路访问比例!

乒乓部署

也可以叫旋转门部署。

解决调试博客插件,修改半成品文章时部署到云端会影响正在查阅博客的用户的问题!

使用Docker版本本地预览是很不错,但是 jsdelivr 版本发布需要在 Github 生成新 release 这时本地就不行了。乒乓部署可以解决这个问题!

具体方法就是同时部署到两个地方A和B,博客域名在两个服务器之间切换。这里以 Vercel 为例

准备工作:

  • 创建2个Github仓库,对应服务器A和B的部署
  • 建立两个服务器A和B,分别关联两个 Github 仓库
  • 把调试完毕的代码上传到两个仓库
  • 这时通过服务器A和B都是可以正常浏览的

要调试的时候:

  • 发布到A之前,把博客域名转移到服务器B
  • 在服务A做一些调试,在线 debug 工作
  • 特别是在线 pageseed 测试调优,这种事必备方法。简单不需要新的 jsdelivr 版本调试本地 docker-hexo 调试即可!

输入想转移的域名

点击确认转移域名

调试完毕后:

  • 把域名切换到服务器A
  • 同时部署到服务器B,服务器B同步A的部署内容,以便下次备用

总结就是服务器A现行,服务器B做后备,调试发布使用A,调试A的时候B就顶上前台!

这样,调试和正常部署网络服务两不误。是不是感觉自己是个大聪明!

本教程还有其它五大部分,更多内容请见Hexo系列教程

系列教程

全部文章RSS订阅

Hexo系列

HexoRSS分类订阅

[三万字教程]基于Hexo的matery主题搭建博客并深度优化完全一站式教程

  • markdown 各种其它语法插件,latex公式支持,mermaid图表,plant uml图表,URL卡片,bilibili卡片,github卡片,豆瓣卡片,插入音乐和视频,插入脑图,插入PDF,嵌入iframe

笔记系列

Note分类RSS订阅

Gitbook使用系列

Gitbook分类RSS订阅

Gitlab 使用系列

Gitlab RSS 分类订阅


作者: 夜法之书
版权声明: 本博客所有文章除特別声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 夜法之书 !
评论
数据加载中 ...
 上一篇

阅读全文

基于Hexo的matery主题搭建博客个性定制篇5
基于Hexo的matery主题搭建博客个性定制篇5 基于Hexo的matery主题搭建博客个性定制篇5
我想对我的博客进行各种个性定制,增加各种额外功能,评论邮件提醒,个人相册,图片懒加载,看板娘,黑暗模式等等,在这里啥都有
2022-03-27
下一篇 

阅读全文

基于Hexo的matery主题搭建博客网络优化篇3
基于Hexo的matery主题搭建博客网络优化篇3 基于Hexo的matery主题搭建博客网络优化篇3
有了一个独立博客后,访问速度很忙怎么办?这时候你需要上各种各样的优化手段了,比喻CDN,service worker,页面压缩技术,SEO优化等等。
2022-03-27
  目录