- 一、为什么要把博客容器化
- 二、看这个博客的依赖
- 三、Dockerfile:把 Jekyll 环境装进镜像
- 四、本地一键构建预览
- 五、GitHub Actions:提交即发布
- 六、进阶:本地磁盘缓存,别再重复 build
- 七、总结
上一篇我说”下一篇把这个博客本身容器化”。今天兑现。这个博客是 Jekyll + GitHub Pages,最大的痛点是什么?换电脑就得重装 Ruby、装一堆 gem、版本还对不上。把构建环境锁进 Docker 镜像里,从此”环境随镜像走”,任何机器
docker run就能构建。
一、为什么要把博客容器化
Jekyll 博客最常见的三个痛点:
- 环境地狱:Ruby 版本、
jekyll、rouge、jekyll-paginate每个都要装对,macOS 自带 Ruby 还经常和系统版本冲突; - 构建不一致:本地
jekyll build正常,CI 里跑却报错——因为环境不同; - 换机器即灾难:新电脑从零配置环境动辄一小时。
容器化的价值一句话:构建环境变成镜像的一部分,本地、CI、服务器三处完全一致。这在《前端工程化与 CI/CD》里讲的”可复现的流水线”是同一个思想。
二、看这个博客的依赖
先看 _config.yml 里决定构建的关键点:
markdown: kramdown
kramdown:
input: GFM
syntax_highlighter: rouge
gems: [jekyll-paginate] # 老写法,等价于 plugins
paginate: 6
配套的 Gemfile(没有就建一个):
source 'https://rubygems.org'
gem 'jekyll', '~> 4.3'
gem 'jekyll-paginate'
gem 'kramdown-parser-gfm'
gem 'rouge'
你的
_config.yml里gems:是旧字段名,Jekyll 4 建议写成plugins:,效果一致。趁这次容器化一起升级,避免 Jekyll 打印 deprecation 警告。
三、Dockerfile:把 Jekyll 环境装进镜像
# Dockerfile —— Jekyll 博客构建镜像
FROM ruby:3.2-alpine
# 装构建 Jekyll 需要的系统库(nokogiri 等原生 gem 需要)
RUN apk add --no-cache build-base
WORKDIR /blog
# 先只拷贝 Gemfile,利用 Docker 层缓存:依赖不变就不重复装
COPY Gemfile Gemfile.lock ./
RUN bundle install
# 再拷贝整个博客源码
COPY . .
# 构建到 _site
RUN bundle exec jekyll build
# 用 nginx 托管静态产物
FROM nginx:1.27-alpine
COPY --from=0 /blog/_site /usr/share/nginx/html
EXPOSE 80
关键技巧:先拷
Gemfile再拷源码。Docker 会按层缓存,只要Gemfile没变,bundle install这一步就不会重跑,构建速度能提升一大截——这跟前端 Dockerfile 里”先COPY package*.json再RUN npm ci“是同一个优化思路。
四、本地一键构建预览
# 构建镜像
docker build -t my-blog:latest .
# 本地预览:容器内 nginx 直接提供博客
docker run -d --name my-blog -p 4000:80 my-blog:latest
open http://localhost:4000
以后换电脑,只需要 Docker 装好,docker run 立即可用——不需要装 Ruby,不需要 bundle install。
如果写文章时要实时预览(改完立刻刷新看效果),用开发镜像 + 挂载源码的方式:
# 开发模式:把源码挂进容器,端口 4000,--watch 自动重建
docker run -it --rm \
-v "$PWD":/blog \
-p 4000:4000 \
my-blog:dev \
bundle exec jekyll serve --watch --drafts
五、GitHub Actions:提交即发布
既然环境已经容器化,CI 里最省事的做法是直接复用镜像构建,或者干脆让 GitHub Pages 官方 Action 构建。这里展示 Docker 化的完整流程:
# .github/workflows/blog.yml
name: Build & Deploy Blog
on:
push:
branches: [ master ] # 你的博客在 master 分支
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 构建 Jekyll 镜像
run: docker build -t my-blog .
- name: 导出静态产物
run: |
docker create --name tmp my-blog
docker cp tmp:/usr/share/nginx/html ./_site
docker rm tmp
- name: 部署到 GitHub Pages
uses: peaceiris/actions-gh-pages@v4
with:
github_token: $
publish_dir: ./_site
publish_branch: gh-pages # 发布到 gh-pages 分支
也可以更简单地用官方
actions/jekyll-build-pages,但自己 Docker 构建的好处是:本地和 CI 用同一个镜像,任何环境问题都能本地复现,这在排障时价值巨大。
六、进阶:本地磁盘缓存,别再重复 build
Jekyll 构建慢,主要慢在 bundle install。除了 Docker 层缓存,还可以给 CI 加依赖缓存,命中缓存时秒级完成:
- name: Cache Ruby gems
uses: actions/cache@v4
with:
path: vendor/bundle
key: $-gems-$
restore-keys: |
$-gems-
配合 bundle config set path vendor/bundle,依赖装一次、缓存一年,后续每次提交构建从十几分钟降到几十秒。
七、总结
把博客容器化,你收获的是:
- 环境可复现:本地、CI、服务器同一镜像,告别”在我电脑上是好的”;
- 换电脑零成本:装好 Docker 就能写、能构建;
- 部署自动化:提交 Markdown → 自动构建 → 自动发布,文章写完 push 即上线;
- 和前端工程化同一套思维:镜像化 + 流水线 + 缓存优化,你已经在用最前沿的工程实践维护博客。
一句话总结:”我用多阶段 Dockerfile 把 Jekyll 构建环境固化,Gemfile 层缓存加速依赖安装,GitHub Actions 提交即自动构建发布,从此博客环境和部署全自动、可复现。”
这篇文章和《Docker + Nginx + HTTPS 部署 Vue3》《Docker 常用命令》《Centos 安装 docker-compose》一起,覆盖了”把东西跑上 Docker”的完整套路。下一篇我们聊一个更贴近日常的主题:Vue3 线上性能排查实战。
