TIL: Publishing an Obsidian Vault with MkDocs + GitHub Pages
What I built
A public knowledge base at notes.serg-markovich.de from an Obsidian vault using MkDocs Material, GitHub Actions and Cloudflare DNS.
DevOps patterns applied
1. Separation of concerns
Keep each project in its own repository with independent commit history. The public vault is separate from the main website — different content, different deploy pipelines.
2. Everything as code
All config lives in files — never manual changes in GitHub UI:
mkdocs.yml— site configuration.github/workflows/deploy.yml— CI/CD pipeline.gitignore/.gitattributes— repo hygiene
3. CI/CD with GitHub Actions
Every git push to main triggers automatic build and deploy. Pin mkdocs<2.0, not mkdocs-material — MkDocs 2.0 is the breaking change.
4. Immutable build artifacts
The site/ folder is never committed — generated fresh on every deploy. Add site/ to .gitignore.
5. DNS without proxy for GitHub Pages
Cloudflare orange cloud breaks GitHub Pages SSL validation. Use grey cloud (DNS only) with CNAME pointing to serg-markovich.github.io.
Troubleshooting
Actions runs in 15s and silently fails
Cause: YAML syntax error — GitHub ignores invalid workflow files silently. Fix: Recreate with heredoc to avoid indentation issues:
Permission denied on git push
Cause: Remote set to SSH, but no key added to GitHub. Fix:
GitHub Pages shows Jekyll instead of MkDocs
Cause: Auto-generated jekyll-gh-pages.yml conflicts with custom workflow.
Fix:
Theme material has no configuration file
Cause: MkDocs 2.0 installed — incompatible with mkdocs-material. Fix:
github-actions[bot] permission denied on push
Cause: Missing permissions block in workflow. Fix: