Project-agnostic documentation engine. Aggregates markdown from remote Git repositories into a single static site.
- Define sources in
folio.config.ts(Git repos with docs directories) folio stagefetches docs via sparse-clone, skipping unchanged reposfolio buildrenders everything with Astro and indexes with Pagefind
bun install
bun run stage # fetch docs from remote repos
bun run dev # stage + start dev server
bun run build # stage + build + pagefind indexUse --force to bypass the cache and re-fetch all sources.
// folio.config.ts
import { defineConfig } from './src/index.js';
export default defineConfig({
site: {
title: 'My Docs',
siteUrl: 'https://docs.example.com',
},
sources: [
{
name: 'my-project',
url: 'https://github.com/org/repo',
docsDir: 'docs',
mount: '/my-project',
},
],
});Each source supports:
| Field | Default | Description |
|---|---|---|
name |
required | Identifier for caching |
url |
required | Git remote URL |
branch |
main |
Branch to fetch |
docsDir |
docs |
Directory containing markdown |
includeFiles |
["README.md"] |
Extra files from repo root |
mount |
required | URL path prefix |
Container stack with nginx, a rebuild cron, and a Pangolin tunnel via Newt.
cd deploy
cp .env.example .env
# fill in credentials
podman-compose up -dCreate a new site in your Pangolin dashboard for your docs domain (e.g. docs.example.com). Configure the resource target to point at the nginx container:
| Setting | Value |
|---|---|
| Target host | folio-nginx |
| Target port | 80 |
| Protocol | http |
Then create a Newt and copy the credentials into deploy/.env:
PANGOLIN_ENDPOINT=https://pangolin.example.com
NEWT_ID=your-newt-id-here
NEWT_SECRET=your-newt-secret-here
REBUILD_INTERVAL=21600
MPL-2.0. See LICENSE.