Hexo @ Docker | 用Docker安装Hexo

0. 装一个Hexo的基本步骤

  1. 安装nodejs
  2. 全局方式安装hexo
  3. 初始化博客文件夹(hexo init)
  4. 开启服务(hexo server)

1. 用hexo自带的webserver安装

选择基础镜像

首先选一个基础镜像, 这里选择nodejs镜像的alpine版本:node:alpine.

FROM node:alpine

安装hexo

先切换到/blog作为当前工作目录, 然后安装hexo

WORKDIR /blog
RUN npm install hexo -g

初始化目录并生成静态文件

RUN hexo init&& hexo generate
# 声明暴露端口
EXPOSE 4000

将Hexo自带的webserver设为默认命令

CMD [ "hexo","server" ]

运行

直接build并执行即可, 记得打开端口映射到内部的4000 端口

docker build -t hexo .
docker run --name blog -p 4000:4000 hexo

构建完成后,打开http://localhost:4000

2. 用Nginx做webserver

在测试环境下使用hexo自带webserver是可以的, 但是生产环境中总觉得不妥. hexo生成的只有静态的文件, 故只需一个Nginx即可.

接下去在刚刚的dockerfile做修改.复制一份重名民为Dockerfile.nginx

去掉下面两行

EXPOSE 4000
CMD [ "hexo","server" ]

安装Nginx

直接用

RUN apk add nginx && mkdir /run/nginx

这里的mkdir /run/nginx是创建nginx.pid所在的目录, 不然Nginx无法启动成功.Nginx会往/run/nginx/nginx.pid写进自己的pid, 如果文件夹不存在的话就会报错

nginx: [emerg] open() "/run/nginx/nginx.pid" failed (2: No such file or directory)

我也不知道为什么Nginx装上去没有没自己创建好必要的文件夹

修改Nginx的根目录

默认的Nginx配置文件是直接返回404的, 我们需要去掉404代码并修改其根目录为/blog/public(hexo生成网页的目录).

默认的配置

        # Everything is a 404
        location / {
                return 404;
        }

修改为

        # Everything is a 404
        location / {
               root /blog/public;
        }

这里我们直接用sed命令来替换即可

RUN sed -i 's/return 404/root \/blog\/public/g' \
        /etc/nginx/conf.d/default.conf

添加默认命令并构建

默认命令直接用nginx是不行的, 因为nginx这个命令会自己退掉导致整个container退掉. 所以需要构造一个脚本在启动完nginx之后再持续运行. 这里使用简单的tail -f 输出日志来实现这个目的.

新建一个docker-entry.sh

#!/bin/sh
nginx
tail -f /var/log/nginx/access.log /var/log/nginx/error.log

然后在Dockerfile中加上以下代码即可

COPY docker-entry.sh /docker-entry.sh
EXPOSE 80
CMD [ "/docker-entry.sh" ]

构建运行

docker build -t hexo:nginx -f Dockerfile.nginx .
docker run --name hexo_nginx -p 4000:80 hexo:nginx

同样打开http://localhost:4000即可看到结果

让Dockerfile更加适合生产环境

这里我们的Hexo是在构建时就已经装好并初始化在了/blog文件夹中了, 但是如果我们想在启动的时候将本地文件夹映射到/blog上(这种时候docker就只是一个运行环境)的时候就不能用了. 比如我希望将blog的数据单独拿出来托管的时候就会遇到这个问题. 解决办法是让hexo在运行的时候再去决定要不要初始化目录. 这个就需要我们将hexo的初始化步骤移到docker-entry.sh里面了.

脚本修改如下:

Dockerfile

FROM node:alpine
WORKDIR /blog
RUN apk add nginx&& mkdir /var/run/nginx &&\
    sed -i 's/return 404/root \/blog\/public/g' \/etc/nginx/conf.d/default.conf  &&\
    npm install hexo -g
COPY docker-entry.sh /docker-entry.sh
EXPOSE 80
CMD ["/docker-entry.sh"]

docker-entry.sh

#!/bin/sh
content=$(ls -A /blog)
if [ -z $content ] ;then
    # empty blog folder
    echo Initing Hexo...
    hexo init /blog 
else
    echo "Skipping init."
fi
cd /blog && hexo generate
nginx
tail -f /var/log/nginx/access.log /var/log/nginx/error.log

测试执行

docker build -f Dockerfile.nginx -t hexo:nginx .
docker run --name hexo_nginx -it -p 4000:80 -v (pwd)/blog:/blog hexo:nginx

成功运行的截图

{% asset_img hexo.png success %}

Dockerfile 托管到了github上.

See Also

  1. WordPress @ Docker | 用Docker安装WordPress
  2. Setup|Hexo
  3. hexo_with_docker

Last modified on 2019-04-10