Why RSS Still Matters
Every morning, millions of people open YouTube, Twitter, or Reddit and let an algorithm decide what they see. The feed is optimized for engagement, not for what you actually care about. RSS is the antidote: a simple, open protocol that pulls content from websites directly to you, with no algorithm in the middle, no tracking, and no ads.
If you’ve ever felt like you’re losing hours scrolling through content you don’t remember choosing, RSS gives you back control. You subscribe to exactly the sources you want, and new articles arrive in chronological order. That’s it.
In this tutorial, we’ll set up FreshRSS, a self-hosted RSS reader that runs on any cheap VPS or home server. It’s lightweight, fast, and gives you a clean reading experience accessible from any device.
Prerequisites
- A Linux server (Ubuntu 22.04 or newer) with at least 512MB RAM
- Docker and Docker Compose installed
- A domain name pointed at your server (optional but recommended)
- Basic comfort with the command line
Step 1: Create the Project Directory
Let’s keep things tidy. Create a directory for FreshRSS:
mkdir -p ~/freshrss && cd ~/freshrss
Step 2: Write the Docker Compose File
Create a docker-compose.yml file with the following content:
version: "3.8"
services:
freshrss:
image: freshrss/freshrss:latest
container_name: freshrss
restart: unless-stopped
ports:
- "8080:80"
environment:
- TZ=America/New_York
- CRON_MINUTE=13,43
volumes:
- freshrss_data:/var/www/FreshRSS/data
- freshrss_extensions:/var/www/FreshRSS/extensions
depends_on:
- db
db:
image: postgres:16-alpine
container_name: freshrss-db
restart: unless-stopped
environment:
- POSTGRES_DB=freshrss
- POSTGRES_USER=freshrss
- POSTGRES_PASSWORD=your_secure_password_here
volumes:
- db_data:/var/lib/postgresql/data
volumes:
freshrss_data:
freshrss_extensions:
db_data:
What’s happening here: We’re running two containers — FreshRSS itself and a PostgreSQL database. PostgreSQL is optional (FreshRSS also supports SQLite), but it gives you better performance if you subscribe to more than a handful of feeds. The CRON_MINUTE setting tells FreshRSS to check for new articles at 13 and 43 minutes past every hour. Adjust to taste.
Don’t forget to change your_secure_password_here to an actual password. If you’re not sure what to use, a random string works fine — you won’t need to type it again.
Step 3: Start the Containers
From the ~/freshrss directory, run:
docker compose up -d
This will download the images and start both services in the background. The first run takes a minute or two. You can check progress with:
docker compose logs -f freshrss
Press Ctrl+C to stop watching the logs.
Step 4: Complete the Web Setup
Open your browser and go to http://your-server-ip:8080. You’ll see the FreshRSS setup page:
- Choose your language and click “Continue”
- Select PostgreSQL as the database type
- Enter the database details:
- Host:
db(the service name from docker-compose) - Database:
freshrss - Username:
freshrss - Password: whatever you set in the compose file
- Host:
- Create your admin account
- Click “Complete installation”
Step 5: Add Your First Feeds
Once logged in, click the + button in the top-left corner to add a feed. Start with something simple:
https://jerithai.com/feed/
FreshRSS will auto-discover the feed URL and pull in recent articles. Add as many feeds as you like — blogs, news sites, YouTube channels (yes, YouTube supports RSS!), and more.
Pro tip: Many sites hide their RSS feeds. If you can’t find one, try adding /feed/ or /rss/ to the end of a URL, or use a tool like feedfinder to discover hidden feeds.
Step 6: Set Up HTTPS (Recommended)
If you have a domain, put Nginx in front of FreshRSS with a reverse proxy and Let’s Encrypt. Here’s a minimal Nginx config:
server {
listen 80;
server_name rss.yourdomain.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name rss.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/rss.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/rss.yourdomain.com/privkey.pem;
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Then get your certificate:
sudo certbot --nginx -d rss.yourdomain.com
Step 7: Access on Mobile
FreshRSS works with any RSS reader app that supports FreshRSS’s API. On iOS, try Fiery Feeds or Unread. On Android, Readify or FocusReader work well. Just point them to your server URL and log in with your FreshRSS credentials.
This means you can read your feeds on your phone without installing a separate app per source — everything flows through your self-hosted instance.
Common Pitfalls
Feeds not updating
Check that the cron job is running. Inside the container:
docker exec freshrss php /var/www/FreshRSS/app/actualize.php
If this works but automatic updates don’t, verify your CRON_MINUTE environment variable is set correctly.
Database connection errors
Make sure the database service name in the setup matches what’s in your compose file. Docker Compose uses the service name (db) as the hostname, not localhost.
Permission errors on data volume
If FreshRSS complains about file permissions, the container’s www-data user needs write access to the data volume. This usually works out of the box with named volumes, but if you switch to bind mounts, you may need to adjust ownership.
Why Bother?
Self-hosting an RSS reader takes about 15 minutes to set up and then just runs. The payoff is a reading experience that’s entirely yours — no promoted posts, no suggested content, no engagement metrics driving what you see. Just the articles you chose to subscribe to, in the order they were published.
In a world where every platform is fighting for your attention, RSS is a quiet act of resistance. It says: I decide what I read.
And honestly? It just feels nice to open an app and see exactly what you expected to see.
Leave a Reply