A self-hostable knowledge base and documentation site for small and medium businesses. Built with Jekyll and the Chirpy theme, with an optional Microsoft Entra ID SSO gate, an Azure Static Web Apps deployment path, and a Microsoft Teams tab.
Live demo: kb.trever.cloud
- Documentation-native out of the box: left-sidebar navigation, per-page table of contents, categories, tags, and full-text search.
- Jekyll + Chirpy with custom branding, favicons, and contact links.
- GitHub Actions pipeline builds
_site/with Ruby 3.3 and deploys to Cloudflare Pages. - Optional: Microsoft Teams tab, Azure Static Web Apps deployment, and Entra ID auth gate via MSAL.js — all disabled by default and ready to enable.
.
├── _config.yml # Site-wide settings (title, theme options, analytics, etc.)
├── _posts/ # All dated markdown articles that render at /posts/:title/
├── _tabs/ # Top-level navigation tabs (About, Archives, Categories, Tags)
├── _data/ # Contact info and share metadata used across layouts
├── _includes/
│ └── metadata-hook.html # Optional MSAL auth hook — disabled by default
├── _plugins/ # Custom Jekyll plugins (last-modified-at hook)
├── assets/ # Images, favicons, and downloadable static files
├── teams/
│ └── index.html # Teams tab entry point — disabled by default
├── manifest/ # Teams app manifest, icons, and packaged .zip for upload
├── tools/ # Local helper scripts (run.sh, test.sh)
├── staticwebapp.config.json # Azure Static Web App routing rules (optional)
├── .github/workflows/ # CI/CD pipeline (build + deploy to Cloudflare Pages)
├── .devcontainer/ # VS Code Dev Container for a prebuilt Jekyll toolchain
└── _site/ # Generated output (never edit by hand, not committed)
- Ruby 3.3 (matches
ruby/setup-ruby@v1in CI) and Bundler. - Node/Yarn are not required.
- Optional: Docker/Dev Containers to reuse
.devcontainer/devcontainer.json.
Install dependencies:
bundle install# Serve with auto-reload
bundle exec jekyll serve --livereload
# Or use the helper (adds Docker polling + host options)
bash tools/run.shDefault dev URL: http://127.0.0.1:4000. Set JEKYLL_ENV=production (or bash tools/run.sh -p) to mirror CI behavior.
To validate links before pushing:
bash tools/test.shThis script rebuilds _site/ and runs htmlproofer with external checks disabled.
- Filename format:
_posts/YYYY-MM-DD-title.md - Required front matter:
---
title: My Post Title
description: A short one-line summary
date: 2025-11-18 15:03:00 -0500
categories: [Category, Subcategory]
tags: [tag1, tag2]
---Place screenshots or diagrams under assets/img/... and reference them with /assets/img/....
Files inside _tabs/ become persistent navigation entries (Archives, Categories, Tags, About). Add new .md files with order: front matter to create additional tabs.
_data/contact.yml/_data/share.yml: power sidebar contact links and share cards.
Favicons and avatar live in assets/img/. For large downloads, create subfolders under assets/.
On every push to main, .github/workflows/deploy-cloudflare.yml builds the site with Jekyll and deploys to Cloudflare Pages.
Required repository secrets:
| Secret | Where to find it |
|---|---|
CLOUDFLARE_API_TOKEN |
Cloudflare dashboard → My Profile → API Tokens → Edit Cloudflare Pages template |
CLOUDFLARE_ACCOUNT_ID |
Cloudflare dashboard → Workers & Pages → right sidebar |
CLOUDFLARE_PROJECT_NAME |
Name of your Pages project in Cloudflare |
If you connected this repo via Cloudflare's Git integration, disable automatic builds in Cloudflare Pages settings to avoid double-deploys.
Deployments finish in ~2–3 minutes. No manual steps required as long as main stays green.
staticwebapp.config.json is present with routing config. To enable Azure deployment:
- Create an Azure Static Web App resource in the Azure portal.
- Copy the deployment token from the resource's Overview page.
- Add it as a repository secret:
AZURE_STATIC_WEB_APPS_API_TOKEN. - Add an Azure deployment workflow using
Azure/static-web-apps-deploy@v1.
_includes/metadata-hook.html contains a full MSAL browser auth implementation that hides every page until the visitor signs in with a Microsoft account. It is entirely wrapped in an HTML comment and has no effect by default.
To enable:
- Create an Azure App Registration (type: Single-page application).
- Note the Application (client) ID and Directory (tenant) ID.
- Add a redirect URI:
https://your-domain.com/. - Open
_includes/metadata-hook.htmland follow the instructions at the top of the file.
teams/index.html is the Teams tab entry point; manifest/manifest.json is the app manifest. Both are present but non-functional until you:
- Replace
YOUR_CLIENT_IDinmanifest/manifest.jsonwith your App Registration client ID. - Enable the Teams SSO block in
teams/index.html(instructions are in the file). - Enable the auth gate in
_includes/metadata-hook.html(see above). - Zip the contents of
manifest/(not the folder itself) and sideload it in Microsoft Teams.
Replace manifest/color.png (192×192) and manifest/outline.png (32×32) with your own icons before uploading.
- Dev Container: launches
mcr.microsoft.com/devcontainers/jekyll:2-bullseye, sets Zsh as the default shell, and installs useful Liquid/Markdown extensions. - Scripts:
tools/run.sh: wrapsbundle exec jekyll s -l, handles Docker volume polling, and provides--host/--productionflags.tools/test.sh: production build + htmlproofer sanity checks.
- Inline scripts: Jekyll's
compress_htmlminifier strips all newlines. Never use//single-line comments inside<script>blocks in Jekyll includes — use/* block comments */instead.
- Branch off
main. - Add or update content plus any supporting assets/data.
- Run
bundle exec jekyll serve(and ideallybash tools/test.sh) to validate locally. - Push to
main. GitHub Actions deploys automatically.
This repository is published under the MIT License inherited from the Chirpy theme.