预览环境
预览环境
企业功能
此功能仅适用于企业计划。如需开始使用,请联系 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
1 name: preview-docs-container 2 3 on: 4 pull_request: 5 6 jobs: 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
1 name: preview-docs-static 2 3 on: 4 pull_request: 5 6 jobs: 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