Self-hosting FreshRSS on a Raspberry Pi device
I love RSS/Atom and am subscribed to at least 75 feeds via the NetNewsWire app on my macOS laptop. While the app works great, sometimes, I want to read blogs on my phone too and my current setup didn't allow that. I was thinking to solve this for me for a long time, and finally got the idea and time to build a better reading setup when I learned about FreshRSS and that it can also be self-hosted.
Initially, I was ready to self-host this on a tiny VPS, but then I decided to use the tiny Raspberry Pi 4B with 1GB RAM that I had. Now that the setup is ready and I am already using it, it only consumes <250MB of RAM on the Pi device.
In this post, I will note down the whole installation process and my experience at the end:
1. Installing Docker
Docker made the process of installing and maintaining FreshRSS easier, and it was also the recommended way to install the app.
I, first, connected to my Pi device from my macOS laptop via SSH and then ran the following commands to install and start Docker.
# Refresh package lists
sudo apt update
# Install Docker engine + CLI + Compose
sudo apt install -y docker.io docker-cli docker-compose
# Start Docker now and on boot
sudo systemctl enable --now docker
# Test iif everything is working
docker --version
docker compose version
sudo docker run hello-world
Earlier, my device was using ~100MB of RAM when it had nothing installed, and now it was using ~180-ish MB of RAM.
2. Installing FreshRSS on the Pi
As Docker was ready, I proceeded with installing the FreshRSS app.
First, created a new folder in the root called freshrss and a few subfolders by running the following command:
# Create a new folder and subfolders
mkdir -p ~/freshrss/data ~/freshrss/extensions
# Go into the newly created folder
cd ~/freshrss
Created the compose.yaml file in the freshrss directory with the following content. I used the nano compose.yaml command to create the file, and then pasted the following:
services:
freshrss:
image: freshrss/freshrss:latest
container_name: freshrss
restart: unless-stopped
ports:
- "127.0.0.1:8080:80"
environment:
TZ: Asia/Kolkata
CRON_MIN: "13,43"
volumes:
- ./data:/var/www/FreshRSS/data
- ./extensions:/var/www/FreshRSS/extensions
healthcheck:
test: ["CMD", "cli/health.php"]
interval: 75s
timeout: 10s
retries: 3
start_period: 60s
You might need to modify the TZ (timezone) value, as per your location. And then started the container:
# Start the docker container
sudo docker compose up -d
# Check status using these commands
sudo docker compose ps
If everything works, exit using ctrl + c.
Now, the app is ready and running at the port 8080, but you can't access it from your different devices yet. From here, you have 2 options:
- Use Tailscale on all your devices to access
- Expose the app to the internet using Cloudflare Tunnel
From the security and ease-of-setup point of view, the #1 method is the best here. But I also wanted to give access to the feed reader app to my friend, so I went with the #2 option.
I will explain the Cloudflare Tunnel method here.
3. Exposing the app to the public internet
First, I needed to install cloudflared on my Pi, so I ran following commands one by one:
sudo mkdir -p --mode=0755 /usr/share/keyrings
curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null
echo 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared any main' | \
sudo tee /etc/apt/sources.list.d/cloudflared.list
sudo apt update
sudo apt install -y cloudflared
I also had to sign up to my Cloudflare account, go to Networking > Tunnels section, and create a Tunnel. Just gave the tunnel a name, and it gave me a command like below that I ran on the Pi:
# Connect to the Cloudflare dashboard
sudo cloudflared service install a_very_long_string_here
# Keep the tunnel running
sudo systemctl enable --now cloudflared
After this I added a destination subdomain, and then added http://localhost:8080 as the service URL, and the app was live.
I opened the destination subdomain I set up in the browser, and FreshRSS installation checklist was shown, then it asked me to sign up for the admin account, and I was in. I tried adding an RSS feed for testing, and it was working.
4. Importing my reading list and final look
I maintain this blogroll page on my website, so I added these feeds to the app. And then I also imported a .opml file shared by Andrej Karpathy earlier, it contained 90+ RSS/Atom feeds of most popular blogs on HackerNews.
I probably don't need all these, but as I spend more time reading, I will slowly keep unsubscribing to the feeds where the content is not relevant to me.
Apart from this, I also did a bit of customizations from the settings, and below is the final look for the reader. The sidebar can be toggled off, so the overall look is cleaner.
Initially, it required getting used to the UI as I have only used NetNewsWire previously and that is simpler to use. But now I like this as well, and have already been using it for a few days.
How the Raspberry Pi 4B is performing
The Pi device is performing surprisingly well. Currently, me and friend both are using the self-hosted RSS reader, and it doesn't even lag or slow down, even for a bit. And still only uses less than 250 MB of RAM, sometimes, even less than 200 MB, as you see below:
I am not on an extremely fast but on a 200 Mbps fiber internet connection (I mean, people already moved to Gbps, right?), and loading is still very fast – faster than many managed RSS reader web-apps I have tried.
Also, earlier, I had the Pi device connected to a power adapter via a type-c cable. But then I noticed a USB port on my WiFi router and connected to it, and now it takes the power from the router itself, as you see in the photo above.
What I like about FreshRSS
Some things I love about the open-source FreshRSS app are:
- It fetches feed updates on the server-side in the background, so I don't have to wait for 2 minutes for all 90 feeds to get refreshed. When I open the public URL in the browser, it's ready for me to read as new updates are already fetched.
- When you mark a post as favorite, it's permanently saved in the SQLite database it uses. Even if the original version is deleted, you still have the locally saved version.
FreshRSS has tons of options that I am still exploring and learning about, and will keep this page updated as I discover more noteworthy things.
Webmentions