//nbkelley /homelab

Self-Hosted CMS Options & Landscape#

What Was Established#

  • User seeks a self-hosted CMS for an Ubuntu VM, explicitly rejecting WordPress due to business practices.
  • Preference for tools respected by the web development and self-hosting communities.
  • Exploration of CMS categories: Monolithic, Flat-file, Static Site Generators (SSG), Headless CMS, and Custom.

Key Decisions#

  • Rejected WordPress: Cited business practices as a dealbreaker.
  • Favoring Developer-Respected Alternatives: Leaned towards headless or modern flat-file CMS options.
  • Top Contenders Identified: Directus (Headless), Strapi (Headless), Kirby (Flat-file), Payload CMS (Headless/TS), Ghost (Blogging).

CMS Landscape & Options#

Monolithic CMS#

  • WordPress: Dominant (60% market), huge ecosystem, but rejected by user.
  • Drupal: Flexible, steep learning curve.
  • Joomla: Balanced ease/power, smaller community.

Flat-file CMS (No Database)#

  • Grav: Fast, simple, file-based.
  • Kirby: Beautiful UI, file-based, commercial license (~$129), highly respected by designers/devs.

Static Site Generators (SSG)#

  • Jekyll: GitHub Pages compatible.
  • Hugo: Blazing fast, Go-based.
  • Eleventy: Flexible, JS-based.
  • Next.js: React-based, hybrid.

Headless CMS (API-Driven)#

  • Directus: Community favorite. Node.js/Vue.js. Provides REST/GraphQL APIs, beautiful admin UI. Excellent for full frontend control.
  • Strapi: Most popular headless. Node.js/React. Strong plugin ecosystem.
  • Payload CMS: Rising star. TypeScript-first, excellent DX.
  • Ghost: Primarily for blogging/publishing. Markdown-native.
  • Contentful/Sanity: Enterprise/Developer friendly, but often cloud-hosted (though self-hostable options exist).

Custom / Build-Your-Own#

  • The Guardian’s “Composer”: Fully custom-built in Scala/Play Framework. Not recommended for small projects.
  • Server-Side: PHP includes, Python (Django/Flask), Node.js (Express).
  • For Maximum Control & Flexibility: Directus or Payload CMS.
  • For Content-Focused Sites: Kirby or Statamic.
  • For API-Driven Projects: Strapi.
  • Quick Start (Directus on Ubuntu):
    curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
    sudo apt-get install -y nodejs
    npm create directus-project@latest my-cms
    cd my-cms
    npm install
    npx directus start

Historical Notes#

  • Conversation date: 2025-11-17.
  • User explicitly stated a preference against WordPress due to business practices.
  • Focus remains on self-hosted, developer-respected tools.
  • Note: Directus and Strapi have evolved significantly since late 2025; verify current self-hosting requirements, licensing, and Docker compatibility for homelab deployment.

Hugo-Specific Configuration#

Project Structure#

myblog/
├── config.toml   -- Main configuration (baseURL, languageCode, title, theme)
├── content/      -- Blog posts in Markdown
├── themes/       -- Installed themes (git submodules)
├── static/       -- Static assets (images, JS, CSS)
└── public/       -- Generated static files (deployed to Nginx)

Key config.toml Settings#

  • baseURL — Domain URL (e.g., https://blog.nbkelley.com)
  • theme — Must match theme folder name in themes/
  • buildDraftstrue during development, false for production
  • paginate — Posts per page

Creating Posts#

hugo new posts/my-post.md  # Draft in content/posts/
hugo -D                     # Build including drafts
hugo                        # Production build to public/

Deployment Options#

  • Manual rsync: rsync -avz --delete public/ user@server:/var/www/html/blog
  • Git webhook: Server-side script that git pull && hugo && cp -r public /var/www/html/blog on push
  • Cloudflare Pages: Push Hugo source to GitHub, Cloudflare builds and deploys automatically

Comments for Static Sites#

  • Utterances — GitHub issues-based, no backend
  • Disqus — Traditional, JS-based
  • Hyvor Talk — Self-hostable alternative

Sources#

  • ingested/chats/106-Beginner Guide to Building Websites with Ubuntu.md
  • ingested/chats/036-Setting Up Self-Hosted Blogs with Nginx.md
  • DeepSeek conversation: “Self-Hosted Websites on Ubuntu Server” (historical)
  • DeepSeek conversation: “Setting Up Self-Hosted Blogs with Nginx” (chat 036)