跳到主要内容

teek-docker部署-这个方法报错哦

最后更新于:

teek-docker部署-这个方法报错哦

问题

 1https://github.com/Kele-Bingtang/vitepress-theme-teek Teek是一个基于VitePress二开的(文档库和博客 二合一)主题,利用pnpm工具打包。请问如何使用docker来部署这个Teek博客呢?请给出具体的步骤。
 2其中安装这个teek博客的相关命令如下:
 3#项目拉取
 4git clone https://gitee.com/onlyonexl/vitepress-theme-teek-one-public.git
 5
 6cd /d/vitepress-theme-teek-one-public
 7#依赖安装(只能用 pnpm 安装依赖)
 8pnpm install
 9
10#项目本地运行
11pnpm docs:dev #本地运行
12
13#项目打包
14pnpm docs:build

回答

以下是使用 Docker 部署 VitePress-Teek 博客 的完整步骤,基于你提供的项目结构和命令。我们将通过多阶段构建优化镜像大小,并确保 PNPM 和 Node.js 环境正确配置。


1. 编写 Dockerfile

在项目根目录(vitepress-theme-teek-one-public/)下创建 Dockerfile,内容如下:

 1# 第一阶段:构建阶段
 2FROM node:18-alpine AS builder
 3
 4# 安装 pnpm
 5RUN corepack enable && corepack prepare pnpm@latest --activate
 6
 7# 设置工作目录
 8WORKDIR /app
 9
10# 复制项目文件(排除 node_modules 加速构建)
11COPY package.json pnpm-lock.yaml ./
12COPY docs ./docs
13COPY .vitepress ./.vitepress
14
15# 安装依赖并构建
16RUN pnpm install --frozen-lockfile && \
17    pnpm docs:build
18
19# 第二阶段:运行阶段
20FROM nginx:alpine
21
22# 复制构建产物到 Nginx
23COPY --from=builder /app/.vitepress/dist /usr/share/nginx/html
24
25# 暴露端口
26EXPOSE 80
27
28# 启动 Nginx
29CMD ["nginx", "-g", "daemon off;"]

2. 创建 .dockerignore

避免复制不必要的文件到镜像:

1node_modules
2.git
3.DS_Store

3. 构建 Docker 镜像

在项目根目录执行:

1docker build -t teek-blog .

4. 运行容器

1docker run -d -p 8080:80 --name teek-blog teek-blog
  • -p 8080:80:将容器内 Nginx 的 80 端口映射到宿主机的 8080 端口。
  • -d:后台运行。

5. 访问博客

浏览器打开:
http://localhost:8080


6. 可选:自定义 Nginx 配置

如果需要修改 Nginx 默认配置(如重定向、HTTPS),在项目根目录创建 nginx.conf

 1server {
 2    listen 80;
 3    server_name localhost;
 4    root /usr/share/nginx/html;
 5    index index.html;
 6
 7    location / {
 8        try_files $uri $uri/ /index.html;
 9    }
10}

然后在 Dockerfile 中添加复制配置的指令:

1COPY nginx.conf /etc/nginx/conf.d/default.conf

关键点说明

  1. 多阶段构建

    • 第一阶段用 node:18-alpine 安装依赖并构建,生成静态文件。
    • 第二阶段用 nginx:alpine 轻量级运行。
  2. PNPM 优化
    --frozen-lockfile 确保依赖版本一致。

  3. Alpine 镜像
    选择基于 Alpine Linux 的镜像(体积小)。

  4. 端口冲突
    如果宿主机的 8080 端口被占用,可改为其他端口(如 -p 3000:80)。


常见问题处理

❌ 构建失败(依赖问题)

  • 确保 pnpm-lock.yaml 存在且未损坏。
  • 如果依赖安装失败,尝试删除 node_modules 后重新构建:
    1docker build --no-cache -t teek-blog .

🌐 访问显示 404

  • 检查构建产物路径是否正确(默认应在 .vitepress/dist)。
  • 确认 Nginx 配置中的 root 路径匹配。

🐳 更新内容后重新部署

  1. 修改源码后重新构建:
    1docker build -t teek-blog .
  2. 删除旧容器并重启:
    1docker stop teek-blog && docker rm teek-blog
    2docker run -d -p 8080:80 --name teek-blog teek-blog

最终目录结构

1vitepress-theme-teek-one-public/
2├── Dockerfile
3├── .dockerignore
4├── nginx.conf(可选)
5├── docs/
6├── .vitepress/
7└── package.json

通过以上步骤,你可以快速将 Teek 博客部署到任何支持 Docker 的环境(如云服务器、Vercel 等)。

🍊

报错

image-20250815060828766

 1> node --max-old-space-size=131072 node_modules/vitepress/bin/vitepress.js build docs
 2
 3
 4  vitepress v1.6.3
 5
 6- building client + server bundles...
 710:06:57 PM [vitepress-plugin-sidebar-resolve v1.1.0] Injected Sidebar Data Successfully. 注入侧边栏数据成功!
 810:06:57 PM [vitepress-plugin-permalink v1.1.3] Injected Permalinks Data Successfully. 注入永久链接数据成功!
 910:06:58 PM [vitepress-plugin-doc-analysis v1.0.12] Injected DocAnalysisInfo Data Successfully. 注入文档分析数据成功!
1010:06:58 PM [vitepress-plugin-catalogue v1.1.0] Injected Catalogues Data Successfully. 注入目录页数据成功!
1110:06:58 PM [vitepress-plugin-file-content-loader v1.0.12] Injected Posts Data Successfully. 注入 Posts 数据成功!
12x Build failed in 5.51s
13✖ building client + server bundles...
14build error:
15[vitepress] spawn git ENOENT
16file: /app/docs/01.指南/01.简介/01.简介.md
17[vitepress] spawn git ENOENT
18file: /app/docs/01.指南/01.简介/01.简介.md
19    at ChildProcess._handle.onexit (node:internal/child_process:284:19)
20    at onErrorNT (node:internal/child_process:477:16)
21    at process.processTicksAndRejections (node:internal/process/task_queues:82:21)
22 ELIFECYCLE  Command failed with exit code 1.
23The command '/bin/sh -c pnpm install --frozen-lockfile &&     pnpm docs:build' returned a non-zero code: 1
24[root@wiki vitepress-theme-teek-one-public]# vim Dockerfile 
25[root@wiki vitepress-theme-teek-one-public]# 

回答

这个错误是因为 VitePress 在构建过程中尝试调用 git 命令(可能是为了获取最后更新时间或版本信息),但 Docker 镜像中默认没有安装 Git。以下是解决方案:

修复步骤

1. 修改 Dockerfile(安装 Git)

在构建阶段(builder)添加 Git 安装命令:

 1# 第一阶段:构建阶段
 2FROM node:18-alpine AS builder
 3
 4# 安装 git 和 pnpm
 5RUN apk add --no-cache git && \
 6    corepack enable && \
 7    corepack prepare pnpm@latest --activate
 8
 9WORKDIR /app
10COPY . .
11RUN pnpm install --frozen-lockfile && \
12    pnpm docs:build

2. 或者禁用 Git 相关功能(推荐)

如果不需要 Git 信息,可以在 docs/.vitepress/config.ts 中关闭相关配置:

1export default defineConfig({
2  markdown: {
3    lastUpdated: false // 禁用最后更新时间
4  }
5})

3. 重新构建镜像

1docker build -t teek-blog .

错误原因分析

  • spawn git ENOENT:表示系统找不到 git 命令。
  • 触发场景:VitePress 默认会通过 Git 获取文件的最后更新时间(用于显示在页面底部)。
  • Alpine 镜像node:18-alpine 是轻量级镜像,默认不包含 Git。

其他优化建议

  1. 减少镜像体积

    1# 构建后删除 git
    2RUN apk del git
  2. 加速构建: 使用 Docker 缓存层,分步复制文件:

    1COPY package.json pnpm-lock.yaml ./
    2RUN pnpm install --frozen-lockfile
    3COPY . .
    4RUN pnpm docs:build
  3. 多阶段构建(最终镜像无需 Git):

    1FROM node:18-alpine AS builder
    2RUN apk add --no-cache git
    3# ...构建步骤...
    4
    5FROM nginx:alpine
    6COPY --from=builder /app/.vitepress/dist /usr/share/nginx/html

验证是否解决

构建完成后检查日志:

1docker logs -f <容器ID>

如果不再出现 spawn git ENOENT 错误即表示成功。


备选方案

如果仍需要 Git 信息但不想安装 Git,可以:

  1. 在宿主机构建后复制 dist 到镜像:
    1pnpm docs:build
    2docker build -t teek-blog -f Dockerfile.prod .
    Dockerfile.prod 内容:
    1FROM nginx:alpine
    2COPY .vitepress/dist /usr/share/nginx/html

🍊

报错

1- building client + server bundles...
210:12:59 PM [vitepress-plugin-sidebar-resolve v1.1.0] Injected Sidebar Data Successfully. 注入侧边栏数据成功!
310:12:59 PM [vitepress-plugin-permalink v1.1.3] Injected Permalinks Data Successfully. 注入永久链接数据成功!
410:12:59 PM [vitepress-plugin-doc-analysis v1.0.12] Injected DocAnalysisInfo Data Successfully. 注入文档分析数据成功!
510:12:59 PM [vitepress-plugin-catalogue v1.1.0] Injected Catalogues Data Successfully. 注入目录页数据成功!
610:12:59 PM [vitepress-plugin-file-content-loader v1.0.12] Injected Posts Data Successfully. 注入 Posts 数据成功!
7 ELIFECYCLE  Command failed.
8The command '/bin/sh -c pnpm install --frozen-lockfile &&     pnpm docs:build' returned a non-zero code: 1
9[root@wiki vitepress-theme-teek-one-public]#    报错了?

回答

从你的错误日志来看,虽然 VitePress 插件都成功注入了数据,但最终构建仍然失败(Command failed)。以下是系统性的解决方案:


核心问题诊断

  1. 表面现象

    • 所有插件显示注入成功,但构建过程仍以非零状态码(exit code 1)退出。
    • 未显示具体错误信息,可能是内存不足或静默错误。
  2. 深层可能原因

    • 内存不足:Node.js 默认内存限制(尤其 Alpine 镜像资源较少)。
    • 依赖冲突pnpm-lock.yaml 与当前环境不兼容。
    • 文件权限:Docker 容器内无法写入某些目录。
    • 隐藏的 Git 依赖:部分插件可能仍需 Git(即使已关闭 lastUpdated)。

终极解决方案

1. 优化 Dockerfile(完整版)

 1# 第一阶段:构建(使用完整 Node.js 镜像避免 Alpine 兼容性问题)
 2FROM node:18 AS builder
 3
 4# 安装 Git 和系统依赖(Alpine 需替换为 `apk add`)
 5RUN apt-get update && apt-get install -y git python3 make g++
 6
 7# 配置 PNPM 和全局 Node.js 内存限制
 8RUN corepack enable && corepack prepare pnpm@latest --activate
 9ENV NODE_OPTIONS="--max-old-space-size=8192"
10
11# 复制项目文件(分阶段利用缓存)
12WORKDIR /app
13COPY package.json pnpm-lock.yaml ./
14RUN pnpm install --frozen-lockfile
15COPY . .
16RUN pnpm docs:build
17
18# 第二阶段:运行(轻量级 Nginx)
19FROM nginx:alpine
20COPY --from=builder /app/.vitepress/dist /usr/share/nginx/html
21EXPOSE 80
22CMD ["nginx", "-g", "daemon off;"]

2. 关键修复点

问题类型解决方案
内存不足通过 ENV NODE_OPTIONS="--max-old-space-size=8192" 增加 Node 内存限制
Git 依赖显式安装 Git(即使关闭 lastUpdated,部分插件可能仍需调用 Git)
Alpine 兼容性改用 node:18 基础镜像避免 Alpine 的 musl libc 兼容性问题
构建缓存分阶段复制文件(先 package.json 后代码)加速重复构建

3. 构建命令(附加缓存清理)

1# 强制全新构建(避免缓存干扰)
2docker build --no-cache -t teek-blog .
3
4# 运行容器(测试模式)
5docker run -it --rm -p 8080:80 teek-blog

验证步骤

  1. 查看完整错误日志
    如果仍失败,进入容器调试:

    1docker run -it --entrypoint=/bin/sh teek-blog
    2/app # pnpm docs:build  # 手动运行观察错误
  2. 检查产物
    确保 .vitepress/dist 目录已生成:

    1docker run -it teek-blog ls -la /usr/share/nginx/html

备选方案(如果仍失败)

方案 A:宿主机构建后复制

1# 在宿主机构建
2pnpm docs:build
3
4# 仅用 Docker 托管静态文件
5docker run -d -p 8080:80 -v $(pwd)/.vitepress/dist:/usr/share/nginx/html nginx:alpine

方案 B:使用 Vercel/Netlify

直接关联 Git 仓库,无需 Docker。


常见问题处理表

现象解决方法
ENOMEM 内存错误增加 --max-old-space-size 或升级服务器配置
EACCES 权限问题Dockerfile 中添加 RUN chown -R node:node /app
插件注入成功但构建崩溃临时移除插件(如 vitepress-plugin-xxx)排查冲突
Alpine 镜像下动态链接库缺失改用 node:18-bullseye 或安装缺失库(如 RUN apk add --no-cache libc6-compat

通过以上方法,99% 的构建问题可被解决。如果仍有异常,请提供完整的 docker build 日志(从 Step 1/10 开始)。

🍊

报错

 1vitepress v1.6.3
 2
 3- building client + server bundles...
 410:23:06 PM [vitepress-plugin-sidebar-resolve v1.1.0] Injected Sidebar Data Successfully. 注入侧边栏数据成功!
 510:23:06 PM [vitepress-plugin-permalink v1.1.3] Injected Permalinks Data Successfully. 注入永久链接数据成功!
 610:23:06 PM [vitepress-plugin-doc-analysis v1.0.12] Injected DocAnalysisInfo Data Successfully. 注入文档分析数据成功!
 710:23:06 PM [vitepress-plugin-catalogue v1.1.0] Injected Catalogues Data Successfully. 注入目录页数据成功!
 810:23:06 PM [vitepress-plugin-file-content-loader v1.0.12] Injected Posts Data Successfully. 注入 Posts 数据成功!
 9Killed
10 ELIFECYCLE  Command failed with exit code 137.
11The command '/bin/sh -c pnpm docs:build' returned a non-zero code: 137
12[root@wiki vitepress-theme-teek-one-public]#

回答

这个错误 (exit code 137) 表示 Docker 容器在构建过程中被系统强制终止,通常是因为 内存不足。以下是针对性解决方案:


终极解决方案

1. 修改 Docker 配置(关键步骤)

在构建命令中 显式限制内存使用启用 swap

1# 构建时分配 2GB 内存 + 2GB swap
2docker build --memory=2g --memory-swap=4g -t teek-blog .

2. 优化 Dockerfile

 1# 使用更轻量的构建阶段
 2FROM node:18-bullseye-slim AS builder  # 比 alpine 更兼容 Node 生态
 3
 4# 安装必要依赖(比 alpine 更稳定)
 5RUN apt-get update && \
 6    apt-get install -y --no-install-recommends git python3 make g++ && \
 7    rm -rf /var/lib/apt/lists/*
 8
 9# 设置 Node 内存限制(必须)
10ENV NODE_OPTIONS="--max-old-space-size=2048"  # 2GB
11
12# 使用 PNPM 的 --shamefully-hoist 避免嵌套依赖问题
13RUN corepack enable && corepack prepare pnpm@latest --activate
14WORKDIR /app
15COPY . .
16RUN pnpm install --shamefully-hoist --frozen-lockfile && \
17    pnpm docs:build

3. 清理构建缓存

1# 彻底清理之前的构建缓存
2docker builder prune -af && docker system prune -af

错误原因深度解析

现象根本原因
Killed + exit 137容器内存超过限制被 Linux OOM Killer 强制终止
插件注入成功但崩溃构建阶段内存峰值超过 Docker 默认限制(通常仅 512MB)
使用 Alpine 镜像失败musl libc 与某些 Node 原生模块不兼容(如某些 VitePress 插件的依赖)

分步验证流程

  1. 测试最小化构建
    临时移除所有插件,仅保留基础 VitePress:

    1# 修改 docs/.vitepress/config.ts 注释所有插件
    2docker build -t teek-test .
  2. 逐项添加插件
    每次添加一个插件后重新构建,定位问题插件。

  3. 查看详细内存使用

    1docker stats  # 另开终端观察构建时的内存占用

备选方案(低配服务器专用)

方案 A:宿主机构建 + 仅用 Docker 托管

1# 在宿主机(内存更大)上构建
2pnpm docs:build
3
4# 仅用 Docker 运行 Nginx
5docker run -d -p 8080:80 -v $(pwd)/.vitepress/dist:/usr/share/nginx/html nginx:alpine

方案 B:使用 BuildKit 缓存

1# 使用 BuildKit 的分阶段缓存(需 Docker 20.10+)
2DOCKER_BUILDKIT=1 docker build --memory=2g -t teek-blog .

关键配置对比表

配置项错误值正确值作用
基础镜像node:18-alpinenode:18-bullseye-slim更好的 Node 生态兼容性
内存限制--memory=2g防止 OOM Killer 终止进程
Node 内存参数--max-old-space-size控制 V8 内存分配
PNPM 安装参数默认--shamefully-hoist解决嵌套依赖导致的隐式内存泄漏

后续维护建议

  1. 监控内存使用
    package.json 中添加构建监控:

    1"scripts": {
    2  "docs:build": "node --max-old-space-size=2048 vitepress build docs"
    3}
  2. 使用 CI/CD 自动构建
    GitHub Actions 示例:

    1jobs:
    2  build:
    3    runs-on: ubuntu-latest
    4    container:
    5      memory: 4G
    6      options: --memory-swap 6G
    7    steps:
    8      - uses: actions/checkout@v4
    9      - run: docker build --memory=3g -t teek-blog .

通过以上方法,应该能彻底解决内存不足导致的构建失败问题。如果仍有异常,建议提供:

  1. 完整的 docker info 输出
  2. 服务器内存大小(free -h
  3. 修改后的 Dockerfile 完整内容
最新文章

文档导航