Skip to content
0

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

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

问题

bash
https://github.com/Kele-Bingtang/vitepress-theme-teek Teek是一个基于VitePress二开的(文档库和博客 二合一)主题,利用pnpm工具打包。请问如何使用docker来部署这个Teek博客呢?请给出具体的步骤。
其中安装这个teek博客的相关命令如下:
#项目拉取
git clone https://gitee.com/onlyonexl/vitepress-theme-teek-one-public.git

cd /d/vitepress-theme-teek-one-public
#依赖安装(只能用 pnpm 安装依赖)
pnpm install

#项目本地运行
pnpm docs:dev #本地运行

#项目打包
pnpm docs:build

回答

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


1. 编写 Dockerfile

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

dockerfile
# 第一阶段:构建阶段
FROM node:18-alpine AS builder

# 安装 pnpm
RUN corepack enable && corepack prepare pnpm@latest --activate

# 设置工作目录
WORKDIR /app

# 复制项目文件(排除 node_modules 加速构建)
COPY package.json pnpm-lock.yaml ./
COPY docs ./docs
COPY .vitepress ./.vitepress

# 安装依赖并构建
RUN pnpm install --frozen-lockfile && \
    pnpm docs:build

# 第二阶段:运行阶段
FROM nginx:alpine

# 复制构建产物到 Nginx
COPY --from=builder /app/.vitepress/dist /usr/share/nginx/html

# 暴露端口
EXPOSE 80

# 启动 Nginx
CMD ["nginx", "-g", "daemon off;"]

2. 创建 .dockerignore

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

ignore
node_modules
.git
.DS_Store

3. 构建 Docker 镜像

在项目根目录执行:

bash
docker build -t teek-blog .

4. 运行容器

bash
docker 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

nginx
server {
    listen 80;
    server_name localhost;
    root /usr/share/nginx/html;
    index index.html;

    location / {
        try_files $uri $uri/ /index.html;
    }
}

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

dockerfile
COPY 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 后重新构建:
    bash
    docker build --no-cache -t teek-blog .

🌐 访问显示 404

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

🐳 更新内容后重新部署

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

最终目录结构

vitepress-theme-teek-one-public/
├── Dockerfile
├── .dockerignore
├── nginx.conf(可选)
├── docs/
├── .vitepress/
└── package.json

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

🍊

报错

image-20250815060828766

bash
> node --max-old-space-size=131072 node_modules/vitepress/bin/vitepress.js build docs


  vitepress v1.6.3

- building client + server bundles...
10:06:57 PM [vitepress-plugin-sidebar-resolve v1.1.0] Injected Sidebar Data Successfully. 注入侧边栏数据成功!
10:06:57 PM [vitepress-plugin-permalink v1.1.3] Injected Permalinks Data Successfully. 注入永久链接数据成功!
10:06:58 PM [vitepress-plugin-doc-analysis v1.0.12] Injected DocAnalysisInfo Data Successfully. 注入文档分析数据成功!
10:06:58 PM [vitepress-plugin-catalogue v1.1.0] Injected Catalogues Data Successfully. 注入目录页数据成功!
10:06:58 PM [vitepress-plugin-file-content-loader v1.0.12] Injected Posts Data Successfully. 注入 Posts 数据成功!
x Build failed in 5.51s
 building client + server bundles...
build error:
[vitepress] spawn git ENOENT
file: /app/docs/01.指南/01.简介/01.简介.md
[vitepress] spawn git ENOENT
file: /app/docs/01.指南/01.简介/01.简介.md
    at ChildProcess._handle.onexit (node:internal/child_process:284:19)
    at onErrorNT (node:internal/child_process:477:16)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21)
 ELIFECYCLE  Command failed with exit code 1.
The command '/bin/sh -c pnpm install --frozen-lockfile &&     pnpm docs:build' returned a non-zero code: 1
[root@wiki vitepress-theme-teek-one-public]# vim Dockerfile 
[root@wiki vitepress-theme-teek-one-public]#

回答

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

修复步骤

1. 修改 Dockerfile(安装 Git)

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

dockerfile
# 第一阶段:构建阶段
FROM node:18-alpine AS builder

# 安装 git 和 pnpm
RUN apk add --no-cache git && \
    corepack enable && \
    corepack prepare pnpm@latest --activate

WORKDIR /app
COPY . .
RUN pnpm install --frozen-lockfile && \
    pnpm docs:build

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

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

ts
export default defineConfig({
  markdown: {
    lastUpdated: false // 禁用最后更新时间
  }
})

3. 重新构建镜像

bash
docker build -t teek-blog .

错误原因分析

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

其他优化建议

  1. 减少镜像体积

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

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

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

验证是否解决

构建完成后检查日志:

bash
docker logs -f <容器ID>

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


备选方案

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

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

🍊

报错

bash
- building client + server bundles...
10:12:59 PM [vitepress-plugin-sidebar-resolve v1.1.0] Injected Sidebar Data Successfully. 注入侧边栏数据成功!
10:12:59 PM [vitepress-plugin-permalink v1.1.3] Injected Permalinks Data Successfully. 注入永久链接数据成功!
10:12:59 PM [vitepress-plugin-doc-analysis v1.0.12] Injected DocAnalysisInfo Data Successfully. 注入文档分析数据成功!
10:12:59 PM [vitepress-plugin-catalogue v1.1.0] Injected Catalogues Data Successfully. 注入目录页数据成功!
10:12:59 PM [vitepress-plugin-file-content-loader v1.0.12] Injected Posts Data Successfully. 注入 Posts 数据成功!
 ELIFECYCLE  Command failed.
The command '/bin/sh -c pnpm install --frozen-lockfile &&     pnpm docs:build' returned a non-zero code: 1
[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(完整版)

dockerfile
# 第一阶段:构建(使用完整 Node.js 镜像避免 Alpine 兼容性问题)
FROM node:18 AS builder

# 安装 Git 和系统依赖(Alpine 需替换为 `apk add`)
RUN apt-get update && apt-get install -y git python3 make g++

# 配置 PNPM 和全局 Node.js 内存限制
RUN corepack enable && corepack prepare pnpm@latest --activate
ENV NODE_OPTIONS="--max-old-space-size=8192"

# 复制项目文件(分阶段利用缓存)
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
COPY . .
RUN pnpm docs:build

# 第二阶段:运行(轻量级 Nginx)
FROM nginx:alpine
COPY --from=builder /app/.vitepress/dist /usr/share/nginx/html
EXPOSE 80
CMD ["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. 构建命令(附加缓存清理)

bash
# 强制全新构建(避免缓存干扰)
docker build --no-cache -t teek-blog .

# 运行容器(测试模式)
docker run -it --rm -p 8080:80 teek-blog

验证步骤

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

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

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

备选方案(如果仍失败)

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

bash
# 在宿主机构建
pnpm docs:build

# 仅用 Docker 托管静态文件
docker 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 开始)。

🍊

报错

bash
vitepress v1.6.3

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

回答

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


终极解决方案

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

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

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

2. 优化 Dockerfile

dockerfile
# 使用更轻量的构建阶段
FROM node:18-bullseye-slim AS builder  # 比 alpine 更兼容 Node 生态

# 安装必要依赖(比 alpine 更稳定)
RUN apt-get update && \
    apt-get install -y --no-install-recommends git python3 make g++ && \
    rm -rf /var/lib/apt/lists/*

# 设置 Node 内存限制(必须)
ENV NODE_OPTIONS="--max-old-space-size=2048"  # 2GB

# 使用 PNPM 的 --shamefully-hoist 避免嵌套依赖问题
RUN corepack enable && corepack prepare pnpm@latest --activate
WORKDIR /app
COPY . .
RUN pnpm install --shamefully-hoist --frozen-lockfile && \
    pnpm docs:build

3. 清理构建缓存

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

错误原因深度解析

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

分步验证流程

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

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

  3. 查看详细内存使用

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

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

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

bash
# 在宿主机(内存更大)上构建
pnpm docs:build

# 仅用 Docker 运行 Nginx
docker run -d -p 8080:80 -v $(pwd)/.vitepress/dist:/usr/share/nginx/html nginx:alpine

方案 B:使用 BuildKit 缓存

bash
# 使用 BuildKit 的分阶段缓存(需 Docker 20.10+)
DOCKER_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 中添加构建监控:

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

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

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

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