Fumadocs 搭建指引:从零开始部署现代化文档站

Fumadocs 是一个基于 Next.js 的现代化文档框架,拥有极佳的性能和开发体验。本文将记录从环境准备到最终 Docker 容器化部署的完整流程,帮助你快速搭建属于自己的文档站点。

# 一、环境准备

在开始之前,我们需要准备好基础的运行环境。

# 1. 安装 Docker

Docker 是我们后续部署的核心工具。具体的安装步骤因操作系统而异,此处不再赘述,请参考官方文档完成安装。

# 2. 安装 Node.js

我们需要 Node.js 环境来初始化项目。推荐使用 nvm (Node Version Manager) 来管理 Node 版本,这样可以轻松切换和升级。

1
2
3
4
5
6
7
8
9
10
11
# 安装 nvm
curl https://raw.githubusercontent.com/creationix/nvm/master/install.sh | bash

# 刷新环境变量
source ./.bashrc

# 验证安装
nvm -v

# 安装最新版 Node.js 并更新 npm
nvm install node --latest-npm

# 二、项目初始化

# 1. 创建 Fumadocs 项目

环境准备好后,我们使用官方脚手架创建一个新项目。

1
2
3
4
5
# 安装必要的依赖库(部分系统可能需要)
apt install -y libatomic1

# 创建项目
npx create-fumadocs-app fumadocs-site

在初始化过程中,脚手架会询问一些配置选项。以下是推荐的配置(大部分保持默认即可):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
┌  Create Fumadocs App

◇ Choose a template
│ Next.js: Fumadocs MDX

◇ Use `/src` directory?
│ Yes

◇ Configure linter?
│ Disabled

◇ Choose a search solution?
│ Default

◇ Do you want to install packages automatically? (detected as npm)
│ Yes

◇ Project Generated

└ Done

# 2. 本地运行验证

项目创建完成后,进入目录并启动开发服务器,确保一切正常。

1
2
cd fumadocs-site/
npm install && npm run dev

如果看到 Ready in ... 的提示,说明项目已成功启动。

# 三、项目配置与构建

为了适应 Docker 部署,我们需要对 Next.js 的配置进行微调。

# 1. 修改配置文件

编辑 next.config.mjs 文件,开启 standalone 模式。这个模式会自动分析依赖,生成一个最小化的生产环境构建包,非常适合 Docker 部署。

1
2
3
4
5
6
7
8
9
10
11
12
// next.config.mjs
import { createMDX } from 'fumadocs-mdx/next';

const withMDX = createMDX();

/** @type {import('next').NextConfig} */
const config = {
output: 'standalone', // 关键配置:开启独立构建模式
reactStrictMode: true,
};

export default withMDX(config);

# 2. 本地构建测试

在打包进 Docker 之前,建议先在本地尝试构建,确保没有报错。

1
2
3
4
5
6
7
8
npm install
npm run build

# 验证是否生成了 standalone 目录
ls .next | grep standalone

# 安装 vite (如果项目中用到相关工具链)
npm install -D vite

# 四、Docker 容器化部署

我们将提供两种部署方案:生产环境(体积小、性能好)和开发环境(支持热更新)。

# 1. 编写 Dockerfile

# 方案 A:生产环境 (Production)

使用多阶段构建(Multi-stage build)来减小镜像体积。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# syntax=docker.io/docker/dockerfile:1

FROM node:25-alpine AS base

# 1. 依赖安装阶段
FROM base AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* .npmrc* source.config.ts next.config.* ./
RUN \
if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
elif [ -f package-lock.json ]; then npm ci; \
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \
else echo "Lockfile not found." && exit 1; \
fi

# 2. 构建阶段
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN \
if [ -f yarn.lock ]; then yarn run build; \
elif [ -f package-lock.json ]; then npm run build; \
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm run build; \
else echo "Lockfile not found." && exit 1; \
fi

# 3. 运行阶段
FROM base AS runner
WORKDIR /app
ENV NODE_ENV=production

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

# 复制构建产物
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

USER nextjs
EXPOSE 3000
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"

CMD ["node", "server.js"]

# 方案 B:开发环境 (Development)

此方案挂载本地目录,修改代码后容器内会实时更新,适合调试。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
FROM node:20-alpine

WORKDIR /app

# 安装依赖
COPY package.json package-lock.json* ./
RUN npm install --ignore-scripts

# 拷贝源码(实际运行时会被 volume 覆盖)
COPY . .

EXPOSE 3000

# 强制监听所有地址
ENV HOST=0.0.0.0
ENV PORT=3000

CMD ["npm", "run", "dev"]

# 2. 编写 docker-compose.yml

使用 Docker Compose 来管理容器,以下配置适用于开发环境。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
version: "3.9"

services:
fumadocs:
container_name: fumadocs-dev
build: .
ports:
- "3000:3000"
volumes:
- ./:/app
- /app/node_modules # 避免本地 node_modules 覆盖容器内的
environment:
- NODE_ENV=development
restart: unless-stopped

# 3. 启动容器

一切准备就绪,一键启动!

1
sudo docker-compose up -d --build

启动后,访问 http://localhost:3000 即可看到你的 Fumadocs 文档站点。

# 五、后续配置

# 反代配置

(此处可根据实际使用的 Nginx 或 1Panel 等工具补充具体的反向代理配置,将域名指向 3000 端口)