So this happened Saturday before last: I went to look at an old post from 2016 (the one about my disastrous first Raspberry Pi cluster, don't ask) and every embedded tweet on it was just... gone. Blank grey boxes where jokes used to be. Turns out that wasn't a bug on my end. Musk announced over that July 1st weekend that Twitter would start rate-limiting how many tweets people can even view per day — something like 600 for verified accounts, 300 if you're not verified, and a genuinely insulting 6 per day if you're a brand new unverified account. The official reason was "extreme levels of data scraping," which, sure, maybe, but the actual effect was that TweetDeck broke, embeds broke, and half my archive suddenly looks like it's been redacted by a government agency.
I'm not going to spend this whole post ranting about Twitter's death spiral, everyone's covering that this month and I don't have anything new to add except that it personally annoyed me enough to finally fix something I'd been putting off for about four years: I didn't have a real RSS reader anymore.
I used to. Everyone did. Then Google Reader died in 2013 (I wrote about that here too, back when this blog was about eighteen months old) and I just... drifted into checking Twitter lists instead, because for a while that was genuinely a fine replacement. It isn't anymore. So last weekend I set up FreshRSS on a little VPS and I want to walk through exactly how, because it took me under twenty minutes and I feel a little silly for waiting this long.
What you actually need
- A cheap VPS. I'm using a $6/month DigitalOcean droplet I already had sitting around running almost nothing.
- Docker and docker-compose installed on it.
- About fifteen minutes and a coffee.
The setup
FreshRSS ships an official Docker image, so the whole thing is one compose file:
version: "3"
services:
freshrss:
image: freshrss/freshrss:latest
ports:
- "8080:80"
volumes:
- ./data:/var/www/FreshRSS/data
- ./extensions:/var/www/FreshRSS/extensions
environment:
- TZ=America/New_York
restart: unless-stopped
Run docker-compose up -d, point your browser at your-server-ip:8080, and you get a setup wizard: pick SQLite unless you're planning on subscribing to a genuinely absurd number of feeds, in which case go MySQL. Took me about four minutes including the time I spent trying to remember my own droplet's IP address.
After that, it's just adding feeds. Most blogs and news sites still publish one, even now: try sitename.com/feed or /rss or /atom.xml and one of those almost always works. This blog's is at /feed, obviously, and has been since day one because I am, if nothing else, consistent.
The part I actually like is the mobile side. FreshRSS speaks the Fever API and the Google Reader API, so any of the old-school readers (Reeder, NetNewsWire, Unread) will sync against your own self-hosted instance instead of some startup's servers that might not exist in three years. I'm using NetNewsWire on my phone and it's been fine, though I'll admit the sync lags by a minute or two sometimes and I don't fully know why yet.
Why bother
Because I don't want the thing that tells me when a blog I like has posted to be a company that can, on a random Saturday, decide I'm only allowed to read 300 things that day. That's the whole reason, really. I put a handful of tech blogs back in there this week that I used to follow religiously ten years ago and had completely lost track of: some are dead, a couple are somehow still going, which honestly gives me hope for this one.
I'm not deleting my Twitter account or anything dramatic like that. I still check it most mornings around 7, mostly out of habit at this point. But it's nice having a reading list again that isn't at the mercy of one guy's mood about scraping bots. If you've got a spare VPS sitting around doing nothing, this is a good weekend project, and a genuinely better use of that box than whatever half-finished side project has been squatting on it since 2021.