Skip to content

Commit 1ac6e09

Browse files
docs: add build-time generation, --only-deps flag, and gRPC air-gapped guidance
Update self-hosted documentation to cover: - Default behavior with fern-generate at build time and its advantages - The --only-deps flag for deferring docs generation to runtime - When to use runtime generation vs build-time generation - gRPC APIs section explaining BSR dependencies and air-gapped environments - Two solutions for air-gapped gRPC: build-time generation or vendoring buf deps Co-Authored-By: Sandeep Dinesh <[email protected]>
1 parent a77d83e commit 1ac6e09

File tree

1 file changed

+107
-1
lines changed

1 file changed

+107
-1
lines changed

fern/products/docs/pages/enterprise/self-hosted-set-up.mdx

Lines changed: 107 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,18 @@ In the directory containing your `fern/` folder, create a new `Dockerfile` with
4747
FROM fernapi/fern-self-hosted:<latest-tag>
4848

4949
COPY fern/ /fern/
50+
51+
RUN fern-generate
5052
```
5153

5254
Replace `<latest-tag>` with the actual tag used in the previous step.
5355

56+
The `fern-generate` command processes your documentation at build time, which provides several advantages:
57+
58+
- **Faster container startup**: Documentation is pre-generated, so the container starts quickly
59+
- **Air-gapped runtime**: No network access required when the container runs
60+
- **Smaller attack surface**: The running container doesn't need to fetch external dependencies
61+
5462
</Step>
5563
<Step title="Build Your Custom Docker Image">
5664

@@ -93,5 +101,103 @@ instances:
93101
You can now deploy the image to your own infrastructure, allowing you to host the documentation on your own domain.
94102
95103
</Step>
96-
</Steps>
104+
</Steps>
105+
106+
## Runtime documentation generation
107+
108+
By default, the `fern-generate` command processes your documentation at Docker build time. However, you can defer documentation generation to runtime using the `--only-deps` flag.
109+
110+
### Using the `--only-deps` flag
111+
112+
The `--only-deps` flag starts all required services (PostgreSQL, MinIO, FDR) at build time but skips the actual documentation generation:
113+
114+
```dockerfile
115+
FROM fernapi/fern-self-hosted:<latest-tag>
116+
117+
COPY fern/ /fern/
118+
119+
RUN fern-generate --only-deps
120+
```
121+
122+
When the container starts, it will automatically detect that documentation hasn't been generated and run `fern generate --docs` at runtime.
123+
124+
### When to use runtime generation
125+
126+
Runtime generation is useful when:
127+
128+
- **Dynamic configuration**: You want to pass documentation configuration (like environment variables or secrets) at runtime rather than baking them into the image
129+
- **Faster builds**: You want to reduce Docker build time during development
130+
- **Shared base images**: You want to build a single image that can serve different documentation configurations
131+
132+
<Warning>
133+
Runtime generation requires network access when the container starts. If you're deploying to an air-gapped environment, use the default build-time generation instead.
134+
</Warning>
135+
136+
## gRPC APIs and air-gapped environments
137+
138+
If your API uses gRPC/Protocol Buffers with dependencies from the [Buf Schema Registry](https://buf.build) (BSR), special consideration is needed for air-gapped deployments.
139+
140+
### Understanding the challenge
141+
142+
When Fern generates documentation for gRPC APIs, it uses the `buf` CLI to resolve protobuf dependencies. By default, `buf` fetches modules from `buf.build` at generation time. In air-gapped environments where external network access is blocked, this will fail.
143+
144+
### Solution 1: Build-time generation (recommended)
145+
146+
The simplest solution is to run `fern-generate` at build time when network access is available:
147+
148+
```dockerfile
149+
FROM fernapi/fern-self-hosted:<latest-tag>
150+
151+
COPY fern/ /fern/
152+
153+
RUN fern-generate
154+
```
155+
156+
This approach downloads all BSR dependencies during the Docker build (when network access is typically available) and bakes the generated documentation into the image. At runtime, no network access is required.
157+
158+
### Solution 2: Vendor buf dependencies
159+
160+
If you need runtime generation in an air-gapped environment, you can vendor your buf dependencies locally in your repository. This eliminates the need for network access entirely.
161+
162+
Add a step in your Dockerfile to export buf dependencies before copying your fern folder:
163+
164+
```dockerfile
165+
FROM fernapi/fern-self-hosted:<latest-tag>
166+
167+
COPY fern/ /fern/
168+
169+
# Export buf dependencies to vendor them locally
170+
RUN cd /fern && buf export . --output ./vendor
171+
172+
RUN fern-generate --only-deps
173+
```
174+
175+
Then update your `buf.yaml` to reference the vendored dependencies instead of BSR modules:
176+
177+
```yaml
178+
# Before (requires network access)
179+
deps:
180+
- buf.build/googleapis/googleapis
181+
182+
# After (uses local vendored files)
183+
deps:
184+
- ./vendor/googleapis
185+
```
186+
187+
<Info>
188+
For more information on vendoring buf dependencies, see the [Buf documentation on dependency management](https://buf.build/docs/bsr/module/dependency-management).
189+
</Info>
190+
191+
### Checking for BSR dependencies
192+
193+
To determine if your project uses BSR dependencies, check your `buf.yaml` file for a `deps` section:
194+
195+
```yaml
196+
version: v2
197+
deps:
198+
- buf.build/googleapis/googleapis
199+
- buf.build/grpc-ecosystem/grpc-gateway
200+
```
201+
202+
If your `buf.yaml` has no `deps` section or only references local paths, your project doesn't require BSR access and will work in air-gapped environments without additional configuration.
97203

0 commit comments

Comments
 (0)