Skip to content

VitePress 文档站部署与维护

当前 wiki 站点使用 VitePress 搭建,采用多阶段 Docker 构建生产环境,通过 Traefik 反向代理对外提供 HTTPS 服务。

架构

写 Markdown 文件

Bun → vitepress build (SSR 预渲染)

node:22-alpine + serve (静态文件服务器)

Traefik Gateway → wiki.zipTako.com (HTTPS)
层级组件职责
编辑器任意文本编辑器.md 文件
构建器Bun + VitePress将 markdown 构建为静态 HTML
运行时node:22-alpine + serve轻量静态文件服务
网关TraefikSSL 终止、域名路由、访问控制

项目结构

bash
~/docker/vitepress/
├── Dockerfile              # 多阶段构建(Bun 构建 + Node 运行)
├── docker-compose.yml      # Traefik 对接配置
├── package.json            # VitePress 依赖
└── docs/
    ├── .vitepress/
   ├── config.js       # 站点导航、主题配置
   └── cache/          # VitePress 缓存(可删除)
    ├── index.md            # 首页
    ├── traefik-setup.md    # Traefik 部署文档
    └── ...                 # 你的 Markdown 文件(URL 由文件路径自动生成)

Dockerfile

采用多阶段构建——Bun 负责快速安装依赖和构建,Node 运行轻量的静态服务器:

dockerfile
FROM oven/bun:latest AS builder

WORKDIR /app
COPY package.json .
RUN bun install --frozen-lockfile

COPY docs ./docs
RUN bunx vitepress build docs

FROM node:22-alpine

WORKDIR /app
RUN npm install -g serve

COPY --from=builder /app/docs/.vitepress/dist /app/dist

EXPOSE 4173

CMD ["serve", "dist", "-l", "4173"]

为什么不用 vitepress devvitepress preview

  • vitepress dev 是开发模式(CSR,不适合生产运行)
  • vp preview 在 Bun 下有 ESM 兼容性 Bug
  • serve 是最轻量的方案(最终镜像约 70MB)

VitePress 配置

js
// docs/.vitepress/config.js
import { defineConfig } from 'vitepress'

export default defineConfig({
  title: "Ziptako's Wiki",
  description: '我的知识文档站',
  vite: {
    server: {
      allowedHosts: ['wiki.zipTako.com', 'wiki.ziptako.com', 'localhost']
    }
  },
  themeConfig: {
    siteTitle: '📚 Ziptako Wiki',
    nav: [
      { text: '首页', link: '/' },
      { text: 'Traefik 部署', link: '/traefik-setup' },
    ],
    sidebar: [
      {
        text: '运维记录',
        items: [
          { text: 'Traefik 部署', link: '/traefik-setup' },
        ],
      },
    ],
    socialLinks: [
      { icon: 'github', link: 'https://github.com/ziptako' },
    ],
    footer: {
      message: 'Powered by VitePress + Bun + Hermes Agent',
      copyright: '© 2026 Ziptako'
    }
  }
})

vite.server.allowedHosts 必须包含所有入口域名(全小写),否则 Vite 会拦截请求。

部署

首次部署

bash
cd ~/docker/vitepress

# 创建 docs 目录
mkdir -p docs/.vitepress/public

# 构建并启动
sudo docker compose up -d --build

# 查看日志确认启动成功
sudo docker compose logs vitepress

# 访问 https://wiki.zipTako.com/

正常启动(已有镜像)

bash
cd ~/docker/vitepress
sudo docker compose up -d

维护

📝 更新文档内容

修改 ~/docker/vitepress/docs/ 下的 .md 文件后,需要重新构建才能生效:

bash
cd ~/docker/vitepress

# 重新构建镜像(Bun 会缓存 node_modules,构建很快)
sudo docker compose up -d --build

# 确认新容器正常运行
sudo docker compose ps

当前是生产模式(静态文件),每次改内容都需要 --build。如果开发阶段想实时预览,请参考下文"切换到 Dev Mode"。

📦 更新 VitePress 版本

bash
cd ~/docker/vitepress

# 编辑 package.json,更新版本号
# "vitepress": "^1.6.0" → "^1.7.0"

# 重新构建(Bun 会下载新版)
sudo docker compose up -d --build

# 验证新版本
sudo docker compose logs vitepress | grep -i vitepress

🧹 清理缓存

bash
cd ~/docker/vitepress
sudo rm -rf docs/.vitepress/cache

.vitepress/cache/ 是 VitePress 的构建缓存,删掉后下次 build 会自动重新生成。

💾 备份

bash
# 只需备份 docs/ 目录中的内容(源码),构建产物可以随时重建
tar czf ~/wiki-backup-$(date +%Y%m%d).tar.gz \
  -C ~/docker/vitepress \
  Dockerfile docker-compose.yml package.json docs/

# 如果想连同镜像一起备份
sudo docker save vitepress-vitepress:latest -o ~/vitepress-image.tar

🔄 重建整个站点

bash
cd ~/docker/vitepress

# 停止并删除容器
sudo docker compose down

# 清理旧镜像
sudo docker rmi vitepress-vitepress:latest 2>/dev/null; sudo docker image prune -f

# 重新构建
sudo docker compose up -d --build

# 验证
sudo docker compose ps

🩺 健康检查

bash
# 容器状态
sudo docker ps --filter name=vitepress --format "{{.Names}} {{.Status}}"

# 直接访问容器内的服务
curl -s -H "Host: wiki.zipTako.com" http://localhost:443 | head -5

# 通过 Traefik 访问
curl -sk https://wiki.zipTako.com/ | head -5
# 应返回 HTML(SSR 预渲染,内容直接包含在 HTML 中)

# 查看日志
sudo docker compose logs vitepress --tail 20

切换到 Dev Mode(写作模式)

写文章时可以用 Dev Mode,每次保存 .md 文件后浏览器自动刷新,非常适合频繁编辑的场景。

docker-compose.yml(Dev 版)

yaml
services:
  vitepress:
    build: .
    container_name: vitepress
    restart: unless-stopped
    networks:
      - traefik
    volumes:
      - ./docs:/app/docs
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.vitepress.rule=Host(`wiki.zipTako.com`)"
      - "traefik.http.routers.vitepress.tls=true"
      - "traefik.http.routers.vitepress.tls.certresolver=letsencrypt"
      - "traefik.http.services.vitepress.loadbalancer.server.port=5173"

Dockerfile(Dev 版)

dockerfile
FROM oven/bun:latest AS builder

WORKDIR /app
COPY package.json .
RUN bun install --frozen-lockfile

FROM oven/bun:latest

WORKDIR /app
COPY --from=builder /app/node_modules /app/node_modules
COPY package.json /app/

EXPOSE 5173

CMD ["bunx", "vitepress", "dev", "docs", "--host", "0.0.0.0", "--port", "5173"]

Dev ↔ Prod 切换流程

bash
# Dev Mode(写作)
# 1. 编辑 docker-compose.yml:port 改为 5173
# 2. 编辑 Dockerfile:替换为 Dev 版
# 3. 启动
sudo docker compose up -d --build

# 写完后回到生产模式
# 1. 编辑 docker-compose.yml:port 改回 4173
# 2. 编辑 Dockerfile:替换回生产版(多阶段构建)
# 3. 重新构建
sudo docker compose up -d --build

⚠️ 不要在生产环境跑 Dev Mode:Vite 开发服务器长期运行可能内存泄漏、暴露 HMR WebSocket 路径、且无法接入 CDN 加速。

常见问题

❌ 修改内容后页面没变

原因:当前是生产模式(静态文件),修改 .md 后需要 --build 重新构建镜像。

解决sudo docker compose up -d --build

❌ "This host is not allowed"(Dev Mode)

原因:Vite 拦截了来自未知 Host 的连接。

解决:在 config.jsvite.server.allowedHosts 中添加域名(全小写),重启容器。

❌ 构建失败

bash
# 查看详细错误
sudo docker compose logs vitepress

# 本地调试构建
cd ~/docker/vitepress
sudo docker build -t vitepress-test .

常见原因:

  • package.json 语法错误
  • .md 文件中有 VitePress 不支持的语法
  • config.js 导入错误

❌ 容器一直重启

bash
# 查看容器状态
sudo docker compose ps

# 查看完整日志
sudo docker compose logs --tail=50 vitepress

可能是:

  • serve 启动失败(端口被占用)
  • vitepress build 阶段报错但 exit code 仍为 0(检查构建日志)
  • 内存不足(极罕见,生产模式很轻量)

URL 路由规则

VitePress 根据 docs/ 下的文件路径自动生成路由:

文件路径对应 URL
docs/index.md/
docs/traefik-setup.md/traefik-setup.html
docs/vitepress-deployment.md/vitepress-deployment.html
docs/guide/advanced.md/guide/advanced.html

技术选型总结

选型原因
VitePress基于 Vite,开发体验好,SSR 预渲染,SEO 友好
Bun构建阶段用 Bun,bun install 超快(~12s vs npm ~60s)
node:22-alpine运行时用标准 Node,避免 Bun 的 ESM Bug
serve最轻量的静态文件服务器,镜像仅 ~70MB
TraefikDNS 服务发现 + 自动 SSL,无需手动配置 Nginx

参考链接

Powered by VitePress + Bun + Hermes Agent