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
- Open
https://your-domain.comin a browser - Click “Sign up” and enter a username and email address
- Go to
https://your-domain.com/mailto find the confirmation email - 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
- Dave Winer — creator of FeedLand, RSS, OPML, and podcasting. FeedLand source code lives at github.com/scripting.
- Scott Hansonde — created the original Docker Compose setup for FeedLand that this deployment builds upon.
- FeedLand documentation — the official docs for understanding FeedLand’s features and API.
Links
- This repo: github.com/rmdes/feedland-docker
- FeedLand docs: docs.feedland.com
- FeedLand install guide (upstream): github.com/scripting/feedlandInstall
- Original Docker Compose: github.com/scotthansonde/feedlandDockerCompose
AI: Text Editorial · Code AI-assisted · Claude
Editorial assistance — article drafted by human, AI helped with structure and clarity

Comments
Sign in with your website to comment:
Loading comments...
No comments yet. Be the first to share your thoughts!