Site runbook¶
How this site is built, how to add to it, and what to do when it breaks.
What's actually running¶
Five moving parts, no servers of your own:
| Part | Where | Job |
|---|---|---|
| Markdown files | docs/ |
The notes themselves |
mkdocs.yml |
repo root | Site config and sidebar order |
theme.css |
docs/stylesheets/ |
Colours, fonts, custom blocks |
requirements.txt |
repo root | Tells Cloudflare what to install |
| Cloudflare Pages | cloud | Rebuilds and hosts on every push |
The flow: write markdown → git push → Cloudflare runs mkdocs build → static HTML lands on the CDN. Nothing is dynamic, nothing has a database.
site/ is generated output. It's gitignored and should stay that way.
Daily workflow¶
Open two terminals.
Terminal 1 — live preview. Leave running while you write:
Browser at localhost:8000. Saves reload automatically.
Terminal 2 — git. When a note's worth keeping:
Cloudflare picks it up within a minute or two.
The venv
source .venv/bin/activate is needed in every new terminal. If mkdocs
says command not found, that's almost always why. The prompt shows
(.venv) when it's active.
Adding a new page¶
Two steps, and the second is the one that gets forgotten.
1. Create the file under the right folder in docs/:
Start it with frontmatter and an H1:
---
status: draft
---
# Ansible Vault
Encrypting secrets so `ansible_password` never sits in plaintext.
2. Add it to nav: in mkdocs.yml, under the section it belongs to:
- 2.0 APIs and protocols:
- IOS-XE with Ansible: apis/ansible-ios.md
- Ansible Vault: apis/ansible-vault.md # ← new
Paths in nav: are relative to docs/, so it's apis/ansible-vault.md, not
docs/apis/ansible-vault.md.
A page not listed in nav: still builds and is reachable by URL — it just
won't appear in the sidebar. If a new page doesn't show up, this is why.
Adding a new section¶
1. Make the folder:
2. Add at least one page — an empty folder does nothing:
3. Add the section to nav:. Order in the file is order in the sidebar:
Indentation is two spaces per level and YAML rejects tabs outright. If VS Code is inserting tabs, bottom-right status bar → click the indent setting → Convert Indentation to Spaces.
Writing: what the theme gives you¶
Callout boxes. Built-in types include note, tip, warning, danger,
example, plus the custom lab type:
!!! lab "Build it from an empty file"
No green dot until I can write this playbook with the docs closed.
!!! warning "Exam trap"
RESTCONF has no candidate datastore. Rollback questions mean NETCONF.
Add ??? instead of !!! to make it collapsible.
Status pills, from theme.css:
Tabs, useful for the same task across platforms:
Code blocks — always tag the language. It drives highlighting and the copy button:
Links between pages use relative paths ending in .md:
MkDocs rewrites those to real URLs at build and warns if the target doesn't exist — which makes it a free broken-link check.
Deploy¶
Automatic. git push to main triggers a Cloudflare build.
To watch it: Cloudflare dashboard → Workers & Pages → your project → Deployments. Click any deployment to see the full build log.
Build settings, for reference if they ever need re-entering:
| Setting | Value |
|---|---|
| Production branch | main |
| Build command | pip install -r requirements.txt && mkdocs build |
| Build output directory | site |
PYTHON_VERSION |
3.12 |
To check a build locally before pushing:
--strict turns warnings into errors, so broken internal links fail the build
instead of shipping quietly.
Troubleshooting¶
mkdocs: command not found¶
The venv isn't active. source .venv/bin/activate. If it's active and still
failing, reinstall: pip install mkdocs-material.
Config value 'site_name': Required configuration not provided¶
mkdocs.yml is empty or malformed. Check first:
Zero lines means a heredoc paste failed silently. Write the file in VS Code
rather than pasting a long block into bash — terminals drop lines on big
multi-line pastes, and a stray EOF inside the content terminates the block
early.
YAML errors on mkdocs serve¶
The error names the line. In order of likelihood: tabs instead of spaces,
wrong indent depth, a missing space after a colon, or an apostrophe in an
unquoted string. Quote any value containing : # ' or ".
A page doesn't appear in the sidebar¶
It's not in nav:. Or the path is wrong — nav: paths are relative to
docs/.
Changes don't show in the browser¶
mkdocs serve only watches docs/. Editing mkdocs.yml needs a restart:
Ctrl+C, then mkdocs serve again.
error: src refspec main does not match any¶
The branch has no commits yet. Commit first, then push:
! [rejected] main -> main (non-fast-forward)¶
Local and remote histories have diverged. Check what's on the remote:
If the remote has nothing you want, git push --force origin main. If it has
work you need, git pull --rebase first. Force-pushing is only safe because
nobody else clones this repo.
command not found running a config file's contents¶
Config blocks (YAML, CSS, a bare package name) are file contents, not
commands. Terminal blocks start with cd, git, mkdocs, pip, echo.
externally-managed-environment from pip¶
Ubuntu blocks system-wide pip. Always install inside the venv — the fix is
source .venv/bin/activate, never --break-system-packages.
Cloudflare build fails: mkdocs: not found¶
requirements.txt is missing from the repo root, or the build command doesn't
install from it. It must be
pip install -r requirements.txt && mkdocs build.
Cloudflare build fails on a plugin¶
The build image's Python may be too old, or the plugin needs git history that
Cloudflare's shallow clone doesn't fetch. Check PYTHON_VERSION is 3.12
first; that fixes most of them.
Site builds but looks unstyled¶
extra_css path is wrong, or theme.css isn't committed. Check:
Custom colours also need primary: custom and accent: custom in the palette
config — without those, Material's own rules outrank the override on
specificity.
Command cheat sheet¶
# start work
cd ~/shan-network-blog && source .venv/bin/activate && mkdocs serve
# save work
git add -A && git commit -m "notes: <what>" && git push
# check before pushing
mkdocs build --strict
# what changed
git status --short
# update the theme
pip install --upgrade mkdocs-material
# see what's tracked
git ls-files
If it all goes wrong¶
The notes are the only irreplaceable part, and they're plain markdown in
docs/. Everything else — venv, config, theme, Cloudflare project — can be
rebuilt in twenty minutes.
Worst case: copy docs/ somewhere safe, delete the folder, re-clone, and
put docs/ back.