Skip to content

rmdes/indiekit-cloudron

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

860 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Indiekit for Cloudron

An IndieWeb-ready blog platform for Cloudron. Deploy your own IndieWeb site with full Micropub support, webmentions, and syndication to Mastodon/Bluesky.

Features

IndieWeb Standards

  • Micropub - Post from any Micropub client (Quill, Indigenous, iA Writer, etc.)
  • Webmentions - Receive and display likes, reposts, and replies
  • IndieAuth - Sign in with your domain
  • Microformats2 - Full h-entry, h-card, h-feed, h-cite markup
  • POSSE - Syndicate to Mastodon, Bluesky, IndieNews, and LinkedIn
  • Bridgy - Content classes for cross-posting
  • ActivityPub - Native fediverse federation via Fedify (actor, inbox, outbox, followers/following, Mastodon migration)
  • Mastodon Client API - Compatible with Phanpy, Elk, Moshidon, Fedilab — post and read your timeline from any Mastodon client
  • Microsub - Built-in social reader with feed subscriptions and channels

Post Types

  • Articles (long-form)
  • Notes (short posts)
  • Photos
  • Bookmarks
  • Likes
  • Replies
  • Reposts
  • Events, RSVPs, Jams, Audio, Video

Theme Features

  • Responsive design with dark mode
  • Tailwind CSS styling
  • RSS and JSON feeds
  • Sitemap generation
  • Image optimization
  • Social embeds (YouTube, Mastodon, Bluesky)
  • Reply context display (h-cite)
  • Interactions pages (likes, replies, reposts)

Optional Integrations

  • GitHub - Display activity, starred repos, contributions
  • Funkwhale - Show listening history
  • Last.fm - Show scrobbles, loved tracks, statistics
  • YouTube - Display channel activity, latest videos, live status
  • RSS reader - Aggregate feeds, cache in MongoDB
  • Microsub - Social reader with channels and feed subscriptions
  • Blogroll - Aggregate blogs from OPML/Microsub
  • Podroll - Aggregate podcast episodes
  • Conversations - Cross-platform notification aggregation (Mastodon, Bluesky, ActivityPub)
  • Comments - Visitor comments via IndieAuth/RelMeAuth
  • Read Later - Save URLs for later consumption
  • CV/Resume - Optional homepage sections with admin editor
  • Homepage builder - Drag-drop sections from CV, GitHub, Funkwhale, Last.fm, etc.
  • LinkedIn - OAuth + syndication to LinkedIn

Post Type Plugins

  • Pages - Slash pages (/about, /now, /uses) via @rmdes/indiekit-post-type-page

Installation

Building Locally (Recommended)

The multi-site architecture (plugin registry, per-site manifests) requires building with make on your local machine. The GitHub Actions CI pipeline does not run make compose, so pre-built generic images are currently unavailable.

To deploy to Cloudron:

  1. Clone and initialize:

    git clone https://github.com/rmdes/indiekit-cloudron.git
    cd indiekit-cloudron
    make init
  2. Create your site (or use existing sites/rmendes/ or sites/chardonsbleus/):

    mkdir -p sites/mysite/config
    cp nginx.conf.template sites/mysite/config/nginx.conf
    cp indiekit.config.js.template sites/mysite/config/indiekit.config.js
    cp redirects.map.template sites/mysite/config/redirects.map
    cp old-blog-redirects.map.template sites/mysite/config/old-blog-redirects.map
    touch sites/mysite/config/env.sh  # add your secrets
    make use SITE=mysite
  3. Deploy:

    make deploy SITE=mysite APP=mysite.example.com

Note on pre-built images: The Docker Hub :latest and tagged images were built with the single-site architecture and will not work with the current multi-site codebase. Build locally with make deploy instead.

Multi-site Deployment

This repo is site-agnostic by design. The committed files are generic (*.template config, Makefile, Dockerfile, plugin-registry submodule, and theme submodule). Per-site configuration lives in sites/<name>/config/ (gitignored, private).

Directory structure:

indiekit-cloudron/
├── *.template                          # committed: generic defaults
├── plugin-registry/                    # submodule: version-pinned plugin catalog
├── eleventy-site/                      # submodule: public theme
├── Makefile, Dockerfile, CloudronManifest.json, …
│
└── sites/                              # gitignored, one dir per site
    ├── rmendes/
    │   ├── config/
    │   │   ├── plugins.yaml            # enable/disable plugins per site
    │   │   ├── nginx.conf              # site-specific nginx config
    │   │   ├── indiekit.config.js      # site-specific Indiekit config
    │   │   ├── env.sh                  # secrets, API keys
    │   │   ├── redirects.map, old-blog-redirects.map
    │   └── .compiled/                  # generated by `make compose` — do not hand-edit
    │
    └── chardonsbleus/
        ├── config/
        │   ├── plugins.yaml            # chardonsbleus enables: donation, webmention-io, cv, etc.
        │   ├── nginx.conf
        │   ├── indiekit.config.js
        │   ├── env.sh
        │   └── …
        └── .compiled/

Key differences from single-site:

  1. plugins.yaml — Per-site enable/disable of optional plugins (registry defaults, then site overrides)
  2. Plugin registryplugin-registry/plugin-registry.yaml is the source of truth for plugin versions (except the 7 forked defaults, whose pins live in the root package.json overrides field)
  3. Composed artifactsmake compose SITE=<site> merges registry + site manifest into .compiled/ directory
  4. Dockerfile — Consumes .compiled/ via --build-arg SITE=<site>, no hardcoded plugin list

Switching sites:

make use SITE=mysite        # remember as default (writes .current-site)
make which                  # show active site
make build                  # uses the default site
make build SITE=othersite   # one-off override
make deploy SITE=mysite APP=mysite.example.com

Adding a new site:

make new-site NAME=mynewsite      # scaffolds sites/mynewsite/config/
# then edit sites/mynewsite/config/{plugins.yaml, indiekit.config.js, nginx.conf, env.sh}
make use SITE=mynewsite
make deploy SITE=mynewsite APP=mynewsite.example.com

Theme customization:

There is exactly one canonical theme (the eleventy-site/ submodule) shared by every site — per-site theme forks/overrides are not supported. Per-site identity, branding, colors, navigation, and homepage layout are configured at runtime through the site-config plugin admin UI (/site-config), which stores settings in MongoDB and renders per-site theme.css / site-config.json / homepage.json.

First-Run Configuration

  1. SSH into the container: cloudron exec --app yourdomain.com
  2. Edit /app/data/config/env.sh with your API tokens and site settings
  3. Restart the app: cloudron restart --app yourdomain.com

Configuration

Environment Variables

All configuration is done via environment variables in /app/data/config/env.sh. Copy env.example as a reference.

Required Variables

Variable Description Example
SITE_URL Your site URL (no trailing slash) https://example.com
SITE_NAME Site name My Blog
AUTHOR_NAME Your name Jane Doe

Optional Variables

See env.example for all options:

  • Author details (bio, avatar, location, email)
  • Social links (for rel="me" verification)
  • Syndication (Mastodon, Bluesky credentials)
  • Webmentions (webmention.io token)
  • Integrations (GitHub, Funkwhale, YouTube)

Legacy URL Redirects

If migrating from another platform (micro.blog, Known, WordPress), you can set up redirects in redirects.map:

/2023/01/15/old-post.html /content/notes/2023-01-15-new-slug/;

The nginx.conf.template includes example patterns for common legacy URL formats.

Usage

Posting

Use any Micropub client:

Or use the built-in editor at /create on your site.

Admin Dashboard

Access /admin or /dashboard on your site to:

  • View recent posts
  • Check syndication status
  • Manage content

Webmentions

  1. Sign up at webmention.io
  2. Add your token to WEBMENTION_IO_TOKEN in env.sh
  3. Webmentions will appear on your posts automatically

Bridgy for Cross-Posting

To syndicate and receive responses from Mastodon/Bluesky:

  1. Connect your accounts at brid.gy
  2. The theme includes Bridgy-compatible content classes

Development & Deployment

Makefile Commands

# Site selection
make use SITE=<site>                    # Set default site
make which                              # Show active site

# Plugin management (updates plugin-registry submodule)
make registry-update                    # Pull latest plugin-registry
make plugin-list SITE=<site>            # Show enabled plugins
make plugin-add SITE=<site> PLUGIN=key  # Enable a plugin
make plugin-remove SITE=<site> PLUGIN=key # Disable a plugin

# Build & Deploy
make compose SITE=<site>                # Merge registry + site manifest → .compiled/
make prepare                            # Materialize config files from sites/<site>/config/
make build SITE=<site>                  # Compose + prepare + cloudron build
make deploy SITE=<site> APP=<app>       # Build + cloudron update to app
make update                             # Redeploy last built image (retry)

# Logs & Access
make logs                               # Follow Cloudron logs
make shell                              # SSH into container

# Reference
make help                               # Show all commands

Plugin Version Bumping Workflow

For registry-managed plugins:

# 1. Edit plugin in its standalone repo
cd ~/code/indiekit-dev/indiekit-endpoint-github
# ... make changes ...
npm version minor
git push

# 2. User publishes (requires OTP)
# (User runs: npm publish)

# 3. Update registry and deploy
cd ~/code/indiekit-dev/indiekit-cloudron
# Edit plugin-registry/plugin-registry.yaml, bump github version
make registry-update  # pulls submodule, commits pointer
make deploy SITE=rmendes APP=rmendes.net

For overridden default plugins:

# 1. Edit plugin, bump version, push
# 2. User publishes
# 3. Update overrides in package.json
cd ~/code/indiekit-dev/indiekit-cloudron
# Edit package.json overrides field
make deploy SITE=rmendes APP=rmendes.net

Local Eleventy Development

cd eleventy-site
npm install
npm run build:css   # Build Tailwind CSS
npm run build       # Build site
npm run serve       # Development server with watch

Architecture

┌─────────────────────────────────────────────────────┐
│                    nginx (port 3000)                │
│         Static files + Proxy to Indiekit           │
└─────────────────┬───────────────────────────────────┘
                  │
      ┌───────────┴───────────┐
      │                       │
      ▼                       ▼
┌─────────────┐       ┌─────────────┐
│  Eleventy   │       │   Indiekit  │
│  (watcher)  │       │ (port 8080) │
│             │       │             │
│ Builds HTML │       │ Micropub    │
│ from content│◄──────│ IndieAuth   │
│             │       │ Syndication │
└─────────────┘       └─────────────┘
      │                       │
      ▼                       ▼
┌─────────────────────────────────────────────────────┐
│              /app/data (persistent)                 │
│  content/  site/  config/  images/  uploads/       │
└─────────────────────────────────────────────────────┘

Directory Structure

/app/pkg (read-only, Docker image)
├── eleventy-site/          # Theme and build tools
│   ├── _data/              # Site data (env-configured)
│   ├── _includes/          # Nunjucks templates
│   ├── css/                # Compiled Tailwind CSS
│   └── node_modules/       # Eleventy dependencies
├── start.sh                # Entry point
├── nginx.conf              # nginx config
├── indiekit.config.js.template
├── redirects.map           # Legacy URL redirects
└── old-blog-redirects.map

/app/data (persistent, backed up)
├── config/                 # Runtime config (env.sh, indiekit.config.js)
├── content/                # User posts (notes/, articles/, etc.)
├── site/                   # Generated static HTML
├── cache/                  # Eleventy cache
├── images/                 # User images
└── uploads/                # Media uploads

Customization

Adding Your Avatar

  1. Set AUTHOR_AVATAR in env.sh to your image path
  2. Place your avatar in eleventy-site/images/ (or use /images/user/ for runtime uploads)

CV/Resume Sections

To display CV sections on the homepage:

  1. Edit eleventy-site/_data/cv.js with your experience, projects, skills, education
  2. Rebuild — sections only appear when data exists

Custom Theme Modifications

Edit files in eleventy-site/:

  • _includes/layouts/ - Page layouts
  • _includes/components/ - Reusable components
  • css/tailwind.css - Custom styles
  • tailwind.config.js - Tailwind configuration

Indiekit Plugins

Plugin versions are pinned in two places:

  • Registry-managed plugins: plugin-registry/plugin-registry.yaml
  • Overridden default plugins: package.json overrides field

Per-site plugin selection: sites/<site>/config/plugins.yaml

Core (always loaded)

  • @rmdes/indiekit-endpoint-site-config - Per-site identity, branding, homepage, blog config via MongoDB (replaces deprecated homepage-builder)
  • @rmdes/indiekit-startup-gate - Library that defers plugin background tasks until after first Eleventy build (memory contention prevention)
  • @rmdes/indiekit-preset-eleventy - Eleventy preset (permalink fix for pages)
  • @indiekit/store-file-system - Local file storage
  • @indiekit/endpoint-json-feed - JSON feed
  • Forked defaults (via npm overrides): auth, micropub, syndicate, posts, files, share, frontend

Federation & Social (optional, enable per-site)

  • @rmdes/indiekit-endpoint-activitypub - ActivityPub federation via Fedify — actor, inbox, outbox, followers/following, Mastodon migration, Mastodon Client API
  • @rmdes/indiekit-endpoint-microsub - Microsub social reader
  • @rmdes/indiekit-endpoint-conversations - Conversation aggregation across Mastodon/Bluesky/ActivityPub
  • @rmdes/indiekit-endpoint-comments - Visitor comments via IndieAuth/RelMeAuth
  • @rmdes/indiekit-endpoint-webmention-io - Webmention.io integration and public API
  • @rmdes/indiekit-endpoint-webmention-sender - Webmention sender
  • @rmdes/indiekit-endpoint-bluesky-pds - Bluesky PDS integration

Syndication (optional, enable per-site)

  • @rmdes/indiekit-syndicator-mastodon - Mastodon syndication (with external like/repost)
  • @rmdes/indiekit-syndicator-bluesky - Bluesky syndication (with external like/repost)
  • @rmdes/indiekit-syndicator-indienews - IndieNews submission
  • @rmdes/indiekit-syndicator-linkedin - LinkedIn syndication
  • @rmdes/indiekit-endpoint-linkedin - LinkedIn OAuth endpoint

Aggregation & Feeds (optional, enable per-site)

  • @rmdes/indiekit-endpoint-rss - RSS feed reader
  • @rmdes/indiekit-endpoint-blogroll - Blog aggregator (OPML/Microsub)
  • @rmdes/indiekit-endpoint-podroll - Podcast aggregator (FreshRSS, OPML)

Identity & Activity (optional, enable per-site)

  • @rmdes/indiekit-endpoint-github - GitHub activity (commits, stars, contributions)
  • @rmdes/indiekit-endpoint-funkwhale - Funkwhale listening history
  • @rmdes/indiekit-endpoint-lastfm - Last.fm scrobbles
  • @rmdes/indiekit-endpoint-youtube - YouTube channel activity
  • @rmdes/indiekit-endpoint-cv - CV/Resume management
  • @rmdes/indiekit-endpoint-donation - Stripe-backed donation campaigns (chardonsbleus-specific)
  • @rmdes/indiekit-endpoint-readlater - Save URLs for later

Post Types (optional, enable per-site)

  • Article, Note, Photo, Bookmark, Reply, Repost, Like (always enabled)
  • @rmdes/indiekit-post-type-page - Slash pages (/about, /now, /uses)
  • Audio, Video, Event, Jam, RSVP (optional per-site)

Credits

License

MIT License

About

Indiekit deployment for Cloudron with IndieWeb-native Eleventy theme

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors