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 
时间: 2024-12-09 09:55:37

Hexo 升级与 Docker 初体验的相关文章

iPhone 4s 升级 iOS 8 初体验 - iPhone 4s 运行 iOS 8 到底卡不卡?

class="post_content" itemprop="articleBody"> 9月10日凌晨1点苹果正式推出了 iPhone 6 与 iPhone 6 Plus,与这两款新机一同来临的还有 iOS 8 正式版,在北京时间9月18日凌晨,苹果正式向用户推送了 iOS 8 正式版操作系统-- iOS 8 系统在手机方面仅支持 iPhone 4S及 以上的设备,不少用户都担心 iPhone 4S 升级到 iOS 8 之后会被系统拖慢,那么究竟如何呢?我们

Docker的Windows容器初体验

系列文章 第一篇 Docker的Windows容器初体验 - 本文 第二篇 阿里云Windows Server 2016环境Docker试用 最近微软发布了Windows Server 2016,其中最让广大开发者和运维同学期待的就是Docker对Windows容器的支持. Windows支持两种不同类型的容器,即 Windows Server 容器和 Hyper V 容器. 这两种类型的容器的使用方式相同,也支持相同的容器映像. 但是它们的实现机制不同,提供了不同的安全隔离级别 Windows

Docker 容器初体验

Docker 容器初体验 在本文中,我们将迈出使用Docker的第一步,学习第一个Docker容器.本章还会介绍如何与Docker进行交互的基本知识. 1 确保Docker已经就绪 首先,我们会查看Docker是否能正常工作,然后学习基本的Docker的工作流:创建并管理容器.我们将浏览容器的典型生命周期:从创建.管理到停止,直到最终删除. 第一步,查看docker程序是否存在,功能是否正常,如代码清单3-1所示. 代码清单3-1 查看docker程序是否正常工作 $ sudo docker i

Docker管理工具Shipyard初体验

本文讲的是Docker管理工具Shipyard初体验,[编者的话]Shipyard是一个Docker管理工具,有WEB界面也可以通过CLI来管理Docker主机.镜像.容器 .要方便的管理Docker相关服务,基于Web的方式来管理肯定是首选.本文介绍了Shipyard的使用方式. Shipyard是一个Docker的管理工具,你可以用它管理在不同机器上Docker镜像和容器的部署,但是在本篇博文中,我将会向你展示如何在你的本地机器上使用Shipyard. 在你机器上安装Shipyard的时候会

DockerCon 2017: Docker新特性初体验

DockerCon2017已经结束了,从去年的版本到现在,Docker产生了很多的变化.Docker的开发者们一直强调他们希望Docker的体验越简单越好.观察下最近几个月Docker的新特性,你会发现所言非虚,DockerCon2017大会也向我们展示了这一点.下面介绍下Docker最近几个月发布的新特性 多阶段构建 构建一个镜像一般需要多个阶段. 编译你的应用 然后跑测试 当测试通过时,你将你的应用打包成可部署的软件包 最后你把软件包添加到镜像里面 你可以将这些步骤都放进一个Dockerfi

新手RoR十分钟初体验Step By Step

http://yulimin.javaeye.com/blog/35929 关键字: rails   Ruby Rails RoR     新手RoR十分钟初体验Step By Step 声明一下,这是个新手启动的体验文章,高手不要看了...:) 1.安装RubyWindows用户去 http://rubyforge.org/ 的 http://rubyforge.org/projects/rubyinstaller/ 下载 One-Click Installer - Windows 安装即可,

Java8初体验(一)lambda表达式语法

感谢同事[天锦]的投稿.投稿请联系 tengfei@ifeve.com 本文主要记录自己学习Java8的历程,方便大家一起探讨和自己的备忘.因为本人也是刚刚开始学习Java8,所以文中肯定有错误和理解偏差的地方,希望大家帮忙指出,我会持续修改和优化.本文是该系列的第一篇,主要介绍Java8对屌丝码农最有吸引力的一个特性-lambda表达式. java8的安装 工欲善其器必先利其器,首先安装JDK8.过程省略,大家应该都可以自己搞定.但是有一点这里强调一下(Windows系统):目前我们工作的版本

下一代动态网络分析工具FakeNet-NG的Linux平台初体验

本文讲的是下一代动态网络分析工具FakeNet-NG的Linux平台初体验, 在2016年,FLARE推出了一款用Python编写的开源网络分析工具FakeNet-NG. FakeNet-NG允许安全分析人员在单个Windows主机上使用标准或自定义协议来观察网络应用程序并与其进行交互,这对恶意软件分析和逆向工程特别有用.自从FakeNet-NG的推出以来,FLARE又对其进行了一些升级,比如增加了对附加协议的支持. FakeNet-NG现在具有DNS,HTTP(包括BITS),FTP,TFTP

DockOne微信分享(七十六):容器化ICT融合初体验

本文讲的是DockOne微信分享(七十六):容器化ICT融合初体验[编者的话]本次将分享的容器化ICT融合平台是一种面向未来ICT系统的新型云计算PaaS平台,它基于容器这一轻量级的虚拟化技术以及自动化的"微服务"管理架构,能够有效支撑应用快速上线和自动扩缩容,最大化IT基础设施资源利用率并降低总体拥有成本(TCO).未来的网络正在向IT化.云化方向发展,容器与微服务技术,完美契合"网络即服务".网络切片等发展理念,将有助于实现更加灵活.智能.高效和开放的5G新型网