GitBook 构建与部署

把原先散落在 git / travis / GitHub Pages 的相关笔记收成一篇。


1. 本地 / CI 用 Docker 构建

docker run --rm -v "$PWD:/gitbook" billryan/gitbook gitbook install
docker run --rm -v "$PWD:/gitbook" billryan/gitbook gitbook build

产物一般在 _book/


2. Travis CI → 远端 bare 仓库 → Nginx

思路:推 master → Travis 用 Docker 构建 GitBook → 强制推 built 分支到服务器 bare 仓库 → post-receive checkout 并重启 Nginx。

加密部署私钥

# 需要 Ruby / travis CLI;也可用官方文档的加密方式
gem install travis
travis login --com --github-token <token>
travis encrypt-file id_rsa -r <user>/<repo> --com

.travis.yml 骨架

sudo: required
language: node_js
branches:
  only:
    - master
services:
  - docker

before_install:
  - openssl aes-256-cbc -K $encrypted_xxx_key -iv $encrypted_xxx_iv \
      -in id_rsa.enc -out id_rsa -d
  - git config --global user.email "[email protected]"
  - git config --global user.name "ci"

install:
  - docker run --rm -v "$PWD:/gitbook" billryan/gitbook gitbook install
  - docker run --rm -v "$PWD:/gitbook" billryan/gitbook gitbook build

before_script:
  - printf "Host *\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config

script: "true"

after_success:
  - eval "$(ssh-agent -s)"
  - chmod 600 id_rsa && ssh-add id_rsa
  - git fetch --unshallow || true
  - git checkout -b built
  - git add -A && git commit -m "built version" || true
  - git remote add deploy ssh://user@host:port/path/gitbook.git
  - git push deploy built --force

encrypted_xxx_*、邮箱、remote 换成自己的;密钥勿明文入库。

服务器:bare 仓库 + hook

git init --bare ~/gitbook.git

hooks/post-receive(需可执行):

#!/bin/sh
while read oldrev newrev ref; do
  if echo "$ref" | grep -q '/built$'; then
    echo "Deploying built..."
    git --work-tree=/var/www/gitbook --git-dir="$HOME/gitbook.git" fetch --all
    git --work-tree=/var/www/gitbook --git-dir="$HOME/gitbook.git" reset --hard built
    docker restart nginx   # 或 systemctl reload nginx
  fi
done

~/.ssh/authorized_keys 写入 CI 公钥。工作树目录先建好。

Nginx 挂静态站(Docker 示例)

docker run -d --name nginx \
  -v /conf/nginx/nginx.conf:/etc/nginx/nginx.conf \
  -v /conf/nginx/conf.d:/etc/nginx/conf.d \
  -v /var/www/gitbook/_book:/wwwroot \
  --restart always -p 80:80 -p 443:443 nginx
server {
    listen 80;
    server_name docs.example.com;
    location / {
        root /wwwroot;
        index index.html;
    }
}

Travis.com 产品形态已变化,新项目更常见 GitHub Actions;流程同构:build → 推制品 → 服务器 hook 或 rsync。


3. GitHub Pages + Vue Router history

GitHub Pages 没有像 Nginx 那样的 try_files,history 模式会 404。

方案做法代价
最简单复制 index.html404.html响应仍是 404,SEO 差
最省事改用 hash 路由URL 带 #
较完整自有域名 + CDN/Worker 把 404 改成 200要域名与边缘配置

Cloudflare Worker 示例(匹配 www.example.com/*):把上游 404 的 body 以 200 返回(配合 Pages 的 404.html = SPA 入口):

addEventListener('fetch', (event) => {
  event.respondWith(handleRequest(event.request))
})

async function handleRequest(request) {
  const resp = await fetch(request)
  if (resp.status === 404) {
    return new Response(resp.body, {
      status: 200,
      statusText: 'OK',
      headers: resp.headers,
    })
  }
  return resp
}

免费档有请求配额,注意用量。