hexo部署到阿里云

服务器Nginx配置

登录到Centos系统root用户。

安装 Git Nginx

1
yum install -y git nginx

Nginx 配置(创建文件目录, 用于博客站点文件存放):

1
2
3
cd /usr/local/
mkdir pub
chmod 775 -R /usr/local/pub/

添加 index.html,用于检测配置 Nginx 是否成功:

1
vi /usr/local/pub/index.html

添加如下代码并保存:

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="UTF-8">
</head>
<body>
<p>Nginx running</p>
</body>
</html>

配置 Nginx 服务器:

1
vi /etc/nginx/nginx.conf

修改server_name和root:

1
2
3
4
5
6
7
8
......
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name www.xxx.com; # 填写个人域名
root /usr/local/pub/;
}
......

启动nginx服务:

1
service nginx start

注意,若你服务器已有了Apache,则需要先停止Apache:

1
/usr/local/apache/bin/apachectl stop

启动浏览器输入云服务器的个人域名或者IP,查看是否呈现index.html内容。

注意每次更改完nginx.conf后,要重启nginx:systemctl restart nginx

服务器Git配置

这部分的作用为建立一个叫做pub.git的裸库,每次使用hexo d命令推送到阿里云的时候,首先先推送到这个裸库,然后使用hook将网站部署到/usr/local/pub目录。

创建文件目录, 用于私人 Git 仓库搭建, 并更改目录读写权限。

1
2
3
cd /usr/local/
mkdir blogRepo
chmod 775 -R /usr/local/blogRepo/

Git 初始化裸库。

1
2
cd blogRepo/
git init --bare pub.git

创建 Git 钩子(hook)。

1
vi /usr/local/blogRepo/pub.git/hooks/post-receive

输入以下信息,用于指定 Git 的源代码 和 Git 配置文件。

1
2
#!/bin/bash
git --work-tree=/usr/local/pub --git-dir=/usr/local/blogRepo/pub.git checkout -f

—work-tree命令将—git-dir下的commit复制到—work-tree目录,此时可以看到很多提示信息,意思是/usr/local/pub/usr/local/blogRepo/pub.git相比很多文件缺失。使用checkout -f强制checkout。

保存并退出后, 给该文件添加可执行权限。

1
chmod +x /usr/local/blogRepo/pub.git/hooks/post-receive

管理公钥

因为我是在root账户下搭建的git服务器,且一般只有我自己使用,所以管理公钥比较简单。

首先,在本地客户端,使用cat ~/.ssh/id_rsa.pub指令查看本地的公钥。然后复制全部内容到服务器端/root/.ssh/authorized_keys文件中,设置/etc/ssh/sshd_config中设置PasswordAuthentication yes

这样,下次git push或者hexo d到阿里云的时候,就不需要输入root账户的密码了。

本地Hexo配置

修改 Hexo 博客站点配置文件_config.yml

1
2
3
4
deploy:
- type: git
repository: root@47.103.17.102:/usr/local/blogRepo/pub
branch: master

这样我们每次使用hexo d指令的时候,就会推动到阿里云了。值得注意的是,第一次推送的时候可能因为网站较大,所以推送速度慢,需要耐心等待。

nginx开机自启

但是,阿里云默认开机自启动Apache,但是没有自启动nginx,提交工单后发现,客服说:/etc/rc3.d/S85apachectl 这个是您主机Apache的开机自动启动脚本文件,您将其删除或者移动到其他目录下。

在/etc/init.d/下新建nginx文件并在其中写入脚本。官方脚本地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#!/bin/sh
#
# nginx - this script starts and stops the nginx daemon
#
# chkconfig: - 85 15
# description: NGINX is an HTTP(S) server, HTTP(S) reverse \
# proxy and IMAP/POP3 proxy server
# processname: nginx
# config: /etc/nginx/nginx.conf
# config: /etc/sysconfig/nginx
# pidfile: /var/run/nginx.pid

# Source function library.
. /etc/rc.d/init.d/functions

# Source networking configuration.
. /etc/sysconfig/network

# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0

nginx="/usr/sbin/nginx"
prog=$(basename $nginx)

NGINX_CONF_FILE="/etc/nginx/nginx.conf"

[ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx

lockfile=/var/lock/subsys/nginx

make_dirs() {
# make required directories
user=`$nginx -V 2>&1 | grep "configure arguments:.*--user=" | sed 's/[^*]*--user=\([^ ]*\).*/\1/g' -`
if [ -n "$user" ]; then
if [ -z "`grep $user /etc/passwd`" ]; then
useradd -M -s /bin/nologin $user
fi
options=`$nginx -V 2>&1 | grep 'configure arguments:'`
for opt in $options; do
if [ `echo $opt | grep '.*-temp-path'` ]; then
value=`echo $opt | cut -d "=" -f 2`
if [ ! -d "$value" ]; then
# echo "creating" $value
mkdir -p $value && chown -R $user $value
fi
fi
done
fi
}

start() {
[ -x $nginx ] || exit 5
[ -f $NGINX_CONF_FILE ] || exit 6
make_dirs
echo -n $"Starting $prog: "
daemon $nginx -c $NGINX_CONF_FILE
retval=$?
echo
[ $retval -eq 0 ] && touch $lockfile
return $retval
}

stop() {
echo -n $"Stopping $prog: "
killproc $prog -QUIT
retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile
return $retval
}

restart() {
configtest || return $?
stop
sleep 1
start
}

reload() {
configtest || return $?
echo -n $"Reloading $prog: "
killproc $nginx -HUP
RETVAL=$?
echo
}

force_reload() {
restart
}

configtest() {
$nginx -t -c $NGINX_CONF_FILE
}

rh_status() {
status $prog
}

rh_status_q() {
rh_status >/dev/null 2>&1
}

case "$1" in
start)
rh_status_q && exit 0
$1
;;
stop)
rh_status_q || exit 0
$1
;;
restart|configtest)
$1
;;
reload)
rh_status_q || exit 7
$1
;;
force-reload)
force_reload
;;
status)
rh_status
;;
condrestart|try-restart)
rh_status_q || exit 0
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
exit 2
esac

然后修改2处(我们这里不需要修改):

1
2
nginx="/usr/sbin/nginx" #改为nginx安装路径下的命令执行处
NGINX_CONF_FILE="/etc/nginx/nginx.conf" #改为nginx配置文件位置路径

给文件添加可执行权限:

1
chmod a+x /etc/init.d/nginx

然后可以通过/etc/init.d/nginx操作nginx了:

1
2
/etc/init.d/nginx start
/etc/init.d/nginx restart

进行chkconfig操作

1
chkconfig --add /etc/init.d/nginx

之后可以通过service命令操作nginx了:

1
service nginx restart

最后设置开机启动:

1
chkconfig nginx on

源文件备份

服务器配置

之前的文章中介绍了怎么备份网站源文件到github,但是最近因为某些原因,github已经墙了某些国家,所以怎么备份源文件到阿里云服务器呢?毕竟不用白不用。

需要注意的是,在我的本地仓库中,网站的分支为master,而博客源文件的分支为hexo。

首先,在服务器端建立文件夹。

1
2
3
cd /usr/local/
mkdir hexo
chmod 775 -R /usr/local/hexo/

Git 初始化裸库。裸仓库没有工作区,因为服务器上的Git仓库纯粹是为了共享,所以不让用户直接登录到服务器上去改工作区,并且服务器上的Git仓库通常都以.git结尾

1
2
cd /usr/local/blogRepo/
git init --bare hexo.git

下面的操作可以不做,可以让服务端/usr/local/hexo目录看到该分支的提交结果,不影响你git clone到本地的操作。

创建 Git 钩子(hook)。

1
vi /usr/local/blogRepo/hexo.git/hooks/post-receive

输入以下信息,用于指定 Git 的源代码 和 Git 配置文件。

1
2
#!/bin/bash
git --work-tree=/usr/local/hexo --git-dir=/usr/local/blogRepo/hexo.git checkout -f hexo

保存并退出后, 给该文件添加可执行权限。

1
chmod +x /usr/local/blogRepo/hexo.git/hooks/post-receive

若要单独执行这句话,可以改文件,只需要在终端输入下面语句即可。

1
/usr/local/blogRepo/hexo.git/hooks/post-receive

本地配置

回到本地的仓库,执行git remote -v查看远程库信息,返回如下:

1
2
origin    git@github.com:zdaiot/zdaiot.github.io.git (fetch)
origin git@github.com:zdaiot/zdaiot.github.io.git (push)

先删除已关联的名为origin的远程库。关联GitHub的远程库,注意,远程库的名称叫github,不叫origin了。关联阿里云的远程库,名字为aliyun

1
2
3
git remote rm origin
git remote add github git@github.com:zdaiot/zdaiot.github.io.git
git remote add aliyun root@47.103.17.102:/usr/local/blogRepo/hexo.git

执行git remote -v查看远程库信息,返回如下:

1
2
3
4
aliyun    root@47.103.17.102:/usr/local/blogRepo/hexo.git (fetch)
aliyun root@47.103.17.102:/usr/local/blogRepo/hexo.git (push)
github git@github.com:zdaiot/zdaiot.github.io.git (fetch)
github git@github.com:zdaiot/zdaiot.github.io.git (push)

此时,使用下面指令推送到github仓库。

1
git push github hexo

使用下面指令推送到aliyun仓库。

1
git push aliyun hexo

在另外一个位置,从阿里云上git clone下来,即可验证是否成功了。

1
2
git clone root@47.103.17.102:/usr/local/blogRepo/hexo.git
git checkout hexo

主题文件备份

之前的文章中介绍了怎么主题文件到github,但是最近因为某些原因,github已经墙了某些国家,所以怎么备份源文件到阿里云服务器呢?毕竟不用白不用。

这里我的主题为next主题,我的github账户名为zdaiot

服务器配置

首先,在服务器端建立文件夹。

1
2
3
cd /usr/local/
mkdir next
chmod 775 -R /usr/local/next/

Git 初始化裸库。裸仓库没有工作区,因为服务器上的Git仓库纯粹是为了共享,所以不让用户直接登录到服务器上去改工作区,并且服务器上的Git仓库通常都以.git结尾

1
2
cd /usr/local/blogRepo/
git init --bare next.git

下面的操作可以不做,可以让服务端/usr/local/next目录看到该分支的提交结果,不影响你git clone到本地的操作。

创建 Git 钩子(hook)。

1
vi /usr/local/blogRepo/next.git/hooks/post-receive

输入以下信息,用于指定 Git 的源代码 和 Git 配置文件。

1
2
#!/bin/bash
git --work-tree=/usr/local/next --git-dir=/usr/local/blogRepo/next.git checkout -f

保存并退出后, 给该文件添加可执行权限。

1
chmod +x /usr/local/blogRepo/next.git/hooks/post-receive

若要单独执行这句话,可以改文件,只需要在终端输入下面语句即可。

1
/usr/local/blogRepo/next.git/hooks/post-receive

本地配置

回到本地的仓库,执行下面语句查看远程库信息

1
2
cd themes/next/
git remote -v

返回如下:

1
2
origin    git@github.com:zdaiot/hexo-theme-next.git (fetch)
origin git@github.com:zdaiot/hexo-theme-next.git (push)

不同于之前我们的源文件备份要删除origin,这里因为主题是整个博客的子模块,我们不想删除这个,实现github的zdaiot/zdaiot.github.io/hexo/themes/next指向的是zdaiot/hexo-theme-next最新版本。

1
git remote add aliyun root@47.103.17.102:/usr/local/blogRepo/next.git

执行git remote -v查看远程库信息,返回如下:

1
2
3
4
aliyun    root@47.103.17.102:/usr/local/blogRepo/next.git (fetch)
aliyun root@47.103.17.102:/usr/local/blogRepo/next.git (push)
origin git@github.com:zdaiot/hexo-theme-next.git (fetch)
origin git@github.com:zdaiot/hexo-theme-next.git (push)

此时,使用下面指令推送到github仓库。

1
git push origin master

使用下面指令推送到aliyun仓库。

1
git push aliyun master

在另外一个位置,从阿里云上git clone下来,即可验证是否成功了。

1
git clone root@47.103.17.102:/usr/local/blogRepo/next.git

另外,在还原整个网站的时候,当使用github上的仓库时,需要执行:

1
git submodule add --name origin git@github.com:zdaiot/hexo-theme-next.git themes/next

为了方便,我们可以在客户端.bashrc文件中添加下面两句话:

1
2
3
alias hexopub='hexo g && gulp && hexo d'
alias hexotheme='git push origin master && git push aliyun master'
alias hexoblog='git push github hexo && git push aliyun hexo'

域名配置

解析配置

首先,说下背景,我的域名www.zdaiot.com是在腾讯云购买的,但是现在服务器是在阿里云上的,所以就需要在阿里云上备案或者接入备案,否则的话无法解析。另外,需要在阿里云服务器控制台->站点设置->域名添加域名并按照提示在腾讯云域名解析处添加DNS认证,如下图所示:

1568644502966

然后,在腾讯云域名解析处设置解析到该服务器的IP地址即可。

HTTPS开启

之前,当我的域名解析到github pages的时候,是默认支持https,但是域名解析到阿里云的时候,不支持了。

这里我在阿里云控制台首页->资源监控->安全预警->SSL证书->去配置处,购买了一年的免费SSL证书(没想到收费的SSL证书那么贵)。然后回到阿里云服务器控制台->站点设置->域名处,将域名的HTTPS证书绑定刚才的证书即可。

这里还有最后一步,要在阿里云控制台首页->资源监控->安全预警->SSL证书->去配置处,找到已经签发的证书,点击下载证书->Nginx类型。如下图所示:

1568645067381

然后,找到/etc/nginx/目录,新建cert文件夹,将下载的SSL证书上传到该文件夹。注意这里证书有两个文件,一个是.pem文件,一个是.key文件。然后打开/etc/nginx/nginx.conf文件,找到里面Settings for a TLS enabled server相关设置,取消注释,并设置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
server {
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
server_name _;
root /usr/local/pub/; # nginx解析目录

ssl_certificate "cert/2816260_www.zdaiot.com.pem"; # 自己的pem文件名
ssl_certificate_key "cert/2816260_www.zdaiot.com.key"; # 自己的key文件名
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;

# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;

location / {
}

error_page 404 /404.html;
location = /40x.html {
}

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

(可选步骤)设置http请求自动跳转https。在需要跳转的http站点下添加以下rewrite语句,实现http访问自动跳转到https页面。例如我这里http配置为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
rewrite ^(.*)$ https://$host$1 permanent;
root /usr/local/pub/;

# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;

location / {
}

error_page 404 /404.html;
location = /40x.html {
}

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

然后,重启nginx服务器:service nginx restart

这里还有一个小细节,我们的版权声明链接还是http连接,需要在博客根目录下的_config.yml文件中设置url: https://www.zdaiot.com而不是url: http://www.zdaiot.com

问题

在使用VScode的远程调试功能后,保持默认配置会在/home/user/.ssh下面建立一个config文件,该文件内容为:

1
2
3
4
Host 47.103.17.102
HostName 47.103.17.102
Port 7009
User lab3

这个时候,如果你再使用上面的hexoblog命令更新博客时,会让你输入密码。此时就算你输入密码也是不对的,最终会提示你Permission denied (publickey,password).。解决方法为将该文件删除。下次使用VScode调试时换一个位置保存配置文件。

参考

利用云服务器搭架Hexo个人博客
Centos下设置Nginx开机启动
使用码云
搭建Git服务器
在Nginx/Tengine服务器上安装证书
github提示Permission denied (publickey),如何才能解决? - ElonChan的回答 - 知乎

------ 本文结束------
坚持原创技术分享,您的支持将鼓励我继续创作!

欢迎关注我的其它发布渠道