# 搭建一个vuepress博客,并使用容器化的方式部署

# 前言

我尝试过很多次搭建博客,像是hexo,wordpress,也试过写公众号,或者说是使用一些第三方的软件,像是印象笔记(当然不用主要是因为它同步收费),微软的OneNotes,要么就是疲于改格式,要么就是使用不便,自从看到这个vuepress,我就觉得,嗯,就是它了。

# 我认为vuepress的几个优点

  1. 简洁
  2. 方便,直接上传md文件即可
  3. 自定义程度高,其实就是vue开发,vuepress不过是其中的一个依赖而已
  4. 支持全文检索【通过第三方依赖添加】,这在我看来是最重要的功能
  5. 屏幕自适应,不管是电脑,平板,手机都可以查看,那么如果想到一个东西,只要手边有手机,随时随地都可以查看博客中的内容,也能快速搜索
  6. ......(想到再补充)

那么,我们开始吧。

【前提条件】node版本大于12,部署博客的服务器。如果没有服务器,用github,或者其他托管静态资源的网站都行,但这种部署方式我们在文中不做讨论。本文主要针对有服务器的同学,并有一定的docker容器化知识的基础。至于为什么选择docker,我也不用多说了,沙箱隔离,一致性,好处很多。

  1. 创建并进入文件夹vuepress-starter

    mkdir vuepress-starter && cd vuepress-starter
    
  2. 使用npm进行初始化

    npm init
    
  3. 将 VuePress 安装为本地依赖

    npm install -D vuepress
    
  4. 在package.json中添加脚本

cp -R myPlugins ./dist意为把自己的依赖拷进最后打好的包中,不拷进去的话,通过build出来的版本全文检索会失败

{
  "scripts": {
    "docs:dev": "vuepress dev docs",
    "docs:build": "vuepress build docs && cp -R myPlugins ./dist"
  }
}
  1. 创建你的第一篇文档

    mkdir docs && echo '# Hello VuePress' > docs/README.md
    
  2. 这个时候,博客已经可以启动了,执行命令npm run docs:dev即可,但这个时候你看的博客是一个啥也没有空白博客,就像下图所示

img

  1. 我们来添加一些内容

    在这之前,我给大家看看我的目录结构

    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页面了

  2. 代码清单

    • /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"
        }
      }
      
  3. 将此代码清单写入你自己的工程之后,在terminal中执行npm install && npm run docs:dev,再次打开首页,就可以看到首页已经显示正常了,且顶部一共有四个导航栏,首页JAVA学习MySQL学习第三方应用探索,且MySQL学习第三方应用探索各有一个下拉菜单。 img.png img.png img.png

    再回头看代码清单可以看到,其实MySQL学习的下拉菜单,就是zerohigh两个子文件夹,显示内容为/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/'}
                    ]
                }
            ]
        }
    
  4. 总结,在添加一个导航或者一个md文件的时候,自己需要对侧边栏进行简单配置,在所在文件夹中的sidebar中添加配置即可。在新增一个导航栏的时候,创建子文件夹的同时,不仅需要在当前文件夹中配置,还需要在docs/sidebar.js中引入新增的sidebar。其实本来有一个自动生成sidebar的插件的,我也使用了一下,但开源的东西,往往都会有很多坑需要去踩,效果差强人意,所以我还是选择了自己手动配置导航栏,和侧边栏这种自定义程度更高的方式,就当学习vue了。接下来的话,我会讲讲如何将代码部署到服务器上,但在这之前,你可以在本地新增一个导航栏,或者新增一个侧边栏,进行简单测试。

# 部署

  1. 部署的话,我们这里选择打包成镜像,用docker的方式去部署

  2. 将代码克隆到服务器上,并打开代码的根目录

  3. 这里首先要提到的是刚才在目录中列出来,却没有在代码清单中列出来的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
    
  4. 给deploy.sh授权,执行命令chmod 777 deploy.sh

  5. 运行脚本,执行命令./deploy.sh

  6. 完成上诉步骤后,执行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
    
  7. 本次构建选择的是nginx作为基础镜像,监听80端口,所以直接访问http://服务器地址,即可看到部署完成的博客

# 总结

到这里结束了,当然你也可以选择将代码部署到github或者其他托管静态资源的网站,这个我也没研究过,所以直接百度教程即可。

Last Updated: 6/26/2022, 4:44:06 PM