How to Self-Host FeedLand with Docker Compose

FeedLand is an open-source feed reader and sharing platform created by Dave Winer, the pioneer behind RSS itself. It describes itself as “an ecosystem of feeds, news and people” — a place to subscribe to RSS feeds, organize them, discover what others are reading, and share news using open formats instead of proprietary social media silos.

The hosted version at feedland.com is currently paused while Dave builds the next generation of the platform. But the server software is open source, and you can run your own instance today.

This guide walks you through deploying a self-hosted FeedLand using Docker Compose.

What FeedLand Does

If you’ve used an RSS reader before, FeedLand will feel familiar — but with a social layer on top:

  • Subscribe to feeds and organize them into categories
  • Read news from all your subscriptions in one place
  • See what others are reading through shared feed lists and a public hotlist
  • Share and discover feeds in a community-driven way

Everything is built on open standards (RSS, OPML). Your feed lists are portable. There’s no algorithmic feed — you see what you subscribe to.

What You’ll Need

  • A Linux server (VPS or dedicated) with Docker and Docker Compose v2 installed
  • A domain name with DNS pointing to your server
  • Ports 80 and 443 open (for HTTP and HTTPS)

That’s it. No Node.js installation, no MySQL setup, no reverse proxy configuration — Docker handles all of it.

Architecture Overview

The deployment runs four containers:

Internet → Caddy (automatic HTTPS via Let's Encrypt)
              ├─ /mail  → Mailpit (email web UI)
              ├─ ws://  → FeedLand WebSocket
              └─ /*     → FeedLand HTTP
                            ↓
                         MySQL 8.0
  • FeedLand — the Node.js application server
  • MySQL 8.0 — the database (FeedLand is MySQL-only)
  • Caddy — reverse proxy that handles TLS certificates automatically
  • Mailpit — a built-in mail catcher for signup confirmation emails

Only Caddy is exposed to the internet. FeedLand, MySQL, and Mailpit communicate over internal Docker networks. Caddy cannot even reach the database — network segmentation is enforced at the Docker level.

Step 1: Clone the Repo

git clone https://github.com/rmdes/feedland-docker.git
cd feedland-docker

Step 2: Generate Your Configuration

Run the setup script. It will prompt for your domain name and generate strong random MySQL passwords:

./scripts/generate-env.sh

This creates a .env file with everything FeedLand needs to start. The only required input is your domain name.

Step 3: Start Everything

docker compose up -d

Docker pulls the images (first run only), creates the database, generates the FeedLand configuration, and starts all four services. Caddy automatically obtains a TLS certificate from Let’s Encrypt.

Check that everything is healthy:

docker compose ps

You should see all four containers with status (healthy) or Up.

Step 4: Create Your First User

  1. Open https://your-domain.com in a browser
  2. Click “Sign up” and enter a username and email address
  3. Go to https://your-domain.com/mail to find the confirmation email
  4. Click the confirmation link

The built-in Mailpit catches all emails sent by FeedLand and makes them available at /mail on your domain. This means email confirmation works out of the box — no external SMTP server needed for a single-user setup.

Configuring Real SMTP (Multi-User)

For a multi-user instance where confirmation emails need to reach real inboxes, edit .env and add your SMTP credentials:

SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USERNAME=you@gmail.com
SMTP_PASSWORD=your_app_password
MAIL_SENDER=noreply@your-domain.com

Then restart FeedLand:

docker compose restart feedland

The built-in Mailpit stays running but FeedLand will route emails through your real SMTP server instead.

Backups

A backup script is included. It dumps the MySQL database to a compressed file:

./scripts/backup.sh

Backups are stored in ./backups/ with the last 7 retained by default. For automatic daily backups, add a cron job:

crontab -e
0 3 * * * cd /path/to/feedland-docker && ./scripts/backup.sh >> backups/cron.log 2>&1

To restore from a backup:

gunzip < backups/feedland-2026-02-17_120000.sql.gz | \
  docker compose exec -T mysql \
  mysql -uroot -p"$MYSQL_ROOT_PASSWORD" feedland

Updating FeedLand

When a new version of the FeedLand image is published:

docker compose pull feedland
docker compose up -d

If the update includes database schema changes (check the FeedLand worknotes), apply them with the migration script:

./scripts/migrate.sh path/to/migration.sql

All Configuration Options

Variable Default Description
FEEDLAND_DOMAIN (required) Your domain name
MYSQL_ROOT_PASSWORD (required) MySQL root password
MYSQL_PASSWORD (required) MySQL password for FeedLand
SMTP_HOST mailpit SMTP server (default: built-in Mailpit)
SMTP_PORT 1025 SMTP port
SMTP_USERNAME (empty) SMTP username
SMTP_PASSWORD (empty) SMTP password
MAIL_SENDER feedland@localhost From address for emails
MYSQL_DATABASE feedland Database name
MYSQL_USER feedland Database username
FEEDLAND_PRODUCT_NAME FeedLand Product name in UI
ENABLE_NEW_USERS true Allow registrations
TZ UTC Timezone

Credits

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
Send a Webmention

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