我是想要在腾讯云上搭建一个基于hexo的个人博客,但是确实踩了不少坑,所以把经历记录下来,方便后人参考
前情提要,如果无特殊说明,本文中的./路径指的是hexo的根目录,我自己创建的blog文件夹
本地环境配置
首先是本地环境配置,在node.js官网上下载node.js并且安装,安装后在shell中测试是否安装成功:
注意一个惨痛的教训,一定要使用稳定版的node.js
node -v
npm -v
如果这两个命令能正确的返回版本号,则表示已经配置完成
然后安装淘宝的cnpm源,避免某个墙的影响
可以使用nrm来进行npm源的管理
sudo npm install -g nrm
记得一定要用sudo加权,因为这个些个内容的安装并非在用户目录下修改用了-g参数,表示为全局安装。
nrm ls # 查看所有源
切换镜像源nrm use <镜像名>
nrm use taobao
如果要添加一个私有源地址nrm add <镜像名> <镜像地址>
测试镜像速度:nrm test <镜像名>
然后通过npm安装hexo
sudo npm install -g hexo-cli
同样可以通过hexo -v来验证安装是否成功
还可以使用nrm来进行管理npm源文件,比上述的更好一点,方法如下
然后找一个合适的地方放置自己的博客资源,我选择的路径是/Users/xzl/Documents/blog下,cd到这个目录,然后执行初始化命令:(blog文件夹是我自己新建的)
hexo init
hexo的四个命令为:
hexo new“file name” # 创建一个新的博文
hexo g # 生成博客资源
hexo s # 本地展示博客资源 地址是 localhost:4000
hexo d # 部署博客
然后就开始尝试导入一个我自己的博客:
hexo new"优先队列"
可以看到在/Users/xzl/Documents/Blog/source/_posts的位置看到我新建的md文件,然后我把我之前写的内容导入进去保存,并且本地展示:
hexo g
hexo s
发现现在有的问题就是我没有能识别Latex表达式支持,在后面我们为其安装支持
主题安装
可以在网上下载自己喜欢的主题,然后解压复制到./themes目录下,同时修改主题名,去掉版本号和master后缀。最后修改./_config.yml文件将主题更换为themes下的主题文件夹名:
# Extensions
## Plugins: https://hexo.io/plugins/
## Themes: https://hexo.io/themes/
theme: icarus
然后在shell中执行
hexo g
理论上会有报错,提醒某些资源没有安装,复制给出的建议命令,执行即可
切换markdown渲染引擎 支持LaTeX表达式渲染
很显然不支持LaTeX表达式渲染,对于博客来说是很致命的,所以要先要切换hexo的渲染引擎为hexi-renderer-karmed,步骤如下
安装Kramed
npm uninstall hexo-renderer-marked --save
npm install hexo-renderer-kramed --save
修改引擎转译bug:修改文件./node_modules/kramed/lib/rules/inline.js相对路径,以blog文件夹作为起点。
vim inline.js
// escape: /^\([\`*{}[]()#$+-.!_>])/,
escape: /^\([`*[]()#$+-.!_>])/,
// em: /^\b_((?:__|[\s\S])+?)_\b|^*((?:**|[\s\S])+?)*(?!*)/,
em: /^*((?:**|[\s\S])+?)*(?!*)/,
修改两行的内容,保存退出
添加mathjax的支持
卸载hexo-math
npm uninstall hexo-math --save
安装mathjax
npm install hexo-renderer-mathjax --save
修改主题的_config.yml ,这里请注意,有的主题的设置文件是在主题文件夹内,比如next主题的设置文件就在./thme/next文件夹内,也有的主题的设置文件在博客目录下,可以是_config.<主题名>.yml
# MathJax Support
mathjax:
enable: true
per_page: true
对博文进行修改
在博客的文章开头加入一行
mathjax:true
重启hexo
hexo clean && hexo g -d
云服务器配置
云服务我是基于centos8.2 yum包管理器进行配置,不再赘述Ubuntu相关内容。
ssh链接云服务器
首先在服务器控制台重置服务器密码,然后使用finalshell或者其他ssh软件,ssh链接到服务器。如果这都不会请Google一下
更新服务器内容
yum update -y
这纯属习惯性手贱
安装node.js
进入nodejs下载页面,选择lts版本Linux二进制文件(x64)然后复制下载链接
在服务器上转到要下载的目录:
cd /usr/local/src/
下载nodejs文件
wget https://nodejs.org/dist/v14.17.5/node-v14.17.5-linux-x64.tar.xz
解压文件
tar -xvf node-v14.17.5-linux-x64.tar.xz
对解压缩后的文件重命名
mv node-v14.17.5-linux-x64 node
删除下载的压缩包
rm node-v14.17.5-linux-x64.tar.xz
设置全局变量
vim ~/.bash_profile
在PATH变量后加上
PATH=$PATH:$HOME/bin:/usr/local/src/node/bin
刷新
source ~/.bash_profile
安装nrm
上面本地化设置里面已经说过了,就不再赘述
切换到taobao源
nrm use taobao
安装git
yum install git
安装hexo
npm install -g hexo-cli
验证
hexo -v
如果返回了版本号则说明安装成功
安装nginx
首先要安装编译所需依赖
yum install -y gc gcc gcc-c++
yum install -y pcre-devel zlib-devel openssl-devel libxslt-devel GeoIP-devel perl-ExtUtils-Embed
然后我去往我想把Nginx放置的目录/usr/local/src
wget http://nginx.org/download/nginx-1.20.1.tar.gz
tar -xf nginx-1.20.1.tar.gz
下载并且解压,进入解压后的目录
./configure --prefix=/usr/local/src/nginx --with-file-aio --with-http_auth_request_module --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module=dynamic --with-http_geoip_module=dynamic --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module --with-http_stub_status_module --with-http_perl_module=dynamic --with-pcre --with-pcre-jit --with-stream=dynamic --with-stream_ssl_module
make编译
make
安装
make install
修改环境变量
vim /etc/profile
在环境变量中添加
PATH=$PATH:/usr/local/src/nginx/sbin
export PATH
刷新环境变量
source /etc/profile
新建一个git用户
useradd -m git
设置密码
passwd git
输入两次相同的密码后就更改完成了
更改新用户的权限
更改文件权限
chomd -v u+w /etc/sudoers
vim /etc/sudos
找到## Allow root to run any commands anywhere的下面,在root ALL=(ALL) ALL下添加一行
git ALL=(ALL) ALL
注:这个用户名是你之前自己创建的用户名
还原文件权限
chmod -v u-w /etc/sudoers
cd /home
chmod 755 git
切换用户并且保存公钥
获取本地主机的公钥
在本地主机终端上使用
cd ~/.ssh
ls
cat id_rsa.pub
如果没有看到公钥文件
ssh-keygen
就可以创建了
复制公钥的内容
在云主机上
su git # 切换到git
mkdir ~/.ssh
vim ~/.ssg/authorized_keys
然后将刚刚复制的公钥黏贴上去
更改权限
chmod 600 ~/.ssh/authorized_keys
chmod 700 ~/.ssh
创建并且链接git仓库
创建一个名叫blog的git仓库
mkdir /var/repo
cd /var/repo
git init --bare blog.git
配置githooks
vim /var/repo/blog.git/hooks/post-receive
写入(注意不要直接黏贴 需要先按i进入插入模式)
#!/bin/sh
git --work-tree=/var/www/hexo --git-dir=/var/repo/blog.git checkout -f
设置可运行权限
chmod +x /var/repo/blog.git/hooks/post-receive
改变目录所有者为git用户
chown -R git:git blog.git
创建网页目录并且配置权限
mkdir /var/www/hexo
chown -R git:git /var/www/hexo # 链接git仓库
chmod -R 755 /var/www/hexo # 配置权限
测试git账户是否正常工作
要求本地必须有ssh环境和git环境,这里不赘述如何安装了,macos使用终端,windows 的powershell也可以使用
首先使用ssh-copy-id git@<address>然后输入密码,接着在ssh中exit退出ssh,然后用ssh git@<address>命令,看是否无需密码就能进入ssh界面,如果可以则成功了,不可以的话,检查上述保存公钥的操作是否正确。
git clone git@服务器ip:/var/repo/blog.git 如果返回的是你似乎克隆了一个空仓库,那么恭喜你 基本上操作完成了。
本地hexo博客设置
打开本地hexo博客目录修改_config.yml文件,修改最下面一行:
deploy:
type: git
repository: git@ip或域名:/var/repo/blog.git
branch: master
改为这样
然后执行
hexo g
hexo d
然后打开你的网站 会发现,是一个Nginx页面,对 你Nginx还没配置呢
Nginx配置
上文我们知道,我们自己编译安装的Nginx目录是在/usr/local/src下的,所以ssh链接到云服务器,然后cd到那个目录开始配置Nginx
首先进入Nginx安装目录
cd conf
ls
vim nginx.conf
找到一个类似下面的结构:
server {
listen 80;
server_name localhost;
…………
然后我们对其进行修改,改成这样
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root /var/www/hexo;
index index.html index.htm;
}
然后重启nginx(我采用的是杀掉80端口的应用 然后再启动Nginx)
fuser -k 80/tcp
nginx
这样网页基本上可以正常访问了
最后需要设置域名解析 icp备案这些东西的 以后再讲
icp备案号注入
采用的方式是本地编辑好之后通过hexo同步到服务器之上
首先我们要知道控制hexo博客页面显示的文件在哪儿
因为我们用的是第三方主题,所以肯定是在themes文件夹之下,所以我们进去查看一番
然后吸引我们关注的文件夹就是layout,学过安卓开发的人都知道这个烦人的layout布局,进去一番寻找,找到一个footer.jsx这个就是我们需要修改的文件
查看这个文件,我们了解到这个和JavaScript类型很像,然后具体看一下语法,有点像js也有点像html
对比原来网页的页脚 嗯 就加在那个位置,备案号啥的直接指向工信部备案网站就行
const { Component } = require('inferno');
const { cacheComponent } = require('hexo-component-inferno/lib/util/cache');
class Footer extends Component {
render() {
const {
logo,
logoUrl,
siteUrl,
siteTitle,
siteYear,
author,
links,
showVisitorCounter,
visitorCounterTitle
} = this.props;
let footerLogo = '';
if (logo) {
if (logo.text) {
footerLogo = logo.text;
} else {
footerLogo = <img src={logoUrl} alt={siteTitle} height="28" />;
}
} else {
footerLogo = siteTitle;
}
return <footer class="footer">
<div class="container">
<div class="level">
<div class="level-start">
<a class="footer-logo is-block mb-2" href={siteUrl}>
{footerLogo}
</a>
<p class="is-size-7">
<span dangerouslySetInnerHTML={{ __html: `© ${siteYear} ${author || siteTitle}` }}></span>
Powered by <a href="https://hexo.io/" target="_blank" rel="noopener">Hexo</a> &
<a href="https://github.com/ppoffice/hexo-theme-icarus" target="_blank" rel="noopener">Icarus</a>
{showVisitorCounter ? <br /> : null}
{showVisitorCounter ? <span id="busuanzi_container_site_uv"
dangerouslySetInnerHTML={{ __html: visitorCounterTitle }}></span> : null}
<br/>
<a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener">鄂ICP备19025190号-1
</a>
</p>
</div>
<div class="level-end">
{Object.keys(links).length ? <div class="field has-addons">
{Object.keys(links).map(name => {
const link = links[name];
return <p class="control">
<a class={`button is-transparent ${link.icon ? 'is-large' : ''}`} target="_blank" rel="noopener" title={name} href={link.url}>
{link.icon ? <i class={link.icon}></i> : name}
</a>
</p>;
})}
</div> : null}
</div>
</div>
</div>
</footer>;
}
}
module.exports = cacheComponent(Footer, 'common.footer', props => {
const { config, helper } = props;
const { url_for, _p, date } = helper;
const { logo, title, author, footer, plugins } = config;
const links = {};
if (footer && footer.links) {
Object.keys(footer.links).forEach(name => {
const link = footer.links[name];
links[name] = {
url: url_for(typeof link === 'string' ? link : link.url),
icon: link.icon
};
});
}
return {
logo,
logoUrl: url_for(logo),
siteUrl: url_for('/'),
siteTitle: title,
siteYear: date(new Date(), 'YYYY'),
author,
links,
showVisitorCounter: plugins && plugins.busuanzi === true,
visitorCounterTitle: _p('plugin.visitor_count', '<span id="busuanzi_value_site_uv">0</span>')
};
});