Hexo 升级与 Docker 初体验

简介:

背景

之前我一直使用 Hexo 2.8 来编译我的博客。几个星期前的一天,我突发奇想要给 Hexo 来个升级,于是接下来的折腾就开始了。

执行了 npm install hexo-cli -g 之后,一切都还好,当我试着执行hexo server 启动服务器的时候,悲剧发生了,没法启动。一番 Google 之后发现从 2.8 升级到 3.0 似乎没那么平滑,于是我决定降回 2.8,然后另选时间升级。

降级之路也不平坦,即使我显式给出了降级之后各个组件的版本,整个依赖树也回不到从前了。可能这个也是 npm 包管理体系的特 (quē) 性 (xiàn) 吧,大家都不太会在依赖中显式的写出某个指定的版本,反而比较喜欢使用版本范围,据说这样子能够自动获取依赖包升级之后的 bug fix 和性能提升[1]

不管怎么说,这样折腾一番之后,我的 Hexo 博客环境没有之前好用了。看来 2.8 已经没法待下去了,只有升级到 3.0 这条路。

Docker

虽然博客环境没有之前好用,但是它至少还是能够磕磕绊绊把我的博客编译部署的。我希望至少在我升级的时候,我还能使用现在的博客环境。

之前用 Python 的时候,有一个叫 Virtualenv 的神器,可以在系统中部署多套隔离的 Python 环境,我的电脑里就用它弄了两套完全隔离的环境,一套是 Py27,一套是 Pypy。似乎 Node.js 生态圈中还没有类似的工具。问题在于 hexo 必须安装到全局目录才能作为命令使用,一旦全局安装 Hexo 3.0,势必覆盖 2.8 版本。

如果在过去,我可能会弄一个 Linux 的虚拟机来安装 Hexo 3.0。在容器技术如火如荼的今天,开个虚拟机就为了用 Linux 显得不合时宜而又可笑,仿佛从几年之前穿越过来的。半年前我就在电脑上安装了 Docker,用的是 boot2docker,文档也看了好几篇,但是一直没有认真用过,只是凑个热闹,假装自己紧跟技术潮流。

这次,我要正正经经的用一次 Docker,至少构建一个包含完整 Hexo 3.0 环境的镜像。

其实 OS X 上有一个看起来还算不错的 Docker GUI 前端,叫 Kitematic,对命令行无爱的话可以试试(对命令行无爱的人得有多大的勇气才能使用 Docker)。

一番折腾之后,我对 Docker 也算有了一些感觉,总体来说体验不错。Docker 的概念中,容器、镜像等等还挺有意思的。

简单用程序来打个比方,也许不是那么贴切。我们用 Dockerfile 来描述镜像的构建过程,就好像我们用高级语言来描述程序的执行过程;当我们根据 Dockerfile 来构建镜像,就仿佛用编译器把代码编译成可执行文件;当我们把镜像跑起来,容器就产生了,就仿佛可执行文件一旦执行,进程就出现了。

个把小时之后,我成功使用 Docker 基于 ubuntu:14.04 构建出了一个 Hexo 镜像,第二天晚上我成功在镜像中完成了 Hexo 的升级尝试,并把我的博客环境也升级到了 Hexo 3.0。

镜像

折腾的过程当然不会像我写的这么顺利,这里把一些重要的过程做个记录。

Docker 和 boot2docker 的安装过程这里就不说了,直接参考 Docker Documentation

写 Dockerfile 的要点可以参考 Best practices for writing Dockerfiles,但是写好的 Dockerfile 该怎怎么用,我翻来覆去看了好多遍文档才找到比较科学的方法。

一般来说使用 docker build 的时候,需要传一个保存有名为 “Dockerfile” 的文件的路径作为参数。这种方式的优点是有一个构建的环境,即 Dockerfile 所在的目录,docker 可以在构建的时候使用这个环境中的文件[2]

对于我构建 Hexo 镜像来说,我不需要这样的构建环境,直接使用重定向把 Dockerfile 传递给 docker 是一个相对更好的选择。

于是我可以随意给 Dockerfile 命名,然后用下面的命令来构建镜像。

docker build -t jamespan/hexo - < path-to-hexo-docker-file
镜像构建完成之后,我可以用下面的命令把镜像跑起来,使用 --rm 参数能够在我退出容器之后自动删除容器,使用 -v 参数能够挂载数据卷,把本地的目录或文件 mount 到容器中,使用 -p 参数能够绑定端口,-t 和 -i 参数经常一起使用,可以给 docker 分配一个虚拟终端,然后一直等待标准输入,像一个 shell 一样工作 [3]
docker run -it --rm -p 4000:4000 \
   -v path-to-source:/root/blog/source \
   -v path-to-theme:/root/blog/themes \
   -v path-to-config.yml:/root/blog/_config.yml \
   jamespan/hexo /bin/bash

Hexo 的用户应该知道,我们实际上需要关心的,就是两个目录一个文件:source 目录存放我们的博文、页面等,是博客内容;themes 目录存放主题,是博客的样式;_config.yml 是整个博客的配置,记录一些重要的变量,定义各种插件的行为。

理论上我们能够做到使用容器运行一个安装了必要插件的 Hexo 环境,然后挂载这些目录和文件到正确的目录,就能使用容器为我们提供标准的 Hexo 服务。

Hexo

我以 ubuntu:14.04 为基础构建我的镜像,Dockerfile 保存在了 Gist,点此访问

FROM ubuntu:14.04
 
MAINTAINER Pan Jiabang, panjiabang@gmail.com
 
RUN \
  # use aliyun's mirror for faster download speed
  sed -i 's/archive.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list && \
  apt-get update && \
  apt-get install -y nodejs curl git-core && \
  # use nodejs as node 
  update-alternatives --install /usr/bin/node node /usr/bin/nodejs 10 && \
  # install npm
  curl -L https://npmjs.org/install.sh | sh && \
  # clean up install cache
  apt-get clean && \
  rm -rf /var/lib/apt/lists/*

WORKDIR /root
 
RUN \
  mkdir blog && cd blog && \
  # install hexo
  npm install hexo-cli -g && \
  hexo init && npm install && \
  # install plugins for hexo
  npm install hexo-generator-sitemap --save && \
  npm install hexo-generator-feed --save && \
  npm install hexo-deployer-git --save && \
  npm un hexo-renderer-marked --save && \
  npm i hexo-renderer-markdown-it --save
 
WORKDIR /root/blog/
 
VOLUME ["/root/blog/source"]
VOLUME ["/root/blog/themes"]
 
EXPOSE 4000
 
CMD ["/bin/bash"]

从 ubuntu 开始,先是更换软件源,使用阿里云的镜像,这样子安装软件的速度会快很多。然后就是安装 nodejs、curl 和 git。curl 后面安装 npm 的时候会用到。我之所以没有选择从软件源安装 npm,是因为那样子会顺带安装上很多 *-dev 的包,而我仅仅是搭建 Hexo 环境而已,不需要那些东西的。

接下来一大段脚本是安装 Hexo 及其插件,还有初始化博客目录。最后是声明目录挂载点。

基本上整个镜像的构建脚本都在这里了。

升级

在 Docker 中尝试安装 Hexo 3.0 是一边调试、部署一边记录,最后把执行过的命令整理成 Dockerfile 的。

调试过程中发现一个有趣的问题,之前使用 Hexo 2.8 的时候,我在编辑器中修改了文件,hexo server 会感知文件变化,然后自动更新静态博客。我在 Docker 中挂载 source 目录然后启动 hexo server,从浏览器访问页面一切都正常,唯独我在编辑器中修改了内容,服务器没有自动更新博客内容,必须让我手动停止然后再重新启动 hexo server。

如果我真正安装 Hexo 3.0 之后也是这种情况,那是没法接受的,我开始查找原因。中间绕了不少弯路,最后查看 npm 安装日志发现是一个叫 fsevents 的可选依赖没有安装。

我想,如果我能够把 fsevents 成功安装,应该就没问题了。谁知道我各种姿势尝试安装之后,还是失败了。查看 fsevents 之后发现这是一个专门用来监听 OS X 系统文件变化的类库。在 Linux 上没法安装一个 OS X 专用类库也是合理的。

好像除了监听文件变化在 Docker 中没法测试之外,其他一切都还好。于是我花了几分钟,把本机博客目录的 node_modules 目录和 package.json 备份之后,升级了 Hexo。

要说这次升级一点后遗症都没有,那是不可能的。不过总体来说,升级到 3.0 之后整体上感觉还是不错的,至少修复了之前困扰我多时的文章发布日期偏移的 bug,代价是我把评论系统从漏洞百出的多说换成了 DISQUS,感觉整个博客瞬间和国际接轨了,萌萌哒~

要不我试着用英文写博客?


  1. 如何使用NPM来管理你的Node.js依赖 

  2. Docker command line - build 

  3. Docker run reference - Foreground 

目录
相关文章
|
3月前
|
Docker 容器
解决升级 win10 中的 docker desktop 2.3.0.x 后无法启动
解决升级 win10 中的 docker desktop 2.3.0.x 后无法启动
|
6月前
|
数据库 Docker 容器
Docker版TDengine2.6升级到Tdengine3.0
请注意,这些步骤提供了一般的升级指南。具体的升级过程可能因你的环境和配置而异。在进行升级之前,建议查阅TDengine官方文档和Docker镜像的相关文档,以获取更详细的升级和配置信息。
148 5
|
Java Linux Shell
centos7内网离线安装face_recognition、python、pip、CMake、dlib,离线升级gcc/切换gcc,文末有face_recognition的docker版本
公司项目需要人脸识别,本来app自带人脸识别,结果api支持的设备试了一圈就一个同事的华为Mate40Pro可以,所以使用无望。接着找了一下免费的java离线人脸识别sdk,发现虹软的确实简单好用,一会就在linux上弄好并测试通过了,然而在准备集成进去开写代码时,不小心看到了一眼首次激活需联网,后续方可离线使用,好吧,我们内网机器首次都不可能的,接着看了下离线激活方法,首先需要企业认证,这一步我们肯定没法做的,毕竟不是之前的小公司了,营业执照啥的随便给我肯定不行,直接放弃了。后来在同事推荐下看了下face_recognition这个项目,之前基本没用过python,于是有了漫长的踩坑之旅。
698 1
|
Kubernetes Java Maven
阿里云云效流水线中的Java构建Docker镜像并推送到镜像仓库和Kubernetes镜像升级这两个节点的区别
阿里云云效流水线中的Java构建Docker镜像并推送到镜像仓库和Kubernetes镜像升级这两个节点的区别
624 1
H8
|
安全 网络协议 Shell
Docker 枚举、特权升级和容器逃逸 (DEEPCE)
为了使其与最大数量的容器兼容,DEEPCE 是纯编写的sh,没有依赖性。如果可用,它将使用其他工具,例如 curl、nmap、nslookup 和 dig,但在大多数情况下不依赖于它们进行枚举。 枚举都不应该触及磁盘,但是大多数漏洞利用会创建新的容器,这将导致磁盘写入,并且一些漏洞利用会覆盖 runC,这可能具有破坏性,所以要小心!
H8
193 0
|
存储 Docker 容器
Docker 安装与升级
/var/lib/docker/ 的内容,包括 image、container、volumes, and networks,将被保留。Docker 引擎包现在被称为 docker-ce。
137 0
|
Kubernetes Ubuntu 网络协议
Docker官方文档学习笔记(一):安装、升级、卸载Docker Desktop for Linux(和安装Docker Engine二选一,推荐Docker Engine)
Docker官方文档学习笔记(一):安装、升级、卸载Docker Desktop for Linux(和安装Docker Engine二选一,推荐Docker Engine)
958 1
Docker官方文档学习笔记(一):安装、升级、卸载Docker Desktop for Linux(和安装Docker Engine二选一,推荐Docker Engine)
|
jenkins 持续交付 Docker
docker 升级后或者重装后,启动容器提示:Error response from daemon: Unknown runtime specified docker-runc...
docker 升级后或者重装后,启动容器提示:Error response from daemon: Unknown runtime specified docker-runc...
669 0
docker 升级后或者重装后,启动容器提示:Error response from daemon: Unknown runtime specified docker-runc...
|
关系型数据库 数据库 时序数据库
docker安装的timescaledb升级注意事项
使用docker安装的timescaledb与postgresQL数据库。目前我们需要升级docker镜像以及目前正在使用的数据库。单纯的更换docker镜像是行不通的,请按照如下方式进行升级。 原版本是timescale/timescaledb-postgis:1.4.0-pg11 新版本是timescale/timescaledb-postgis:1.7.4-pg11
1118 0
|
Linux 开发工具 Docker
使用 Docker CLI 将 CE 引擎升级到 EE 引擎
Docker 船长 Sujay Pillai 使用 Docker CLI 将 CE 引擎升级到 EE 引擎。
2505 0