预览环境

Beta
以 Markdown 格式查看
企业功能

此功能仅适用于企业计划。如需开始使用,请联系 support@buildwithfern.com

有两种方式为自托管文档设置预览环境:

  • 基于容器 — 部署与生产环境中使用的相同自托管 Docker 容器,为您提供具有搜索、API Explorer 和身份验证的完整预览。
  • 静态导出 — 将文档渲染为静态 HTML 和资源文件,可从任何对象存储(S3、GCS、R2)提供服务,无需运行容器。

两种方法都会渲染与生产环境中完全相同的内容。

选择方法

对于大多数团队来说,静态导出是最佳起点,因为它的基础设施和设置要求最少。如果您需要在预览中使用搜索、API Explorer 或身份验证,请选择基于容器的方法。

基于容器静态导出 Beta
内容渲染与生产环境相同与生产环境相同
搜索
API Explorer(试用功能)
身份验证
基础设施需要容器托管、负载均衡器、DNS可从任何对象存储提供服务(S3、GCS、R2)
扩展性每个预览一个容器无需服务器即可支持数千个预览
成本较高较低
清理必须拆除容器和资源简单 — 删除静态文件

GitHub Actions 工作流

可以将以下工作流添加到您的代码库中,以在每个拉取请求上自动构建和部署预览环境。

此工作流在每个拉取请求上构建 Docker 镜像并将其部署到您的容器托管平台。

.github/workflows/preview-docs-container.yml
1name: preview-docs-container
2
3on:
4 pull_request:
5
6jobs:
7 preview-docs:
8 runs-on: ubuntu-latest
9 permissions: write-all
10 steps:
11 - name: Checkout repository
12 uses: actions/checkout@v4
13
14 - name: Log in to Docker Hub
15 uses: docker/login-action@v3
16 with:
17 username: ${{ secrets.DOCKERHUB_USERNAME }}
18 password: ${{ secrets.DOCKERHUB_TOKEN }}
19
20 - name: Build docs container
21 run: docker build -t self-hosted-docs:${{ github.sha }} .
22
23 - name: Push container to registry
24 run: |
25 docker tag self-hosted-docs:${{ github.sha }} ${{ secrets.REGISTRY }}/self-hosted-docs:${{ github.sha }}
26 docker push ${{ secrets.REGISTRY }}/self-hosted-docs:${{ github.sha }}
27
28 - name: Deploy preview
29 run: |
30 # Deploy the container to your hosting platform
31 # (e.g. ECS, Cloud Run, Kubernetes, etc.)
32 # and retrieve the preview URL
33 echo "Deploy self-hosted-docs:${{ github.sha }} to your platform"

此工作流构建容器,运行静态导出,并将输出上传到 S3。根据您的对象存储调整上传步骤。

.github/workflows/preview-docs-static.yml
1name: preview-docs-static
2
3on:
4 pull_request:
5
6jobs:
7 preview-docs:
8 runs-on: ubuntu-latest
9 permissions: write-all
10 steps:
11 - name: Checkout repository
12 uses: actions/checkout@v4
13
14 - name: Log in to Docker Hub
15 uses: docker/login-action@v3
16 with:
17 username: ${{ secrets.DOCKERHUB_USERNAME }}
18 password: ${{ secrets.DOCKERHUB_TOKEN }}
19
20 - name: Build docs container
21 run: docker build -t self-hosted-docs .
22
23 - name: Start container
24 run: |
25 docker run -d \
26 --name docs-container \
27 -e WARMUP=true \
28 self-hosted-docs
29
30 - name: Wait for container to be healthy
31 run: |
32 echo "Waiting for container to be healthy..."
33 MAX_ATTEMPTS=60
34 ATTEMPT=0
35 while [ "$ATTEMPT" -lt "$MAX_ATTEMPTS" ]; do
36 ATTEMPT=$((ATTEMPT + 1))
37 if docker exec docs-container sh -c \
38 'TOKEN=$(cat /tmp/.cache-admin-token 2>/dev/null); \
39 curl -f -s --max-time 5 \
40 -H "Authorization: Bearer $TOKEN" \
41 http://localhost:3000/__cache/stats' > /dev/null 2>&1; then
42 echo "Container is healthy."
43 break
44 fi
45 echo " Not ready yet... ($ATTEMPT/$MAX_ATTEMPTS)"
46 sleep 5
47 done
48 if [ "$ATTEMPT" -ge "$MAX_ATTEMPTS" ]; then
49 echo "Error: container did not become healthy."
50 exit 1
51 fi
52
53 - name: Export static site
54 run: |
55 docker exec docs-container /scripts/export.sh
56 docker cp docs-container:/tmp/fern-static-export.tar.gz ./export.tar.gz
57
58 - name: Extract static files
59 run: |
60 mkdir -p ./site
61 tar -xzf export.tar.gz -C ./site
62
63 - name: Upload to S3
64 uses: jakejarvis/s3-sync-action@v0.5.1
65 with:
66 args: --delete
67 env:
68 SOURCE_DIR: ./site
69 AWS_S3_BUCKET: ${{ secrets.AWS_S3_BUCKET }}
70 AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
71 AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
72 AWS_REGION: ${{ secrets.AWS_REGION }}
73 DEST_DIR: pr-${{ github.event.pull_request.number }}
74
75 - name: Comment preview URL on PR
76 if: github.event_name == 'pull_request'
77 uses: thollander/actions-comment-pull-request@v3
78 with:
79 message: |
80 Preview: http://${{ secrets.AWS_S3_BUCKET }}.s3-website.${{ secrets.AWS_REGION }}.amazonaws.com/pr-${{ github.event.pull_request.number }}
81 pr-number: ${{ github.event.pull_request.number }}
82
83 - name: Stop container
84 if: always()
85 run: docker rm -f docs-container