How to Self-Host FreshRSS with Docker Compose: Your Personal News Garden

Why You Need Your Own RSS Reader

Remember when the internet felt like a place you chose to visit? When you curated your own little corner of the web instead of having an algorithm decide what you see?

RSS is the original internet subscription protocol — and it’s still the most powerful tool for taking back control of your information diet. No ads, no engagement bait, no rage-optimized feeds. Just the content you actually want, on your terms.

FreshRSS is a self-hosted RSS feed aggregator that’s lightweight, feature-rich, and surprisingly easy to set up. Think of it as your personal news garden: you plant the seeds (subscribe to feeds), and FreshRSS helps you tend and harvest them.

What You’ll Need

  • A server or machine running Linux (Ubuntu 22.04+ recommended)
  • Docker and Docker Compose installed
  • A domain name pointed at your server (optional but recommended for mobile access)
  • About 15 minutes of your time

Step 1: Install Docker and Docker Compose

If you haven’t already, install Docker on your Ubuntu server:

sudo apt update
sudo apt install -y docker.io docker-compose-v2
sudo systemctl enable docker
sudo systemctl start docker
sudo usermod -aG docker $USER

Log out and back in so the group change takes effect. Verify with:

docker --version
docker compose version

Step 2: Create the Project Directory

We’ll keep everything organized in one directory:

mkdir -p ~/freshrss
cd ~/freshrss

Step 3: Write the Docker Compose File

Create docker-compose.yml with the following configuration. This sets up FreshRSS with a PostgreSQL database — more reliable than SQLite for long-term use:

cat <<'EOF' > docker-compose.yml
version: "3.8"

services:
  freshrss:
    image: freshrss/freshrss:latest
    container_name: freshrss
    restart: unless-stopped
    ports:
      - "8080:80"
    environment:
      - CRON_MINUTE=13,43
      - TZ=America/Los_Angeles
      - FRESHRSS_BASE_URL=https://rss.yourdomain.com
    volumes:
      - freshrss_data:/var/www/FreshRSS/data
      - freshrss_extensions:/var/www/FreshRSS/extensions
    depends_on:
      - db
    networks:
      - freshrss_net

  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
    networks:
      - freshrss_net

volumes:
  freshrss_data:
  freshrss_extensions:
  db_data:

networks:
  freshrss_net:
EOF

Let’s break down what’s happening here:

  • CRON_MINUTE=13,43 — FreshRSS uses its own internal cron to fetch new articles. This fetches twice an hour at :13 and :43. Adjust to taste — */5 would fetch every 5 minutes.
  • TZ — Set this to your timezone. FreshRSS uses it for scheduling and display.
  • FRESHRSS_BASE_URL — Important for proper link generation, especially if you put this behind a reverse proxy.
  • PostgreSQL — We’re using Postgres instead of SQLite because it handles concurrent reads better and is easier to back up.

Step 4: Start FreshRSS

docker compose up -d

Check that both containers are running:

docker compose ps

You should see freshrss and freshrss_db both in running state.

Step 5: Complete the Web Installation

Open your browser and navigate to http://your-server-ip:8080. You’ll be greeted by the FreshRSS setup wizard:

  1. Step 1: Select your language and check the environment requirements (all should be green).
  2. Step 2: Configure the database. Use these settings:
    • Database type: PostgreSQL
    • Host: db (this matches the service name in docker-compose)
    • Port: 5432
    • Database name: freshrss
    • Username: freshrss
    • Password: your_secure_password_here (same as in your compose file)
  3. Step 3: Create your admin account. Choose a strong password — this is the keys to your news kingdom.
  4. Step 4: Add your first feeds! Start with a few blogs or news sites you love.

Step 6: (Optional) Put It Behind Nginx with SSL

If you want to access FreshRSS from anywhere (including mobile apps), you’ll want a reverse proxy with HTTPS. Here’s a minimal Nginx config:

server {
    listen 80;
    server_name rss.yourdomain.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    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;
    }
}

Get your SSL certificate with Certbot:

sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d rss.yourdomain.com

Step 7: Connect Mobile Apps

FreshRSS supports the Fever API and its own API, which means you can use it with popular RSS apps:

  • iOS: Reeder, Unread, or Fiery Feeds
  • Android: Feedly (with Fever plugin), News+
  • Desktop: QuiteRSS, NewsFlow

In your app, use the Fever API endpoint: https://rss.yourdomain.com/api/fever.php and your admin credentials.

Step 8: Set Up Automatic Updates

Docker images get updated regularly. To keep FreshRSS current, create a simple update script:

cat <<'EOF' > ~/freshrss/update.sh
#!/bin/bash
cd ~/freshrss
docker compose pull
docker compose up -d
docker image prune -f
echo "FreshRSS updated at $(date)"
EOF
chmod +x ~/freshrss/update.sh

Then add it to your crontab to run weekly:

crontab -e
# Add this line:
0 3 * * 0 /home/youruser/freshrss/update.sh >> /var/log/freshrss-update.log 2>&1

Common Pitfalls and Troubleshooting

“I can’t reach the setup page”

Check that the port is open in your firewall: sudo ufw allow 8080/tcp. If you’re on a cloud provider, check their security groups too.

“FreshRSS says it can’t connect to the database”

Make sure you used db as the hostname (not localhost or 127.0.0.1). Docker Compose creates a network where containers reach each other by service name.

“Feeds aren’t updating”

Check the cron is running inside the container: docker exec freshrss php /var/www/FreshRSS/app/actualize_script.php. This forces an immediate fetch. Also verify your CRON_MINUTE environment variable is set correctly.

“I want to import my feeds from another reader”

FreshRSS supports OPML import. Export your feeds from your previous reader as an OPML file, then go to FreshRSS → Import/Export → Import. Easy.

“The container uses too much memory”

FreshRSS is quite lightweight, but if you have thousands of feeds, add a memory limit to the compose file under the freshrss service: mem_limit: 256m.

Why This Matters

Self-hosting your RSS reader isn’t just a technical exercise — it’s a small act of digital sovereignty. You’re saying: I decide what I read, when I read it, and how long it stays around.

In a world where platforms rise and fall (RIP Google Reader, 2013), having your own aggregator means your reading history and subscriptions belong to you. Not to a company. Not to an algorithm. To you.

And honestly? There’s something deeply satisfying about opening your own personal news garden every morning, knowing it’s been quietly growing while you slept.

Next Steps

Once you’re comfortable with FreshRSS, explore these features:

  • User accounts: Create separate accounts for family members
  • Tags and categories: Organize feeds into topics
  • Filters: Auto-mark articles as read based on keywords
  • Extensions: Browse the extension marketplace for custom features
  • Web scraping: For sites without RSS feeds, FreshRSS can generate feeds from web pages

Happy reading. 🌱

Leave a Reply

Your email address will not be published. Required fields are marked *