FreshRSS Feed Reader Installation
FreshRSS is a lightweight, self-hosted RSS and Atom feed aggregator that lets you follow hundreds of news sources and blogs without relying on Google Reader alternatives or commercial services. With a Fever and Google Reader-compatible API, it integrates with popular mobile RSS apps, and its multi-user support with per-user feed configurations makes it suitable for both personal and family server deployments.
Prerequisites
- Ubuntu 20.04+, Debian 11+, or CentOS/Rocky 8+
- PHP 8.1+ with required extensions
- A web server (Apache or Nginx)
- MySQL/MariaDB or SQLite (SQLite works for single-user setups)
- Root or sudo access
Installing FreshRSS
Method 1: Docker (recommended):
# Create FreshRSS directory
sudo mkdir -p /opt/freshrss/{data,extensions}
# Run with Docker
docker run -d \
--name freshrss \
-p 8080:80 \
-e TZ=America/New_York \
-e CRON_MIN="*/10" \
-v /opt/freshrss/data:/var/www/FreshRSS/data \
-v /opt/freshrss/extensions:/var/www/FreshRSS/extensions \
--restart unless-stopped \
freshrss/freshrss
# With Docker Compose for MySQL backend:
sudo tee /opt/freshrss/docker-compose.yml <<'EOF'
version: '3.8'
services:
freshrss-app:
image: freshrss/freshrss:latest
restart: unless-stopped
ports:
- "8080:80"
environment:
TZ: America/New_York
CRON_MIN: "*/10"
FRESHRSS_ENV: production
volumes:
- /opt/freshrss/data:/var/www/FreshRSS/data
- /opt/freshrss/extensions:/var/www/FreshRSS/extensions
depends_on:
- freshrss-db
freshrss-db:
image: mariadb:11
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: root-password
MYSQL_DATABASE: freshrss
MYSQL_USER: freshrss
MYSQL_PASSWORD: db-password
volumes:
- /opt/freshrss/db:/var/lib/mysql
EOF
cd /opt/freshrss && sudo docker compose up -d
Method 2: Manual installation with Nginx:
# Install dependencies
sudo apt install -y nginx php8.1-fpm php8.1-curl php8.1-xml \
php8.1-mbstring php8.1-zip php8.1-intl \
php8.1-mysql php8.1-sqlite3
# Download FreshRSS
cd /var/www
sudo git clone https://github.com/FreshRSS/FreshRSS.git
sudo chown -R www-data:www-data FreshRSS/
# Set correct permissions
sudo chmod -R 755 /var/www/FreshRSS/
sudo chmod -R 775 /var/www/FreshRSS/data/
Configure Nginx for FreshRSS:
# /etc/nginx/sites-available/freshrss
server {
listen 80;
server_name rss.example.com;
root /var/www/FreshRSS/p/;
location / {
try_files $uri $uri/ index.php;
index index.php index.html;
}
location ~ ^.+\.php {
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
Initial Setup
Web wizard:
- Navigate to
http://your-server:8080(Docker) orhttp://rss.example.com - Select language
- Choose database: MySQL (production) or SQLite (testing)
- For MySQL, enter:
- Host:
freshrss-db(Docker) orlocalhost - Database:
freshrss - Username/password from docker-compose.yml
- Host:
- Create admin account
- Complete setup
Configure refresh schedule:
# Docker automatically sets up cron via CRON_MIN env variable
# For manual install, add cron job:
sudo -u www-data crontab -e
# Add:
# */10 * * * * php /var/www/FreshRSS/app/actualize_script.php > /dev/null 2>&1
Feed Management
Add feeds via the web interface:
- Click + Add a feed (left sidebar)
- Paste the RSS/Atom URL
- Click Add — FreshRSS fetches and shows a preview
- Assign to a category and click Add this feed
Import OPML feed list:
- Go to Settings > Import/Export
- Click Choose File and select your OPML file
- Click Import
Export your feeds as OPML:
# Via CLI
sudo docker compose exec freshrss-app \
php /var/www/FreshRSS/cli/export-opml.php \
--user admin > /opt/freshrss/backup/feeds-backup.opml
Extensions
FreshRSS supports extensions for customization:
# Available extensions: https://github.com/FreshRSS/Extensions
# Install an extension by placing it in the extensions directory
# Example: Install the Reading Time extension
cd /opt/freshrss/extensions
sudo git clone https://github.com/FreshRSS/Extensions.git /tmp/freshrss-extensions
sudo cp -r /tmp/freshrss-extensions/xExtension-ReadingTime ./
# Enable in web UI: Settings > Extensions > Reading Time > Enable
Popular extensions:
- xExtension-ReadingTime: Estimated reading time per article
- xExtension-CustomCSS: Apply custom CSS to the UI
- xExtension-TwitterTimeline: Twitter integration
- xExtension-GoogleCachedImages: Load images via Google Cache
API Access for Mobile Apps
Enable API access:
- Go to Settings > Authentication
- Check Allow API access
- Set an API password (can differ from your login password)
Compatible mobile apps:
| App | Platform | API Type |
|---|---|---|
| Reeder 5 | iOS/macOS | Fever API |
| NetNewsWire | iOS/macOS | Fever API |
| FeedMe | Android | Google Reader API |
| Fluent Reader | Cross-platform | Fever API |
| ReadYou | Android | Google Reader API |
Configure Fever API in mobile apps:
Server URL: https://rss.example.com/api/fever.php
Username: your-username
Password: your-API-password (not login password)
Configure Google Reader API:
Server URL: https://rss.example.com/api/greader.php
Username: your-username
Password: your-API-password
Test the API:
# Test Fever API
curl -d "api_key=$(echo -n 'username:apipassword' | md5sum | cut -c1-32)" \
"https://rss.example.com/api/fever.php?api"
# Test Google Reader API
curl "https://rss.example.com/api/greader.php/accounts/ClientLogin" \
-d "[email protected]&Passwd=apipassword"
User Management
Create additional users:
# Via CLI (Docker)
sudo docker compose exec freshrss-app \
php /var/www/FreshRSS/cli/create-user.php \
--user reader1 \
--password "user-password" \
--email "[email protected]"
# List all users
sudo docker compose exec freshrss-app \
php /var/www/FreshRSS/cli/list-users.php
# Delete a user
sudo docker compose exec freshrss-app \
php /var/www/FreshRSS/cli/delete-user.php \
--user reader1
Database Optimization
MySQL optimization for large feed lists:
-- Connect to the database
sudo docker compose exec freshrss-db \
mysql -u freshrss -p freshrss
-- Optimize tables periodically
OPTIMIZE TABLE freshrss_default_entrytmp;
OPTIMIZE TABLE freshrss_default_entry;
-- Check table sizes
SELECT table_name,
ROUND(((data_length + index_length) / 1024 / 1024), 2) AS size_mb
FROM information_schema.tables
WHERE table_schema = 'freshrss'
ORDER BY size_mb DESC;
Configure article retention:
- Go to Settings > Archival
- Set Maximum number of articles to keep per feed: e.g., 500
- Set Number of days of articles to keep: e.g., 90
- This prevents unbounded database growth
Troubleshooting
Feeds not refreshing automatically:
# Check cron is running in the Docker container
sudo docker compose logs freshrss-app | grep cron
# Force a manual refresh
sudo docker compose exec freshrss-app \
php /var/www/FreshRSS/app/actualize_script.php
# Check error logs
sudo docker compose exec freshrss-app \
cat /var/www/FreshRSS/data/users/admin/log.txt
API authentication failing:
# Verify API access is enabled in Settings > Authentication
# Check the API password (separate from login password)
# Test with verbose output
curl -v -d "api_key=$(echo -n 'user:apipassword' | md5sum | cut -c1-32)" \
"http://localhost:8080/api/fever.php?api"
Slow page loads with many feeds:
# Check database query performance
# Enable MySQL slow query log
sudo docker compose exec freshrss-db \
mysql -u root -p -e "SET GLOBAL slow_query_log=1; SET GLOBAL long_query_time=1;"
# Add database indexes (FreshRSS does this automatically on updates)
# But can manually trigger:
sudo docker compose exec freshrss-app \
php /var/www/FreshRSS/cli/update-user.php --user admin
Conclusion
FreshRSS provides a capable, resource-efficient RSS aggregator that consolidates hundreds of news feeds into a single interface accessible from any device, with API compatibility that works with all major mobile RSS clients. Its multi-user support, extension ecosystem, and configurable article retention make it a practical long-term self-hosting choice for replacing commercial feed readers without the ongoing subscription costs.


