使用Hexo搭建博客之进阶篇

简介

  • HexoA fast, simple & powerful blog framework,即一个快速、简单且强大的博客框架
  • Hexo的简单之处在于你可以用30分钟,甚至更短的时间就可以生成一个属于你自己的博客。
  • Hexo的强大之处在于你对博客界面细节的调整,有可能用上1天的时间。
  • 在进阶篇中,我着重介绍如何方便的部署博客及迁移博客。

起因

  • 每次更换电脑以后,为了写博客就必须去安装Hexo,这么繁琐的工作,不愿意重复花时间完成,故封装了docker-hexodocker-nginx镜像。
  • 使用Docker封装镜像后,可以很方便的利用Docker跨平台的特性,在Linux上安装Docker
  • 由于本文涉及的LinuxDocker知识较多,建议量力而行。

备份/迁移博客

  • 如果想要很方便的迁移博客或者部署博客,需要我们将博客的原始文件进行远程备份,GitHub成为了我们的首选。
  • 使用Hexo搭建博客之基础篇中,我们了解了Hexo相关目录及文件的作用。
  • 此处,我采用将博客的原始文件托管到GitHub管理,渲染后的文件放在云服务器上,以供他人访问。
  • 其中需要备份的文件:全局配置文件(_config.yml)和source目录,而主题(themes)目录则是在每次迁移博客后,重新拉取。
  • 正如我的GitHub上一样,而多出的backup目录和README.md文件是为了方便我自己迁移博客。

备份博客

  • GitHub上新建一个仓库,例如:blog
  • 在本地新建一个与GitHub仓库同名的目录:
1
mkdir -p /blog
  • 拷贝我们需要备份的目录及文件到此目录:
1
2
cp _config.yml /blog/
cp -r source/ /blog/
  • 若你的主题自定义过多且不考虑升级,建议同时备份到GitHub上,注意删除对应主题下有关git的目录及文件。
1
2
cp -r themes/ /blog/
rm -rf /blog/themes/next/.git*
  • 配置Git的基本信息:
1
2
git init
git remote add origin git@github.com:YuXiaoCoder/blog.git
  • 上传到GitHub仓库:
1
2
3
git add --all
git commit -a -m '07/15/2018'
git push --set-upstream origin master
  • 以后更新博客内容以后,记得不仅要deploy,还要commitGitHub上。

迁移博客

  • 当换了新的环境以后,先配置好可以免密访问GitHub
  • 然后,将备份的博客拉取到本地即可。

docker-hexo

  • 其实,Docker的作用就是帮我们把hexo及依赖插件与博客的原始文件进行了分离。

构建镜像

  • 方式一:通过URL构建镜像, 已知在CentOS云主机上无法使用:
1
docker build --no-cache -t docker-hexo https://github.com/YuXiaoCoder/docker-hexo.git#stable
  • 方式二:通过本地构建镜像, 先clone仓库到本地, 再构建镜像:
1
2
3
git clone https://github.com/YuXiaoCoder/docker-hexo.git
cd docker-hexo/
./tools/build_images.sh

配置环境变量

  • 配置Linux的环境变量,为之后创建容器提供方便:
1
2
3
4
5
echo 'export BlogRoot="/opt/blog"' >> /etc/profile
echo 'export BlogPort=80' >> /etc/profile
echo 'export GitHub_Name="YuXiaoCoder"' >> /etc/profile
echo 'export GitHub_Email="xiao.950901@gmail.com"' >> /etc/profile
source /etc/profile

创建Web容器

  • 此容器用于Hexo博客的预览,相当于hexo server命令。
  • 参数释义:
    • ${BlogPort}:博客的端口,此处将物理机的指定端口映射到容器的80端口,使得我们直接访问物理机的端口就能预览博客。
    • ${BlogRoot}:博客的根目录,此处将物理机中博客根目录下的指定文件映射到容器中,使得容器能够访问到博客的原始文件及配置。
    • ${GitHub_Name}:传递GitHub的名称到容器中。
    • ${GitHub_Email}:传递GitHub的邮箱地址到容器中。
1
2
3
4
5
6
7
8
9
docker run -dit -p ${BlogPort}:80 --name "hexo-server" \
-v ${BlogRoot}/source:/blog/source \
-v ${BlogRoot}/themes:/blog/themes \
-v ${BlogRoot}/_config.yml:/blog/_config.yml \
--restart=always \
docker-hexo \
${GitHub_Name} \
${GitHub_Email} \
server

创建Deploy容器

  • 此容器用于Hexo博客的部署,相当于hexo deploy -g命令。
  • 参数释义:
    • ${BlogRoot}:博客的根目录,此处将物理机中博客根目录下的指定文件映射到容器中,使得容器能够访问到博客的原始文件及配置。
    • ${GitHub_Name}:传递GitHub的名称到容器中。
    • ${GitHub_Email}:传递GitHub的邮箱地址到容器中。
    • /root/.ssh:由于是部署博客,所以需要映射密钥文件到容器中。
1
2
3
4
5
6
7
8
9
docker run -d --name "hexo-deploy" \
-v ${BlogRoot}/source:/blog/source \
-v ${BlogRoot}/themes:/blog/themes \
-v ${BlogRoot}/_config.yml:/blog/_config.yml \
-v /root/.ssh:/root/.ssh \
docker-hexo \
${GitHub_Name} \
${GitHub_Email} \
deploy

设置命令别名

  • 由于封装了docker-hexo镜像,导致我们物理机中没有hexo命令,命令别名的目的就在于让我们更方便的使用hexo命令。
  • 此命令实际上是创建了一个一次性的Docker容器。
1
2
echo 'alias hexo="docker run -it --rm -v ${BlogRoot}/source:/blog/source -v ${BlogRoot}/themes:/blog/themes -v ${BlogRoot}/_config.yml:/blog/_config.yml docker-hexo /usr/local/bin/hexo"' >> /etc/profile
source /etc/profile

常见操作

创建新的文章

  • 由于我们设置了命令别名,此处的使用方法和未封装docker-hexo镜像的一致。
1
hexo new NAME

重启Web容器

  • 由于我们更新了博客内容之后,可能Hexo没有及时更新,需要我们手动重启Web容器(预览服务)。
1
docker restart hexo-server

启动Deploy容器

  • 当我们每次想要部署博客时,只需要启动Deploy容器即可,相当于hexo clean && hexo deploy -g命令。
1
hexo start hexo-deploy

docker-nginx

  • 若博客使用的是GitHub Pages,则无需阅读此部分的内容。
  • 为了方便云服务器部署并升级Nginx, 故封装了docker-nginx镜像。
  • 本镜像仅开放了80端口及443端口(若需要),请自行理解docker的端口映射及目录映射。

构建镜像

  • 方式一:通过URL构建镜像, 已知在CentOS云主机上无法使用:
1
docker build --no-cache -t docker-nginx https://github.com/YuXiaoCoder/docker-nginx.git#stable
  • 方式二:通过本地构建镜像, 先clone仓库到本地, 再构建镜像:
1
2
3
git clone https://github.com/YuXiaoCoder/docker-nginx.git
cd docker-nginx/
./tools/build_images.sh

运行Web-Http容器

配置环境变量

  • 设置映射端口号, 配置文件目录:
1
2
3
4
5
6
7
sed -i '/NGINX_ROOT/d' /etc/profile
sed -i '/NGINX_HTTP_PORT/d' /etc/profile
sed -i '/NGINX_CONFD/d' /etc/profile
echo 'export NGINX_ROOT="/data/www/"' >> /etc/profile
echo 'export NGINX_HTTP_PORT=80' >> /etc/profile
echo 'export NGINX_CONFD="/etc/nginx/conf.d/"' >> /etc/profile
source /etc/profile
  • 已经在镜像中了优化nginx.conf配置, 若仍需自定义, 请自行配置:
1
2
sed -i '/NGINX_CONF/d' /etc/profile
echo 'export NGINX_CONF="/etc/nginx/nginx.conf"' >> /etc/profile

创建配置文件

  • 创建blog.conf配置文件(请勿修改监听端口及根目录), 可以参考conf/nginx目录中的配置文件:
1
2
mkdir -p /etc/nginx/conf.d/
vim /etc/nginx/conf.d/blog.conf
1
2
3
4
5
6
7
8
9
10
server {
listen 80;
server_name www.xiaocoder.com;
access_log /var/log/nginx/default.access.log main;

location / {
root /data/www/;
index index.html index.htm;
}
}
  • 在物理机上创建根目录:
1
mkdir -p /data/www/
  • 部署博客内容到根目录。

运行容器

  • 运行nginx-server容器,此处仅映射了80端口:
1
2
3
4
5
6
7
docker run -d \
--name "nginx-server" \
-p ${NGINX_PORT}:80 \
-v ${NGINX_ROOT}:/data/www:ro \
-v ${NGINX_CONFD}:/etc/nginx/conf.d/:ro \
--restart=always \
docker-nginx
  • 如需加载自行配置的nginx.conf, 请加如下参数:
1
-v ${NGINX_CONF}:/etc/nginx/nginx.conf:ro
  • 如需访问日志文件, 请加如下参数:
1
-v /var/log/nginx/:/var/log/nginx/

运行Web-Https容器

配置环境变量

  • 设置映射端口号, 配置文件目录及证书目录:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
sed -i '/NGINX_ROOT/d' /etc/profile
sed -i '/NGINX_HTTP_PORT/d' /etc/profile
sed -i '/NGINX_HTTPS_PORT/d' /etc/profile
sed -i '/NGINX_CONFD/d' /etc/profile
sed -i '/LETSENCRYPT_DIR/d' /etc/profile
sed -i '/SSL_DIR/d' /etc/profile
sed -i '/PKI_DIR/d' /etc/profile
sed -i '/NGINX_LOG/d' /etc/profile
echo 'export NGINX_ROOT="/data/www/"' >> /etc/profile
echo 'export NGINX_HTTP_PORT=80' >> /etc/profile
echo 'export NGINX_HTTPS_PORT=443' >> /etc/profile
echo 'export NGINX_CONFD="/etc/nginx/conf.d/"' >> /etc/profile
echo 'export LETSENCRYPT_DIR="/etc/letsencrypt/"' >> /etc/profile
echo 'export SSL_DIR="/etc/ssl/"' >> /etc/profile
echo 'export PKI_DIR="/etc/pki/"' >> /etc/profile
echo 'export NGINX_LOG="/var/log/nginx/"' >> /etc/profile
source /etc/profile
  • 初始化目录:
1
2
mkdir -p /etc/nginx/conf.d/
mkdir -p /var/log/nginx/

申请证书

1
yum install -y vim bash-completion git-core certbot
  • 配置环境语言:
1
2
export LANG=en_US.UTF-8
echo 'LANG="en_US.UTF-8"' > /etc/locale.conf
  • 运行一个nginx服务证明域名所有权:
1
2
mkdir -p /etc/nginx/conf.d/
vim /etc/nginx/conf.d/blog.conf
1
2
3
4
5
6
7
8
9
10
11
12
server {
listen 80;
server_name www.xiaocoder.com;
location ~ /.well-known/acme-challenge {
allow all;
}

location / {
root /data/www/;
index index.html index.htm;
}
}
1
2
3
4
5
6
7
docker run -d --rm \
--name "nginx-server" \
-p ${NGINX_HTTP_PORT}:80 \
-v ${NGINX_ROOT}:/data/www:ro \
-v ${NGINX_CONFD}:/etc/nginx/conf.d/:ro \
--restart=always \
docker-nginx
  • 申请证书:
1
certbot certonly --webroot -w /data/www -d www.xiaocoder.com -d www.xiaocoder.cn --agree-tos --email xiao.950901@gmail.com
1
docker stop nginx-server

创建配置文件

1
vim /etc/nginx/conf.d/blog.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
server {
listen 80;
server_name www.xiaocoder.com;
location ~ /.well-known/acme-challenge {
allow all;
}
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name www.xiaocoder.com;
ssl_certificate /etc/letsencrypt/live/www.xiaocoder.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.xiaocoder.com/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_dhparam /etc/ssl/certs/dhparams.pem;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
ssl_prefer_server_ciphers on;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security max-age=15768000;
root /data/www;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
}
  • 在物理机上创建根目录:
1
mkdir -p /data/www/
  • 部署博客内容到根目录。

运行容器

  • 运行nginx-server容器,此处映射了80端口与443端口:
1
2
3
4
5
6
7
8
9
10
11
12
docker run -d \
--name "nginx-server" \
-p ${NGINX_HTTP_PORT}:80 \
-p ${NGINX_HTTPS_PORT}:443 \
-v ${NGINX_ROOT}:/data/www/:ro \
-v ${NGINX_CONFD}:/etc/nginx/conf.d/:ro \
-v ${LETSENCRYPT_DIR}:/etc/letsencrypt/:ro \
-v ${SSL_DIR}:/etc/ssl/:ro \
-v ${PKI_DIR}:/etc/pki/:ro \
-v ${NGINX_LOG}:/var/log/nginx/:rw \
--restart=always \
docker-nginx

部署完成

  • 设置定时更新证书并重启nginx服务:
1
crontab -e
1
2
30 3 * * 1 /usr/bin/certbot renew >> /var/log/le-renew.log
35 3 * * 1 docker restart nginx-server

有你就有世界,感谢有你,昕!
0%