还记得,今年、前年或大前年,618、双11 租来吃灰的 xx云服务器 吗?
还记得,当初是怀揣着怎么的心情,从服务器供应商小心翼翼的接过它吗?
还记得,斥资几百租回来后,自己口口声声立下的海誓山盟吗?
而今多年过去,它在你身边过得还安好吗?
看到这里,相信部分读者 才 想起自己租的云服务器,扫码登录ing...
笔者大前年学Python爬虫,一口气搞了三个,主从服务器,弄分布式爬取,
玩了一下下,可惜工作中没有具体的业务场景,劲头过了就搁置了。
后面妹子要找工作,挑了一个,随手给她撸了个静态网站放放作品和简历,
然后就一直吃灰直到过期,现在就剩一个薅了5年的弱鸡服务器。
最近一些事情,让我再次有了一种置办自己个人博客的想法:
- 1、平时写的文章大部分是面向读者,骚话、废话和表情有点多,而且比较零散, 自己 回顾和速查 的时候 效率低下,有时要翻上好几篇才能找到姿势点;
- 2、平台的不可控性,比如Github,本来就慢,因为某些原因,间接性抽风;
还有某些博客站点,时不时来个“因涉及xxx”,含辛茹苦写好的文章被下架无法访问;- 3、很多无脑搬运的直接照搬文章,改个标题就是自己的了,在推荐群学了个骚操作:
以上就是笔者置办个人博客的动机,尔后是技术选型:
- 简洁:界面简洁,排版合理,不需要花里花哨;
- 简单:上手简单,开箱即用,输出文章即可,无需过于关注实现细节;
- 快:加载快,性能高效,移动端适配(地铁上也可以康康);
Gitbook、Hexo、WordPress等之前折腾过一下,各有优缺点,最后决定用尤大的 Vuepress,
相关介绍自行移步至官网查阅:vuepress.docschina.org/,就不复制粘贴了。
网上大部分文章都是教如何把Vuepress部署到Github上,上面也说了不稳定,
部署到云服务器上也不难,就是build一下生成带样式的 静态网站,通过ftp传上去,
配置下Nginx,域名解析下即可。于是乎每次更新博客的流程:
本地修改 → 命令行build → ftp工具上传生成文件进行覆盖
可以是可以,就是有点繁琐,其实可以把build这一步放在服务器上,就不用ftp传了:
答:自动化构建 了解下?说到这个名词,第一反应是不是:Gitlab CI + jenkins, 但是小博客用他两太重了,官方推荐Gitlab服务器内存4G以上,Jenkins对配置要求也较高, 内存只有一个鸡的云服务器表示心有余而力不足。
酱紫,就得想想其他替代方案了,我把目光转向了国产Github → 码云Gitee,支持 WebHooks
em,要写一个API接口给它调,接口功能:拉取最新博客源代码 → 执行vuepress build构建命令 等。 一切准备就绪后的结果:我文章写完,git push一波,个人博客就自动更新了。妙啊! 另外,考虑到云服务器的硬盘只有50G,图片类资源文件就不丢上去了,直接用CDN~
本节就来手把手实践一波~
0x1、Vuepress 本地部署
① Node.js 安装配置
官网下载:nodejs.org/en/download…,傻瓜式下一步安装,完成后可配置
npm 安装的 全局模块 和 缓存cache的路径,不然全局安装的模块都会塞到:
C:\Users\用户名\AppData\Roaming\npm 中,占用C盘空间,可通过下述命令
修改为node.js的安装文件夹:
cd nodejs
# 创建文件夹
mkdir node_global
mkdir node_cache
# 设置
npm config set prefix node_global
npm config set cache node_cache
# 配置下环境变量(路径根据自己的实际情况进行替换):
# 系统变量 => 新建 => NODE_PATH => 输入
D:\Coding\nodejs\node_global\node_modules
# 用户变量Path中删除:
C:\Program Files\nodejs\node_global
# 新增
D:\Coding\nodejs\node_global
附:Node.js 及 npm 更新相关命令:
# 查看安装的node.js版本
node -v
# 清除cache
sudo npm cache clean -f
# 安装用于管理node.js版本的n工具
sudo npm install -g n
# 安装最新node.js
sudo n stable
# 查看版本号
npm -v
# 更新最新版
npm install npm@latest -g.
Tips:深入了解npm可移步至:www.npmjs.cn/getting-sta…
② 快速搭建
走一波命令安装vuepress,以及创建相关文件
# 全局安装,执行一次即可
npm install -g vuepress
# 创建博客项目
mkdir Blog
# 项目初始化
npm init -y
# 添加主README.md文件
touch README.md
# 添加docs文件夹
mkdir docs
# docs文件夹中创建.vuepress文件夹
cd docs
mkdir .vuepress
# 新建总配置config.js文件
cd .vuepress
touch config.js
# dosc文件夹中创建README.md文件
cd ..
touch README.md
此时目录结构比较简单:
D:\Blog
├── docs
| ├── .vuepress
| | └── config.js
| └── README.md
├── package-lock.json
├── package.json
└── README.md
接着打开package.json添加运行脚本:
"scripts": {
"dev": "vuepress dev docs",
"build": "vuepress build docs"
}
保存后,输入下述命令中的一个即可运行:
npm run dev
yarn run dev
运行成功,可以看到控制台输出:
此时打开localhost:8080,即可看到效果。
③ 推荐的目录结构
VuePress 遵循 “约定优于配置” 的原则,推荐的目录结构如下(小改了一些~):
.
├── docs
│ ├── .vuepress (可选) → 存放全局配置、组件、静态资源等
│ │ ├── components (可选) → 该目录中的 Vue 组件将会被自动注册为全局组件
│ │ ├── theme (可选) → 存放本地主题
│ │ │ └── Layout.vue
│ │ ├── public (可选) → 静态资源目录
│ │ ├── styles (可选) → 存放样式相关的文件
│ │ │ ├── index.styl → 将会被自动应用的全局样式文件,会生成在最终的
│ │ │ │ CSS 文件结尾,具有比默认样式更高的优先级。
│ │ │ └── palette.styl → 重写默认颜色常量,或者设置新的 stylus 颜色常量
│ │ ├── templates (可选,谨慎配置,最好基于默认模板文件来修改) → 存储HTML模板文件
│ │ │ ├── dev.html → 用于开发环境的HTML模板文件
│ │ │ └── ssr.html → 重写默认颜色常量,或者设置新的 stylus 颜色常量
│ │ ├── config.js → 全局配置文件
│ │ ├── enhanceApp.js → 客户端应用的增强
│ ├── guide (可选) → 一般会在此目录下创建网站指南
│ │ └── README.md
│ ├── study (举例)
│ │ └── study01.md
│ │ └── study02.md
│ ├── README.md → 博客首页
└── package.json → 项目启动配置
④ 默认主题配置
此处只是做下简单配置,更详细的配置可移步至官方文档: www.vuepress.cn/theme/defau…
1)页面标题与图标
修改 → docs/.vuepress/config.js
module.exports = {
title: 'CoderPig的小世界', // 网站标题
description: '吾日三省吾身', // 网站描述
head: [
// 网页标签图标,'/'指向docs/.vuepress/public 文件目录
['link', { rel: 'icon', href: '/img/favicon.ico' }]
],
base: '/',// 设置站点根路径
dest: './ROOT', // 设置输出目录
plugins: [],
}
2) 设置封面页
修改 → docs/README.md
---
home: true
heroImage: /img/logo.png
heroText: CoderPig的小世界
tagline: 吾日三省吾身
actionText: Get Started →
actionLink: /zh/guide/
features:
- title: 待填充
details: 待填充
- title: 待填充
details: 待填充
- title: 待填充
details: 待填充
footer: MIT Licensed | Copyright © 2018-present Evan You
---
看下运行效果,很Nice!
3) 添加导航栏nav
修改 → docs/.vuepress/config.js
themeConfig: {
// 添加导航栏
nav: [
{ text: '主页', link: '/' },
{ text: 'Android',
items: [
{text: '源码', link: '/android/sourcecode/'},
{text: '架构', link: '/android/architecture/'},
{text: '逆向', link: '/android/hook/'}
]
},
{ text: 'Github', link: 'https://github.com/coder-pig' },
{ text: '关于我', link: '/other/aboutme.md' },
],
}
看下运行结果:
基础配置的示例就说这些,接着说下抽取配置,实现模块化。
⑤ 配置抽取
配置的东西全写在config.js中,后续随着博客文章数量及分类增多,维护起来不怎么方便。
可将对应的属性抽取出来,放到一个单独的js文件中,config.js中去引用,示例如下:
// head.js
module.exports =[
['link', { rel: 'icon', href: '/img/favicon.ico' }]
]
// nav.js
module.exports = [
{
text: '首页', link: '/'
},
{
text: 'Python',
items: [
{text :'基础', link: '/python/base'},
{text :'爬虫', link: '/'},
{text :'Web', link: '/'},
{text :'机器学习', link: '/'},
]
},
]
// config.js中引用
const navConf = require('./config/nav')
const headConf = require('./config/head')
module.exports = {
title: 'CoderPig的小世界', // 网站标题
description: '吾日三省吾身', // 网站描述
dest: './ROOT', // 设置输出目录
plugins: [],
head: headConf,
themeConfig: {
nav: navConf,
sidebarDepth: 2,
lastUpdated: 'Last Updated',
}
}
另外说下sidebar,有时可能会为某几个页面设置单独的侧边栏,比如:
可以单独设置一个sidebar,如:
// ptyhon-base/sidebar.js
module.exports = [
{
title: '开发环境搭建',
sidebarDepth: 2,
collapsable: true,
children: ['1.1/', '1.2/', '1.3/']
},
{
title: '概念常识',
sidebarDepth: 2,
collapsable: true,
children: ['2.1/', '2.2/', '2.3/']
},
{
title: '数据类型',
sidebarDepth: 2,
collapsable: true,
children: ['3.1/', '3.2/', '3.3/', '3.4/']
},
{
title: '条件判断与循环',
sidebarDepth: 2,
collapsable: true,
children: ['1.1/', '1.2/']
},
]
然后config/slidebar.js引用一波:
module.exports = {
'/python-base/': require('../../python-base/sidebar'),
}
完美~
⑥ 生成静态文件
执行一波 vuepress build 即可,构建成功后,可以看到文件的存放目录:
此时如果你来到目录下打开index.html,会发现没有样式,控制台也一堆爆红
点开其中一个css:
明显的路径不对,可以修改config.js中的 base 属性,然后重新build一下,
不过笔者发现即使修改正确后,本地打开正常,然后会立马跳转404,目前无解,
有知道的朋友欢迎在评论区留言告知下,万分感激~
⑦ 添加.gitignore文件
然后是配置.gitignore文件,将一些不需要提交的文件忽略掉:
node_modules
dist
.idea
本地部署相关的就折腾那么多,接着是部署到云服务器上。
0x2、Vuepress 部署到云服务器
相关工具:
- 云服务器系统:CentOS 8
- SSH终端:Windows terminal
- FTP工具:WinSCP
① SSH 连接云服务器
# 回车输入密码 → 回车
ssh root@xxx.xxx.xxx.xxx
② Nginx 安装
# 安装Nginx
sudo yum install nginx
# ↓ ↓ ↓ ↓ ↓ ↓ 其他常用命令 ↓ ↓ ↓ ↓ ↓ ↓
# 查看nginx运行状态
ps aux | grep nginx
# 重载nginx配置文件n
nginx -s reload
# 立即停止nginx
nginx -s stop
# 优雅停止nginx
nginx -s quit
# 杀死所有nginx进程
killall nginx
# 启动nginx
systemctl start nginx.service
# 停止nginx服务
systemctl stop nginx.service
# 重启nginx服务
systemctl restart nginx.service
# ↓ ↓ ↓ ↓ ↓ ↓ 常用文件位置 ↓ ↓ ↓ ↓ ↓ ↓
# 查看nginx安装列表,可看到所有安装位置
rpm -ql nginx
/etc/nginx/nginx.conf # nginx总配置文件
/etc/nginx/conf.d # 所有的nginx自定义配置文件
/var/log/nginx/error.log # 错误日志文件
/usr/share/nginx/html # 服务器默认启动目录
另外,CentOS 8内置FirewallD防火墙方案,需要配置运行nginx的 80(HTTP) 和 443(HTTPS) 端口通过:
firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --permanent --zone=public --add-service=https
firewall-cmd --reload
浏览器输入主机公网ip,出现如下页面,代表Nginx安装成功。
③ Nginx 配置
接着把我们本地build生成的文件通过ftp工具上传到云服务器上,因为使用相对路径,
build之前要修改下config.js文件,添加 base 属性:
build一波,然后上传一波,传哪里自己看自己喜好,笔者上传到下述路径中:
然后配置下nginx,来到 /etc/nginx/ 目录下,配置文件一般是 nginx.conf,不过考虑到
后续可能还要导几个项目,此处分一层,把配置写到单独一个文件中,放到 /conf.d 文件夹下。
文件内容如下:
server {
listen 80;
server_name xxx.xxx.xxx.xxx; // 主机IP
location /{
root /home/project/blog;
index index.html index.htm index.nginx-debian.html;
try_files $uri $uri/ =404;
}
}
然后 /conf.d 文件的http层级,添加:
include /etc/nginx/conf.d/*.conf;
最后 nginx -s reload 重载下配置文件,此时在浏览器打开主机的公网IP:
啧啧啧,可以外网访问自己的博客了,接着弄自动化部署~
0x3、Vuepress 自动部署
码云Gitee 新建个仓库,把本地代码Push上去,基本常识不讲,不懂善用搜索引擎~ 开头说过,这个自动化部署的流程:
- 1、提供一个接口,功能:自动拉取最新代码 → build生成文件 → 覆盖博客目录
- 2、当我们Push代码,Gitee WebHook调用这个接口即可
① 编写脚本文件
我们把自动化操作写到一个脚本文件中,调用接口时执行这个sh脚本即可:
# 拉取远程分支
git pull origin master
# 生成静态文件
npm run build
# 把生成的静态文件 复制到 静态网站的目录下,存在则覆盖
\cp -rf docs/.vuepress/dist/. /home/project/blog
SSH终端 bash xxx.sh 运行一波,看下是否有覆盖成功即可~
② 编写接口
脚本写完,写个接口来执行这个脚本,后台语言Java,Python、Go、PHP等都可以,会啥用啥。
笔者用的是Python Flask,相关API及详细用法可参见之前写的:
《偷个懒,公号抠腚早报80%自动化——3.Flask速成大法》,
此处仅做演示,故只是简单的写个接口~
CentOS 8 自带Python 3.6.8,就不用另外安装Python了,命令行:
cd /home/project
mkdir Api
cd Api
python3 -m venv venv
source venv/bin/activate
pip install flask
pip install flask-script
vim app.py
输入下述内容:
from flask_script import Manager
from flask import Flask
import os
app = Flask(__name__)
@app.route("/api/refresh_blog")
def refresh_blog():
os.system("cd ../blog/;bash auto.sh")
return "博客刷新成功!"
if __name__ == '__main__':
app.run()
按ESC,输入 :wq,保存即可,然后输入下述命令启动项目:
python app.py runserver -p 12345
再接着新开一个ssh终端链接云服务器,用curl命令看下接口能否正常调用:
curl http://127.0.0.1:12345/refresh_blog
如果正常调用,终端可以看到vuepress打包的过程,最后输出:
③ 安装uwsgi
yum install uwsgi
# 如果安装报错:Command "/usr/bin/python3.6 -u -c "import setuptools, tokenize;
# 先安装一波python-devel,这里是python3.6版本,要用python36-devel
# 搜索python36-devel版本
yum search python36-devel
# 根据输出结果,如:python36-devel.x86_64 : Libraries and header files ..。
# 安装对应版本的python36-devel
yum install python36-devel.x86_64
# 此时再安装uwsgi就可以了~
④ 编写uwsgi配置文件
在项目目录下创建一个配置文件
vim config.ini
配置内容如下:
[uwsgi]
# 指明要启动的模块,前者为项目启动文件名去掉.py,后者为变量app,Flask的实例
module = app:app
# 处理器数
processes = 1
# 指向网站目录
chdir = /home/project/Api
# uwsgi 启动时所使用的地址与端口
socket = 127.0.0.1:8005
# 日志输出目录
logto = /home/project/Api/history.log
# 状态检测地址
stats = 127.0.0.1:12345
然后命令行启用即可:
uwsgi config.ini
⑤ Nginx 配置
上面Vuepress部署时配过Nginx,没太大必要用两个域名,直接在原先基础上配置一个location即可,配置后的blog.conf
server {
listen 80;
server_name xx.xx.xx.xx;
location /{
root /home/project/blog;
index index.html index.htm index.nginx-debian.html;
try_files $uri $uri/ =404;
}
location /api/ {
include uwsgi_params;
uwsgi_pass 127.0.0.1:8005;
}
}
保存后 nginx -s reload,重载下nginx,接着浏览器访问:主机IP/api/refresh_blog,没有出现404,静待片刻后,出现如下界面即可:
⑥ 域名解析
这个就很简单了,自己买个域名备案,然后打开域名管理页面,找到刚买的域名,点击 解析:
点击 添加记录,出现如图所示对话框,记录值那里填写你的云服务器公网ip即可。
过10分钟左右就可以用你的域名访问我们的个人博客了~
⑦ Gitee配置WebHooks
点击项目 Settings → 找到点击 WebHooks → 点击 Add
我丢,竟然还要POST请求的,另外码云这里街口响应时间超过10s就会超时,
执行构建命令比较耗时,使用线程池来异步执行,修改后的代码如下:
import os
from concurrent.futures.thread import ThreadPoolExecutor
from flask import Flask
app = Flask(__name__)
executor = ThreadPoolExecutor(max_workers=2)
def auto_build():
os.system("cd ../blog/;bash auto.sh")
@app.route("/api/refresh_blog", methods=['POST'])
def refresh_blog():
executor.submit(auto_build)
return "博客刷新成功!"
if __name__ == '__main__':
app.run()
然后Gitee上点击Test,可以看到接口响应结果:
最后打开blog项目,改点东西,然后Push一下,打开域名康到蕾姆酱:
大功告成~~~
结语
以上就是如何把Vuepress生成的静态网站部署到云服务器上的全过程实录, 实现手法比较 粗糙,后续肯定是会折腾下主题和其他乱七八糟的, 当然最重要的还是整理记录自己的姿势树,厚积薄发,温故知新,就酱,谢谢~