Hosting Fibel
Run Fibel as a documentation server or mount the documentation under a route in an existing app.
Fibel exposes a fetch handler. The documentation can run as its own server or be mounted under a route in an existing web app.
Develop locally
Use the development command while editing content and configuration.
bunx --bun @k2b/fibel dev --port 5173The command loads fibel.config.ts, builds the theme CSS, creates the documentation app, and starts a local server.
The development server watches the config file, docs folder, and assets folder. When a change is detected, Fibel rebuilds the app in memory and reloads connected browser tabs after the rebuild succeeds.
bunx --bun @k2b/fibel dev --no-watch
bunx --bun @k2b/fibel dev --no-reloadIf a rebuild fails, the server keeps serving the last working app and prints the error in the terminal.
The watcher covers content, assets, and the config file only. Editing a project plugin or any other TypeScript file does not trigger a rebuild, so restart the server after changing plugin code.
Build for deployment
bunx --bun @k2b/fibel buildThe build creates a runtime entry and generated documentation files. Requests still pass through Fibel. This keeps the theme cookie, search, Markdown routes, and mounted paths consistent.
If the host owns its server bundle and output directory, generate only Fibel's runtime stylesheet:
import { buildFibelStyles } from "@k2b/fibel/build";
await buildFibelStyles(process.cwd(), true);The stylesheet is written to .fibel/public/styles.css. The second argument
enables minification. The host remains responsible for its other assets and for
replacing its build output.
Deploy behind Traefik
The recommended deployment is the container image behind Traefik.
services:
docs:
image: ghcr.io/k2b-dev/fibel:latest
labels:
- traefik.enable=true
- traefik.http.routers.docs.rule=Host(`docs.example.com`)
- traefik.http.routers.docs.tls.certresolver=letsencrypt
- traefik.http.services.docs.loadbalancer.server.port=3000The server listens on PORT, which defaults to 3000. Set siteUrl in fibel.config.ts to the same host so canonical URLs and the sitemap match the deployment.
For a project's own documentation, build an image from the project instead of using the Fibel image and keep the same labels.
Run the default docs image
The Fibel repository includes a Docker image for hosting the default documentation.
docker build -t fibel-docs .
docker run --rm -p 3000:3000 fibel-docsThe image uses a Bun multi-stage build. It installs development dependencies only in the build stage, runs typecheck, tests, and build, then runs the generated server as the non-root bun user with production dependencies.
Tagged releases publish the image to GitHub Container Registry:
docker run --rm -p 3000:3000 ghcr.io/k2b-dev/fibel:latest
docker run --rm -p 3000:3000 ghcr.io/k2b-dev/fibel:v0.7.2Mount in Hono
import { Hono } from "hono";
import config from "./fibel.config";
import { createFibelApp } from "@k2b/fibel";
const docs = await createFibelApp(config);
const app = new Hono();
app.mount("/docs", docs.fetch);Set routing.basePath to the same path:
export default defineFibel({
title: "My Docs",
routing: {
basePath: "/docs",
},
});Fibel then generates links, internal routes, and assets relative to /docs.
If this instance enables agentSkillsPlugin(), also forward its
origin-scoped well-known route:
app.all("/.well-known/agent-skills/*", (c) =>
docs.fetch(c.req.raw),
);The host must do this explicitly because a /docs subrouter never receives
requests for the origin root. See Agent Skills discovery.
Mount several instances
Several Fibel instances can run in one server and one deployment. Separate base paths keep their navigation, search indexes, assistant context, chat sessions, MCP endpoints, and path-scoped discovery routes independent:
const docs = await createFibelApp(docsConfig); // basePath: "/docs"
const ui = await createFibelApp(uiConfig); // basePath: "/ui"
export default new Hono()
.mount("/docs", docs.fetch)
.mount("/ui", ui.fetch);The instances can share the same header configuration, theme cookie, assistant provider, and process-wide rate limiters. Only one instance can own origin-level Agent Skills discovery; route /.well-known/agent-skills/* to that explicit owner. The custom pages guide shows the complete header and Solid SSR setup.
Mount in other servers
Any environment that can pass a Web-standard Request to a fetch handler can serve Fibel.
const docs = await createFibelApp(config);
export default {
fetch(request: Request) {
return docs.fetch(request);
},
};The host remains responsible for outer routing, authentication, or middleware. Fibel handles only requests forwarded to the documentation app.
Routes
A Fibel app handles:
- Page routes such as
/en/configuration. - Markdown source routes such as
/en/configuration.md. - Internal files under
routing.internalPath. - Assets under
routing.assetsPath. - Plugin routes, including the SEO and
llms.txtfiles. - Origin-scoped plugin routes when the outer server forwards them.
- A redirect from the mount root to the default locale, so
/lands on/en.
When a project runs under a base path, external links and reverse proxies should preserve that path.