# 搭建一个vuepress博客,并使用容器化的方式部署
# 前言
我尝试过很多次搭建博客,像是hexo,wordpress,也试过写公众号,或者说是使用一些第三方的软件,像是印象笔记(当然不用主要是因为它同步收费),微软的OneNotes,要么就是疲于改格式,要么就是使用不便,自从看到这个vuepress,我就觉得,嗯,就是它了。
# 我认为vuepress的几个优点
- 简洁
- 方便,直接上传md文件即可
- 自定义程度高,其实就是vue开发,vuepress不过是其中的一个依赖而已
- 支持全文检索【通过第三方依赖添加】,这在我看来是最重要的功能
- 屏幕自适应,不管是电脑,平板,手机都可以查看,那么如果想到一个东西,只要手边有手机,随时随地都可以查看博客中的内容,也能快速搜索
- ......(想到再补充)
那么,我们开始吧。
【前提条件】node版本大于12,部署博客的服务器。如果没有服务器,用github,或者其他托管静态资源的网站都行,但这种部署方式我们在文中不做讨论。本文主要针对有服务器的同学,并有一定的docker容器化知识的基础。至于为什么选择docker,我也不用多说了,沙箱隔离,一致性,好处很多。
创建并进入文件夹vuepress-starter
mkdir vuepress-starter && cd vuepress-starter
使用npm进行初始化
npm init
将 VuePress 安装为本地依赖
npm install -D vuepress
在package.json中添加脚本
cp -R myPlugins ./dist意为把自己的依赖拷进最后打好的包中,不拷进去的话,通过build出来的版本全文检索会失败
{
"scripts": {
"docs:dev": "vuepress dev docs",
"docs:build": "vuepress build docs && cp -R myPlugins ./dist"
}
}
创建你的第一篇文档
mkdir docs && echo '# Hello VuePress' > docs/README.md
这个时候,博客已经可以启动了,执行命令
npm run docs:dev
即可,但这个时候你看的博客是一个啥也没有空白博客,就像下图所示
我们来添加一些内容
在这之前,我给大家看看我的目录结构
vuepress-starter ├── docs │ ├─ .vuepress │ │ ├─ public │ │ │ └─ log.ico # 选择一个你喜欢的log放在这个目录下即可,在md文件中使用的时候,直接使用/log.ico即可 │ │ ├─ config.js # 配置文件信息 │ │ ├─ nav.js # 顶部导航栏配置 │ │ └─ sidebar.js # 侧边栏配置,这里是为了聚合各子文件夹下的侧边栏配置 │ ├─ java │ │ ├─ README.md │ │ ├─ sidevar.js │ │ └─ sort.md │ ├─ mysql │ │ ├─ high │ │ │ ├─ README.md │ │ │ ├─ sidevar.js │ │ │ └─ 进阶.md │ │ └─ zero │ │ ├─ README.md │ │ ├─ sidevar.js │ │ └─ 基础.md │ └─ README.md ├── myPlugins │ └─ vuepress-plugin-full-text-search # 全文检索代码源文件 ├── Docerfile # 代码打包文件 ├── deploy.sh # 部署脚本 └── package.json # 依赖管理文件
全文检索为什么不直接install第三方的依赖?
本来有直接install依赖的方式,但只支持英文检索,不太友好,所以在我一番探索之后,找到了网友的修改版。
git地址:https://github.com/taojunnan/vuepress-plugin-full-text-search,将源代码下载到myPlugins目录下即可
为什么有那么多README?
可能你有注意到,有很多README文件,这是因为,在进入到一个页面的时候,首先会去查找并加载README.md文件,如果没有这个文件,那么从导航点进去的时候,就会直接跳转404页面了
代码清单
/docs/README.md
--- home: true heroImage: /log.ico actionText: 看看都有些啥 → actionLink: /java/ features: - title: 杂记 details: 想到什么记什么。 - title: 卷耳 details: 采采卷耳,不盈顷筐。嗟我怀人,置彼周行。 - title: 目标驱动 details: 把大事情拆分成许多目标清晰明确,环环相扣,易于完成的小目标。 footer: Copyright © 2021 Grasswort ---
/docs/.vuepress/config.js
module.exports = { title: '学习才是源动力', description: 'Hello, World!', head: [ ['link', { rel: 'icon', href: `/log.ico` }] ], // 执行npm run docs:build命令后,文件的输入地址 dest: './dist', ga: '', // 浏览器适配 evergreen: true, markdown: { // 显示行号 lineNumber: true }, plugins: [ // 在依赖中添加全文索引 require.resolve('../../myPlugins/vuepress-plugin-full-text-search/') ], themeConfig: { // 以配置文件的方式读取顶部导航栏 nav: require("./nav"), // 以配置文件的方式读取各个页面的侧边栏 sidebar: require("./sidebar"), // 侧边栏的读取深度为2 sidebarDepth: 2, // 显示文件的最后更新时间 lastUpdated: 'Last Updated', searchMaxSuggestoins: 10, serviceWorker: { updatePopup: { message: "有新的内容.", buttonText: '更新' } }, editLinks: true, editLinkText: '在 GitHub 上编辑此页 !' }, }
/docs/.vuepress/nav.js
module.exports = [ { text: '首页', link: '/' }, { text: 'Java学习', link: '/java/' }, { text: 'MySQL学习', link: '/mysql/', items: [ {text: '初级开发篇', link: '/mysql/zero/'}, {text: '中高进阶篇', link: '/mysql/high/'}, ] }, { text: '第三方应用探索', items: [ { text: '在线编辑', items: [ {text: '图片压缩', link: 'https://tinypng.com/'} ] }, { text: '在线服务', items: [ {text: '阿里云', link: 'https://www.aliyun.com/'}, {text: '腾讯云', link: 'https://cloud.tencent.com/'} ] }, { text: '博客指南', items: [ {text: '掘金', link: 'https://juejin.im/'}, {text: 'CSDN', link: 'https://blog.csdn.net/'} ] } ] } ]
/docs/.vuepress/sidebar.js
module.exports = { '/java/': require('../java/sidebar'), '/mysql/high/': require('../mysql/high/sidebar'), '/mysql/zero/': require('../mysql/zero/sidebar') }
/docs/java/README.md
### Java简介 /// 此处省去好多好多字
/docs/java/sidebar.js
module.exports = [ { title:'排序算法', collapsable: false, children:[ '/java/sort', // java指文件夹名称,sort指sort.md, 即可按照sort.md中的首行,排序算法生成侧边栏 ] } ]
/docs/java/sort.md
### 排序算法 /// 此处省去好多好多字
/docs/mysql/high/README.md
### MySQL高级教程
/docs/mysql/high/sidebar.js
module.exports = [ { title:'MySQL高级教程', collapsable: false, children:[ '/mysql/high/进阶', ] } ]
/docs/mysql/high/进阶.md
### 为什么删了数据,mysql的占用空间没有减少 /// 此处省去好多好多字
/docs/mysql/zero/README.md
### MySQL简介 /// 此处省去好多好多字
/docs/mysql/zero/sidebar.js
module.exports = [ { title:'MySQL基础教程', collapsable: false, children:[ '/mysql/zero/基础', ] } ]
/docs/mysql/zero/基础.md
### 为什么删了数据,mysql的占用空间没有减少 /// 此处省去好多好多字
package.json
{ "name": "yes", "version": "1.0.0", "description": "vue-press", "main": "index.js", "scripts": { "docs:dev": "vuepress dev docs", "docs:build": "vuepress build docs" }, "keywords": [], "author": "liuxiaolu", "license": "ISC", "repository": { "type": "git", "url": "xxxx" }, "devDependencies": { "@vuepress/theme-blog": "^2.3.3", "vuepress": "^1.7.1", "flexsearch": "nextapps-de/flexsearch", "html-to-text": "^5.1.1", "segmentit": "^2.0.3" } }
将此代码清单写入你自己的工程之后,在terminal中执行
npm install && npm run docs:dev
,再次打开首页,就可以看到首页已经显示正常了,且顶部一共有四个导航栏,首页,JAVA学习,MySQL学习,第三方应用探索,且MySQL学习和第三方应用探索各有一个下拉菜单。再回头看代码清单可以看到,其实MySQL学习的下拉菜单,就是zero和high两个子文件夹,显示内容为/docs/.vuepress/nav.js中配置的text
{ text: 'MySQL学习', link: '/mysql/', items: [ // 选择初级开发,将打开mysql文件夹中的zero文件夹,显示README.md中的内容 {text: '初级开发篇', link: '/mysql/zero/'}, // 逻辑同上 {text: '中高进阶篇', link: '/mysql/high/'}, ] }
第三方应用探索就不用我多说了,直接看/docs/.vuepress/nav.js就可以理解
{ text: '第三方应用探索', items: [ { text: '在线编辑', items: [ // 这里和MySQL学习部分有所不同,这里的links是打开第三方网站,而不是打开本地目录 {text: '图片压缩', link: 'https://tinypng.com/'} ] }, { text: '在线服务', items: [ {text: '阿里云', link: 'https://www.aliyun.com/'}, {text: '腾讯云', link: 'https://cloud.tencent.com/'} ] }, { text: '博客指南', items: [ {text: '掘金', link: 'https://juejin.im/'}, {text: 'CSDN', link: 'https://blog.csdn.net/'} ] } ] }
总结,在添加一个导航或者一个md文件的时候,自己需要对侧边栏进行简单配置,在所在文件夹中的sidebar中添加配置即可。在新增一个导航栏的时候,创建子文件夹的同时,不仅需要在当前文件夹中配置,还需要在docs/sidebar.js中引入新增的sidebar。其实本来有一个自动生成sidebar的插件的,我也使用了一下,但开源的东西,往往都会有很多坑需要去踩,效果差强人意,所以我还是选择了自己手动配置导航栏,和侧边栏这种自定义程度更高的方式,就当学习vue了。接下来的话,我会讲讲如何将代码部署到服务器上,但在这之前,你可以在本地新增一个导航栏,或者新增一个侧边栏,进行简单测试。
# 部署
部署的话,我们这里选择打包成镜像,用docker的方式去部署
将代码克隆到服务器上,并打开代码的根目录
这里首先要提到的是刚才在目录中列出来,却没有在代码清单中列出来的Dockerfile和deploy.sh
- Dockerfile
# 来源一个基础镜像,这里我们选择nginx # 由于nginx官方镜像下载较慢,在这之前,我已经将镜像上传到我自己的阿里云镜像仓库中 FROM registry.cn-hangzhou.aliyuncs.com/liuxiaoluxx/nginx:1.18 MAINTAINER liuxiaoluxx@gmail.com # 将打包的内容放进nginx的 ADD ./dist /usr/share/nginx/html EXPOSE 80
- deploy.sh
# 打包, 需要已有node环境 npm install && npm run docs:build # 强制移除容器,不存在也不会报错 docker rm -vf my-doc # 移除已构建的镜像 docker rmi -f doc:v1.0 # 构建镜像,注意最后的.很重要,不能遗漏 docker build -t doc:v1.0 . # 运行 docker run -it -d --name my-doc -p 80:80 doc:v1.0
给deploy.sh授权,执行命令
chmod 777 deploy.sh
运行脚本,执行命令
./deploy.sh
完成上诉步骤后,执行
docker ps
命令就可以查看到运行中的容器了liuxiaoluxx ~: docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES caf3b4ca1764 doc:v1.0 "/docker-entrypoint.…" 7 seconds ago Up 6 seconds 0.0.0.0:80->80/tcp my-doc
本次构建选择的是nginx作为基础镜像,监听80端口,所以直接访问
http://服务器地址
,即可看到部署完成的博客
# 总结
到这里结束了,当然你也可以选择将代码部署到github或者其他托管静态资源的网站,这个我也没研究过,所以直接百度教程即可。