Deploy Your Own IndieWeb Site on Cloudron with Indiekit

What You’ll Build

By the end of this tutorial, you’ll have:

  • A personal website at your own domain
  • The ability to post from any Micropub client (Quill, Indiepass, iA Writer)
  • Automatic syndication to Mastodon and Bluesky
  • Webmentions showing likes, replies, and reposts from across the web
  • Optional activity widgets for GitHub, YouTube, Funkwhale, or Last.fm

Live Example: rmendes.net

Prerequisites

Before starting, you’ll need:

  • A Cloudron server (self-hosted)
  • A domain configured in Cloudron
  • Basic familiarity with the command line & cloudron cli
  • Git/Docker installed on your local machine

Optional (for syndication and integrations):

  • Mastodon account and access token
  • Bluesky account and app password
  • webmention.io account
  • API keys for GitHub, YouTube, Funkwhale, or Last.fm

Part 1: Installation

Step 1: Clone the Repository

git clone https://github.com/rmdes/indiekit-cloudron.git
cd indiekit-cloudron

Step 2: Initialize the Submodule

The Eleventy theme is included as a Git submodule:

git submodule update --init --recursive

Step 3: Build the Cloudron Image

cloudron build

This builds a Docker image containing:

  • Indiekit (the publishing server)
  • Eleventy (the static site generator)
  • nginx (for serving static files and proxying)
  • All required plugins and dependencies

Note: The first build takes several minutes. Subsequent builds are faster due to caching.

Step 4: Install to Cloudron

cloudron install --app yourdomain.com

Replace yourdomain.com with your actual domain configured in Cloudron.

Step 5: Verify Installation

Visit your domain. You should see a basic site with “Blog coming soon” or similar placeholder content. The admin interface is available at /admin.

Part 2: Basic Configuration

Step 6: Access the Container

cloudron exec --app yourdomain.com

Step 7: Create Your Environment Configuration

cd /app/data/config
cp /app/pkg/env.example env.sh
nano env.sh

Configure the required variables:

# Required - Your site identity
export SITE_URL="https://yourdomain.com"
export SITE_NAME="Your Site Name"
export AUTHOR_NAME="Your Name"

# Optional - Author details
export AUTHOR_BIO="A short bio about yourself"
export AUTHOR_EMAIL="you@example.com"
export AUTHOR_AVATAR="/images/avatar.jpg"
export AUTHOR_LOCATION="City, Country"

# Optional - Social links (for rel="me" verification)
export SOCIAL_GITHUB="https://github.com/yourusername"
export SOCIAL_MASTODON="https://mastodon.social/@yourusername"
export SOCIAL_BLUESKY="https://bsky.app/profile/yourdomain.com"

Step 8: Restart the App

Exit the container (exit) and restart:

cloudron restart --app yourdomain.com

Visit your site - you should now see your configured site name and author information.

Part 3: Setting Up Syndication

Syndication lets you automatically cross-post to social networks when you publish.

Mastodon Syndication

Get a Mastodon Access Token

  1. Log into your Mastodon instance
  2. Go to Preferences → Development → New Application
  3. Name it “Indiekit”
  4. Select scopes: read, write:statuses, write:media
  5. Submit and copy the access token

Configure in env.sh

export MASTODON_ACCESS_TOKEN="your-access-token-here"

The Mastodon instance URL and username are configured in indiekit.config.js (see Part 6).

Bluesky Syndication

Create an App Password

  1. Log into bsky.app
  2. Go to Settings → App Passwords
  3. Create a new app password
  4. Copy the password (you won’t see it again)

Configure in env.sh

export BLUESKY_PASSWORD="your-app-password-here"

Your Bluesky handle is configured in indiekit.config.js.

Bridgy for Backfeed

Bridgy pulls responses (likes, reposts, replies) from social networks back to your site as webmentions.

  1. Visit brid.gy
  2. Connect your Mastodon and/or Bluesky accounts
  3. Bridgy will automatically send webmentions when people interact with your syndicated posts

Part 4: Setting Up Webmentions

Webmentions let other websites notify you when they link to your content.

Step 1: Sign Up for webmention.io

  1. Visit webmention.io
  2. Sign in with your domain (uses IndieAuth)
  3. Go to Settings and copy your API token

Step 2: Configure in env.sh

export WEBMENTION_IO_TOKEN="your-webmention-io-token"

Step 3: Verify Webmention Endpoints

Your site already includes the required <link> tags for webmention discovery. Verify at webmention.rocks.

Part 5: Optional Integrations

These plugins display activity from external services on your site.

GitHub Activity

Shows your commits, stars, PRs, and featured repositories.

Get a GitHub Token

  1. Go to GitHub → Settings → Developer settings → Personal access tokens → Fine-grained tokens
  2. Create a token with public_repo read access
  3. Copy the token

Configure in env.sh

export GITHUB_TOKEN="your-github-token"

YouTube Channel

Displays your latest videos and live streaming status.

Get a YouTube API Key

  1. Go to Google Cloud Console
  2. Create a project or select existing
  3. Enable “YouTube Data API v3”
  4. Go to Credentials → Create Credentials → API Key
  5. (Optional) Restrict to YouTube Data API only

Configure in env.sh

export YOUTUBE_API_KEY="your-youtube-api-key"
export YOUTUBE_CHANNELS="@YourChannel,@AnotherChannel"

Funkwhale Listening Activity

Shows your listening history from a Funkwhale instance.

Get a Funkwhale Token

  1. Log into your Funkwhale instance
  2. Go to Settings → Applications
  3. Create an application with read permissions
  4. Copy the access token

Configure in env.sh

export FUNKWHALE_INSTANCE="https://funkwhale.example.com"
export FUNKWHALE_USERNAME="yourusername"
export FUNKWHALE_TOKEN="your-funkwhale-token"

Last.fm Scrobbles

Shows your listening history from Last.fm.

Get a Last.fm API Key

  1. Visit last.fm/api/account/create
  2. Create an API account
  3. Copy the API key

Configure in env.sh

export LASTFM_API_KEY="your-lastfm-api-key"
export LASTFM_USERNAME="yourusername"

Part 6: Customizing indiekit.config.js

For advanced configuration, you can customize the Indiekit config.

Step 1: Copy the Template

cloudron exec --app yourdomain.com
cp /app/pkg/indiekit.config.js.template /app/data/config/indiekit.config.js
nano /app/data/config/indiekit.config.js

Step 2: Key Configuration Options

export default {
  application: {
    mongodbUrl: process.env.MONGODB_URL,
    url: process.env.CLOUDRON_APP_URL,
    name: "Your Site Name",
    locale: "en",
    timeZone: "Europe/London",  // Change to your timezone
  },

  publication: {
    me: "https://yourdomain.com",
    categories: ["blog", "notes", "links", "photos"],
  },

  // Mastodon configuration
  "@indiekit/syndicator-mastodon": {
    url: "https://mastodon.social",  // Your instance
    user: "yourusername",
    accessToken: process.env.MASTODON_ACCESS_TOKEN,
    checked: true,  // Enable by default when posting
  },

  // Bluesky configuration
  "@indiekit/syndicator-bluesky": {
    handle: "yourdomain.com",  // Or your-handle.bsky.social
    password: process.env.BLUESKY_PASSWORD,
    checked: true,
  },

  // GitHub plugin
  "@rmdes/indiekit-endpoint-github": {
    mountPath: "/githubapi",
    username: "yourusername",
    token: process.env.GITHUB_TOKEN,
    featuredRepos: [
      "yourusername/cool-project",
      "yourusername/another-project",
    ],
  },

  // ... other plugins
};

Step 3: Restart After Changes

exit
cloudron restart --app yourdomain.com

Part 7: Publishing Your First Post

Option 1: Using the Built-in Editor

  1. Visit https://yourdomain.com/admin
  2. Sign in with IndieAuth (your domain)
  3. Click “Create” → “Note”
  4. Write your post
  5. Check syndication targets (Mastodon, Bluesky)
  6. Publish

Option 2: Using Quill

  1. Visit quill.p3k.io
  2. Sign in with your domain
  3. Authorize Quill to post to your site
  4. Compose and publish

Option 3: Using Indigenous (iOS)

  1. Install Indigenous from the App Store
  2. Add your site URL
  3. Authenticate with IndieAuth
  4. Post from your phone

Part 8: Customizing the Theme

The Eleventy theme can be customized by creating override files.

Theme Structure

eleventy-site/
├── _includes/
│   ├── layouts/       # Page layouts
│   │   ├── base.njk   # Base HTML template
│   │   ├── home.njk   # Homepage layout
│   │   └── post.njk   # Individual post layout
│   └── components/    # Reusable components
├── _data/             # Site data files
├── css/
│   └── tailwind.css   # Custom styles
└── content/           # Your posts (symlinked to /app/data/content)

Adding Custom CSS

Edit eleventy-site/css/tailwind.css to add custom styles:

@tailwind base;
@tailwind components;
@tailwind utilities;

/* Your custom styles */
.custom-class {
  @apply text-primary-600 dark:text-primary-400;
}

Modifying Templates

Templates use Nunjucks syntax. Key files:

  • _includes/layouts/home.njk - Homepage layout
  • _includes/layouts/post.njk - Post template with syndication, webmentions
  • _includes/components/ - Header, footer, navigation, etc.

After modifying theme files, rebuild and redeploy:

cloudron build --no-cache
cloudron update --app yourdomain.com

Part 9: Maintenance

Viewing Logs

cloudron logs -f --app yourdomain.com

Manual Eleventy Rebuild

If posts aren’t appearing, trigger a manual rebuild:

cloudron exec --app yourdomain.com -- bash -c "cd /app/pkg/eleventy-site && ./node_modules/.bin/eleventy --output=/app/data/site"

Updating the App

When updates are released:

cd indiekit-cloudron
git pull
git submodule update --remote
cloudron build --no-cache
cloudron update --app yourdomain.com

Backup

Cloudron automatically backs up /app/data/ which includes:

  • Your content (/app/data/content/)
  • Generated site (/app/data/site/)
  • Configuration (/app/data/config/)
  • Uploaded images (/app/data/images/)

Troubleshooting

“Blog coming soon” instead of content

The Eleventy build failed. Check logs:

cloudron logs -f --app yourdomain.com

Common causes:

  • Template syntax errors
  • Missing environment variables
  • Permission issues

Posts not syndicating

  1. Verify tokens in env.sh are correct
  2. Check that syndicators are enabled in indiekit.config.js
  3. Look for errors in logs after posting

Webmentions not appearing

  1. Verify WEBMENTION_IO_TOKEN is set
  2. Check webmention.io dashboard for received mentions
  3. Webmentions are fetched at build time - trigger a rebuild

Admin login failing

IndieAuth requires proper <link rel="me"> tags and authorization endpoint. Verify your homepage includes:

<link rel="authorization_endpoint" href="https://yourdomain.com/auth">
<link rel="token_endpoint" href="https://yourdomain.com/auth/token">

Architecture Reference

┌─────────────────────────────────────────────────────┐
│                    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/       │
└─────────────────────────────────────────────────────┘

Resources

All my forks/new indiekit repo’s are here


Questions or issues? Open an issue on GitHub or find me on the IndieWeb chat.

AI: Text Editorial · Code AI-assisted · Claude

Editorial assistance — article drafted by human, AI helped with structure and clarity

Learn more about AI usage on this site

Comments

Sign in with your website to comment:

Signed in as

Webmentions (1)

1 Like

Send a Webmention

Have you written a response to this post? Send a webmention by entering your post URL below.