服务器购买
鉴于博客托管到Github上加载太慢,搞个服务器是必须的,而且后面白嫖七牛云图床服务也需要用到。服务器这块可供选择很多,国内的直接阿里云,腾讯云走起,国外的搬瓦工,Vultr,Hostwinds等VPS厂商也还行
最终选的阿里云学生套餐,配置是1核、2GB内存、40GB SSD的轻量应用服务器,服务端预装CentOS 7.3,一般会进工单后台系统重置下密码,不然下一步SSH连接输密码无回显,输入无规律字符会很难受
使用PuTTY,Xshell,SecureCRT等工具,SSH连上远程服务器,这里使用MobaXterm,颜值还是比较耐打的,免费版差不多够用了,话说Windows Terminal也很OK
域名 + 备案
域名的话腾讯名购买的,考虑到续费比较贵,购买时应尽量选择年限长一点,会比较合算,阿里云的线上备案机制还是比较完善的,照着填就好
备案信息提交后,
阿里云客服
会初审,电话回访确认信息以及让提供视频备案承诺信息,提交给工信部
后,工信部会发信息验证码,要求进行核验,完成后提交通管局
不过实际管局审核后未进行电话核实,差不对一周的时间,直接发消息提醒备案通过
然后就是安装个面板,干起运维的活,这里用的宝塔面板,体验还不错
注意:这里也有可能你进不去面板页面,是因为服务器没有开8888这个端口(具体看宝塔面板连接的端口),去阿里云轻量服务器控制台中的“安全”->“防火墙”,右上角的”添加规则”,添加相应的端口即可。
这边的话安装完成,注册个BT账号绑定下,登录即可开启运维大业
图床搭建
图床简介
Markdown是博客的标配,写markdown肯定离不开图床,数据才是核心的东西,免费的说不定什么时候就暴毙了,微博图床和路过图床先pass,码云和github上当备份还行,作为主力图床可能加载速度有点勉强,排除这些,然后剩下的主流提供服务的厂商有阿里云OSS存储,七牛云存储,腾讯云对象存储,又拍云图床,认真思虑良久,还是白嫖七牛云使人快乐
注册登录七牛云,进入控制台找到添加对象存储,并新建一个存储空间用来作图床
创建空间
域名更换
到这里我们就可以在我们的博客引用外链,显示图片了,当然也可用于公众号。但是七牛云给我们使用这种链接的时间只有一个月,一个月之后就会回收域名
所以用我们自己的二级域名来绑定七牛云进行访问(最好不用www开头的二级域名来绑定,因为www开头的域名,我们都是作为主域名的)
配置CNAME
添加域名后会生成CNAME,拷贝到域名厂商处添加解析
添加解析
图床搭建完成
PicGo绑定七牛云图床
七牛云个人中心查看密钥
本地Hexo搭建
Hexo概览
使用hexo g将source文件夹下md文件渲染成静态HTML文件
在服务器远端也部署下git环境
hexo d将生成的静态文件push到远程仓库(这里指github和阿里云服务器上)
使用git-hooks实现自动部署,将仓库checkout到网站根目录
Nginx用做静态文件服务器,实现外界对博客的访问
安装nodejs
安装完nodejs,node -v, npm -v查看下版本号
添加国内镜像源,这里选择使用阿里的国内镜像进行加速
npm config set registry https://registry.npm.taobao.org
安装Hexo
$ npm install -g hexo-cli
初始化Hexo
- scaffolds是模版文件夹,当新建文章时,Hexo 会根据 scaffold 来建立文件
- source文件夹是存放用户资源的地方
- themes是主题文件夹,Hexo 会根据主题来生成静态页面
输入命令行进行本地调试,即可看到初始效果
更换主题为matery
确保本地git环境部署好,使用matery theme代替默认的landscape,这个hexo主题与前面提到的typora-vue-theme都是blinkfox大佬制作的,审美在我的点上
修改配置文件
站点配置文件:根目录 config.yml ,主题配置文件: themes/config.yml
tags 页面
tags页是用来展示所有标签的页面,如果博客source目录下还没有tags/index.md 文件,那么就需要新建一个
hexo new page "tags"
编辑刚刚新建的页面文件/source/tags/index.md,至少需要以下内容:
---
title: tags
date: 2020-10-28 18:23:38
type: "tags"
layout: "tags"
---
categories 页面
categories页是用来展示所有分类的页面,如果博客source目录下还没有 categories/index.md文件,那么就需要新建一个
hexo new page "categories"
编辑刚刚新建的页面文件/source/categories/index.md,至少需要以下内容:
---
title: categories
date: 2020-10-28 17:25:30
type: "categories"
layout: "categories"
---
about 页面
about页是用来展示关于我和我的博客信息的页面,如果博客source目录下还没有about/index.md文件,那么就需要新建一个
hexo new page "about"
编辑刚刚新建的页面文件/source/about/index.md,至少需要以下内容:
---
title: about
date: 2020-10-28 17:25:30
type: "about"
layout: "about"
---
当然上面提到的这些通过手动创建也是可以的
菜单导航配置
名称、路径和图标
- 菜单导航名称可以是中文也可以是英文(如:Index或主页)
- 图标icon 可以在Font Awesome 中查找
menu:
Index:
url: /
icon: fas fa-home
Tags:
url: /tags
icon: fas fa-tags
Categories:
url: /categories
icon: fas fa-bookmark
Archives:
url: /archives
icon: fas fa-archive
About:
url: /about
icon: fas fa-user-circle
二级菜单配置
如果需要二级菜单,则可以在原基本菜单导航的基础上如下操作
- 在需要添加二级菜单的一级菜单下添加children关键字(如:About菜单下添加children)
- 在children下创建二级菜单的 名称name,路径url和图标icon.
- 注意每个二级菜单模块前要加 -.
- 注意缩进格式
插件
代码高亮
由于 Hexo 自带的代码高亮略显平庸,所以主题中使用到了 hexo-prism-plugin 的 Hexo 插件来做代码高亮,安装命令如下:
npm i -S hexo-prism-plugin
修改 Hexo 根目录下_config.yml文件中highlight.enable的值为 false,并新增prism插件相关的配置,主要配置如下:
prism_plugin:
mode: 'preprocess' # realtime/preprocess
theme: 'tomorrow'
line_number: true #default false
custom_css:
搜索
使用hexo-generator-search](https://github.com/wzpan/hexo-generator-search) 插件来做内容搜索
npm install hexo-generator-search --save
在 Hexo 根目录下的_config.yml文件中,新增以下的配置项:
search:
path: search.xml
field: post
文章字数统计
安装hexo-wordcount插件,在文章中显示文章字数、阅读时长信息
npm i --save hexo-wordcount
需要在本主题下的_config.yml 文件中,激活以下配置项
postInfo:
date: false # 发布日期
update: false # 更新日期
wordCount: true # 文章字数统计
totalCount: true # 站点总文章字数
min2read: true # 文章阅读时长
readCount: true # 文章阅读次数
JS特效
HTML + CSS齐活了,肯定不能少了JS的身影
添加雪花飘落效果
在themes/matery/source/js目录下新建snow.js文件
/*样式一*/
(function($){
$.fn.snow = function(options){
var $flake = $('<div id="snowbox" />').css({'position': 'absolute','z-index':'9999', 'top': '-50px'}).html('❄'),
documentHeight = $(document).height(),
documentWidth = $(document).width(),
defaults = {
minSize : 10,
maxSize : 20,
newOn : 1000,
flakeColor : "#AFDAEF" /* 此处可以定义雪花颜色,若要白色可以改为#FFFFFF */
},
options = $.extend({}, defaults, options);
var interval= setInterval( function(){
var startPositionLeft = Math.random() * documentWidth - 100,
startOpacity = 0.5 + Math.random(),
sizeFlake = options.minSize + Math.random() * options.maxSize,
endPositionTop = documentHeight - 200,
endPositionLeft = startPositionLeft - 500 + Math.random() * 500,
durationFall = documentHeight * 10 + Math.random() * 5000;
$flake.clone().appendTo('body').css({
left: startPositionLeft,
opacity: startOpacity,
'font-size': sizeFlake,
color: options.flakeColor
}).animate({
top: endPositionTop,
left: endPositionLeft,
opacity: 0.2
},durationFall,'linear',function(){
$(this).remove()
});
}, options.newOn);
};
})(jQuery);
$(function(){
$.fn.snow({
minSize: 5, /* 定义雪花最小尺寸 */
maxSize: 50,/* 定义雪花最大尺寸 */
newOn: 300 /* 定义密集程度,数字越小越密集 */
});
});
在themes/matery/layout/layout.ejs文件内加下
鼠标点击文字特效
在themes/matery/source/js目录下新建click_show_text.js文件
var a_idx = 0;
jQuery(document).ready(function ($) {
$("body").click(function (e) {
var a = new Array("富强", "民主", "文明", "和谐", "自由", "平等", "公正", "法治", "爱国", "敬业", "诚信", "友善");
var $i = $("<span/>").text(a[a_idx]);
a_idx = (a_idx + 1) % a.length;
var x = e.pageX,
y = e.pageY;
$i.css({
"z-index": 5,
"top": y - 20,
"left": x,
"position": "absolute",
"font-weight": "bold",
"color": "#FF0000"
});
$("body").append($i);
$i.animate({
"top": y - 180,
"opacity": 0
},
3000,
function () {
$i.remove();
});
});
setTimeout('delay()', 2000);
});
function delay() {
$(".buryit").removeAttr("onclick");
}
在themes/matery/layout/layout.ejs文件内添加下面的内容:
<script src="/js/click_show_text.js"></script>
鼠标彩虹星星掉落
添加鼠标彩虹星星掉落跟随效果
在themes/matery/source/js目录下新建cursor.js文件
/*!
* Fairy Dust Cursor.js
* - 90's cursors collection
* -- https://github.com/tholman/90s-cursor-effects
* -- http://codepen.io/tholman/full/jWmZxZ/
*/
//鼠标点击雪花特效
(function fairyDustCursor() {
var possibleColors = ["#D61C59", "#E7D84B", "#1B8798"]
var width = window.innerWidth;
var height = window.innerHeight;
var cursor = {x: width/2, y: width/2};
var particles = [];
function init() {
bindEvents();
loop();
}
// Bind events that are needed
function bindEvents() {
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('touchmove', onTouchMove);
document.addEventListener('touchstart', onTouchMove);
window.addEventListener('resize', onWindowResize);
}
function onWindowResize(e) {
width = window.innerWidth;
height = window.innerHeight;
}
function onTouchMove(e) {
if( e.touches.length > 0 ) {
for( var i = 0; i < e.touches.length; i++ ) {
addParticle( e.touches[i].clientX, e.touches[i].clientY, possibleColors[Math.floor(Math.random()*possibleColors.length)]);
}
}
}
function onMouseMove(e) {
cursor.x = e.clientX;
cursor.y = e.clientY;
addParticle( cursor.x, cursor.y, possibleColors[Math.floor(Math.random()*possibleColors.length)]);
}
function addParticle(x, y, color) {
var particle = new Particle();
particle.init(x, y, color);
particles.push(particle);
}
function updateParticles() {
// Updated
for( var i = 0; i < particles.length; i++ ) {
particles[i].update();
}
// Remove dead particles
for( var i = particles.length -1; i >= 0; i-- ) {
if( particles[i].lifeSpan < 0 ) {
particles[i].die();
particles.splice(i, 1);
}
}
}
function loop() {
requestAnimationFrame(loop);
updateParticles();
}
/**
* Particles
*/
function Particle() {
this.character = "*";
this.lifeSpan = 120; //ms
this.initialStyles ={
"position": "fixed",
"top": "0", //必须加
"display": "block",
"pointerEvents": "none",
"z-index": "10000000",
"fontSize": "20px",
"will-change": "transform"
};
// Init, and set properties
this.init = function(x, y, color) {
this.velocity = {
x: (Math.random() < 0.5 ? -1 : 1) * (Math.random() / 2),
y: 1
};
this.position = {x: x - 10, y: y - 20};
this.initialStyles.color = color;
console.log(color);
this.element = document.createElement('span');
this.element.innerHTML = this.character;
applyProperties(this.element, this.initialStyles);
this.update();
document.body.appendChild(this.element);
};
this.update = function() {
this.position.x += this.velocity.x;
this.position.y += this.velocity.y;
this.lifeSpan--;
this.element.style.transform = "translate3d(" + this.position.x + "px," + this.position.y + "px,0) scale(" + (this.lifeSpan / 120) + ")";
}
this.die = function() {
this.element.parentNode.removeChild(this.element);
}
}
/**
* Utils
*/
// Applies css `properties` to an element.
function applyProperties( target, properties ) {
for( var key in properties ) {
target.style[ key ] = properties[ key ];
}
}
init();
})();
在themes/matery/layout/layout.ejs文件内添加如下
<script src="/js/cursor.js"></script>
配置音乐播放器
要支持音乐播放,就必须开启音乐的播放配置和音乐数据的文件
首先,在博客source目录下的_data目录(没有的话就新建一个)中新建 musics.json文件,文件内容如下所示:
[{ "name": "五月雨变奏电音",
"artist": "AnimeVibe",
"url": "http://xxx.com/music1.mp3",
"cover": "http://xxx.com/music-cover1.png"
}, {
"name": "Take me hand",
"artist": "DAISHI DANCE,Cecile Corbel",
"url": "/medias/music/music2.mp3",
"cover": "/medias/music/cover2.png"
}, {
"name": "Shape of You",
"artist": "J.Fla",
"url": "http://xxx.com/music3.mp3",
"cover": "http://xxx.com/music-cover3.png"
}]
注:以上 JSON 中的属性:name、artist、url、cover 分别表示音乐的名称、作者、音乐文件地址、音乐封面。
然后,在主题的_config.yml配置文件中激活配置即可
服务端部署
安装依赖库
yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel
安装编译工具
yum install gcc perl-ExtUtils-MakeMaker package
查看git的版本
git version
删除git
yum remove git -y
下载解压最新版
cd /usr/local/src #下载的目录
wget https://www.kernel.org/pub/software/scm/git/git-2.28.0.tar.gz #下载最新版
tar -zxvf git-2.28.0.tar.gz #解压到当前文件夹
编译源码并安装
cd git-2.28.0 #进入文件夹
make prefix=/usr/local/git all #编译源码
make prefix=/usr/local/git install #安装路径
配置git的环境变量
echo 'export PATH=$PATH:/usr/local/git/bin' >> /etc/bashrc
刷新环境变量
source /etc/bashrc
查看版本号
git --version
创建用户并修改权限
adduser holy
passwd holy
chmod 740 /etc/sudoers
vim /etc/sudoers
root ALL=(ALL) ALL
holy ALL=(ALL) ALL
改回权限
chmod 400 /etc/sudoers
设置holy账户密码
sudo passwd holy
输入两次密码,不可见
打通SSH
ssh-keygen -t rsa
切换至holy用户,创建 ~/.ssh文件夹和 ~/.ssh/authorized_key文件,并赋予相应的权限
su holy
mkdir ~/.ssh
vim ~/.ssh/authorized_keys
接着将win10中生成的id_rsa.pub文件中的公钥复制到authorized_keys中
赋予权限
chmod 600 /home/holy/.ssh/authorized_keys
chmod 700 /home/holy/.ssh
本地登录
在本地Git终端中测试是否能免密登录git,其中SERVER为填写自己的云主机IP,执行输入yes后输入之前配置的git密码,无报错就说明好了
集成到Windows Terminal中
Windwos Terminal 可以开多个窗口,也不断开源维护更新,搭配主题美化下还是很优秀的,所以这里在Windows Terminal配置文件集成下,另外不得不说的是,自从微软收购github以来,生产力工具真的越做越好,VSOCDE、Visual Studio都是开发必备,WSL体验也极佳
网站配置
创建Git仓库
在var目录下创建repo作为Git仓库目录,返回服务端命令行切换到root账户,然后输入
mkdir /var/repo
赋予权限:
chown -R holy:holy /var/repo
chmod -R 755 /var/repo
创建站点目录
mkdir /var/hexo
chown -R holy:holy /var/hexo
chmod -R 755 /var/hexo
初始化远程仓库
cd /var/repo
git init --bare hexo.git
创建新的 Git 钩子
在 /var/repo/hexo.git 下,有一个自动生成的 hooks 文件夹,需要在里边新建一个新的钩子文件 post-receive,用于自动部署
vim /var/repo/hexo.git/hooks/post-receive
#!/bin/bash
git --work-tree=/var/hexo --git-dir=/var/repo/hexo.git checkout -f
修改权限
chown -R holy:holy /var/repo/hexo.git/hooks/post-receive
chmod +x /var/repo/hexo.git/hooks/post-receive
Nginx安装
在本地浏览器端输入宝塔面板地址,进入服务器运维管理界面,安装Nginx
添加站点
回到服务器终端,重启宝塔服务,使之生效
service bt restart
本地博客发布
首先需要安装发布的插件,在博客目录下执行hexo d部署到远端仓库,可以添加多个仓库,一般github会留个备份
npm install hexo-deployer-git --save
申请SSL证书
既然要支持全站https,那必不可少的是申请证书了,因为域名是在腾讯云买的,所以是直接在腾讯云管理平台申请的ssl证书,选择自动验证十分钟左右就把证书颁发下来了,直接点击下载证书,解压之后会有四个文件夹,因为用的Nginx,所以只需要Nginx文件夹下面的bundle.crt和.key两个文件,至于外层的csr不需要用到
由于七牛云图床https流量要计费,所以博客站点还是采用http吧,后续有相关博客美化再更新!
总结
拆开来看,技术上没什么难点,主要还是框架和服务的选择,Wordpress、Hexo、Typecho都是比较流行的博客框架,图床服务和Markdown编辑器的选择也很丰富,重点还是要有自己的思路,将记录积累的活整合到适合自己的个性化学习工作流程中,形成习惯,博客只是恰好能提供这样一个持续的反馈