Go to file
нездалисько ea58c8d2bc
Update 06_Public_Hosts.md (#3877)
2024-01-06 18:13:50 +01:00
.devcontainer Docker from Debian base image (#3500) 2023-09-13 18:08:22 +02:00
.github [prtester] improvements and fixes for prtester (#3721) 2023-09-30 22:09:59 +02:00
actions fix(reddit): cache tweak for 403 forbidden (#3830) 2023-12-13 21:56:14 +01:00
bridges [PepperBridgeAbstract, DealabsBridge, HotUKDealsBridge, MydealsBridge] (#3876) 2024-01-05 07:23:40 +01:00
cache [TwitterBridge] Fix the bridge using a brand new API 2020-06-05 10:17:53 +02:00
caches docs(nginx, phpfpm): improve install and config instructions (#3866) 2023-12-28 23:26:14 +01:00
config Docker fix default fastcgi.logging (#3875) 2024-01-05 07:22:16 +01:00
contrib chore: prepare 2023-09-24 release (#3703) 2023-09-24 20:53:07 +02:00
docs Update 06_Public_Hosts.md (#3877) 2024-01-06 18:13:50 +01:00
formats Add 'itunes:duration' tag for items with duration (#3774) 2023-10-19 17:02:53 +02:00
lib [BridgeAbstract] use getParameters instead of static to allow overriding it from bridges (#3858) 2023-12-26 12:20:49 +01:00
static [BridgeCard] add example value to info hint and allow using it by right click (#3726) 2023-10-02 03:02:57 +02:00
templates feat: embed response in http exception (#3847) 2023-12-20 03:16:25 +01:00
tests test: happy new year (#3873) 2024-01-02 16:21:52 +01:00
vendor fix: various notice fixes (#3718) 2023-09-29 19:17:03 +02:00
.dockerignore [Docker file] Fix wrong version string in docker images (#2497) 2022-03-14 05:48:40 +05:00
.git-blame-ignore-revs Add .git-blame-ignore-revs file (#2903) 2022-07-08 17:00:34 +02:00
.gitattributes [Docker] force unix line ending on bash files to prevent docker run failing on windows (#2629) 2022-04-10 18:05:43 +02:00
.gitignore Docker from Debian base image (#3500) 2023-09-13 18:08:22 +02:00
CONTRIBUTORS.md chore: introduce CONTRIBUTORS.md (#2839) 2022-07-04 07:33:23 +02:00
Dockerfile Docker fix default fastcgi.logging (#3875) 2024-01-05 07:22:16 +01:00
README.md docs(nginx, phpfpm): improve install and config instructions (#3866) 2023-12-28 23:26:14 +01:00
UNLICENSE let's unlicense ! 2014-05-21 20:11:01 +02:00
app.json Update app.json 2022-04-26 22:43:13 +02:00
composer.json feat: preserve and reproduce podcast feeds (itunes rss module) (#3759) 2023-10-16 02:58:03 +02:00
composer.lock chore: synchronize composer.lock (#3513) 2023-07-08 17:07:35 +02:00
config.default.ini.php feat: embed response in http exception (#3847) 2023-12-20 03:16:25 +01:00
docker-bake.hcl New docker build mechanism (#2268) 2021-10-03 16:06:30 +02:00
docker-entrypoint.sh Docker from Debian base image (#3500) 2023-09-13 18:08:22 +02:00
index.php docs(nginx, phpfpm): improve install and config instructions (#3866) 2023-12-28 23:26:14 +01:00
phpcompatibility.xml refactor: general code base refactor (#2950) 2022-08-06 22:46:28 +02:00
phpcs.xml ci: incease max line length to 180 (#3714) 2023-09-27 23:29:08 +02:00
phpunit.xml refactor: rename rssbridge.php to bootstrap.php (#2987) 2022-08-27 23:01:06 +02:00
scalingo.json Typo 2016-08-02 23:37:01 +02:00




RSS-Bridge is a PHP web application.

It generates web feeds for websites that don't have one.

Officially hosted instance: https://rss-bridge.org/bridge01/

IRC channel #rssbridge at https://libera.chat/

LICENSE GitHub release irc.libera.chat Actions Status

Screenshot #1 Screenshot #2
Screenshot #3 Screenshot #4
Screenshot #5 Screenshot #6
Screenshot #7 Screenshot #8

A subset of bridges (17/412)

Full documentation

Check out RSS-Bridge right now on https://rss-bridge.org/bridge01/

Alternatively find another public instance.

Requires minimum PHP 7.4.


How to install on traditional shared web hosting

RSS-Bridge can basically be unzipped in a web folder. Should be working instantly.

Latest zip as of Sep 2023: https://github.com/RSS-Bridge/rss-bridge/archive/refs/tags/2023-09-24.zip

How to install on Debian 12 (nginx + php-fpm)

These instructions have been tested on a fresh Debian 12 VM from Digital Ocean (1vcpu-512mb-10gb, 5 USD/month).

timedatectl set-timezone Europe/Oslo

apt install git nginx php8.2-fpm php-mbstring php-simplexml php-curl

# Create a new user account
useradd --shell /bin/bash --create-home rss-bridge

cd /var/www

# Create folder and change ownership
mkdir rss-bridge && chown rss-bridge:rss-bridge rss-bridge/

# Become user
su rss-bridge

# Fetch latest master
git clone https://github.com/RSS-Bridge/rss-bridge.git rss-bridge/
cd rss-bridge

# Copy over the default config
cp -v config.default.ini.php config.ini.php

# Give full permissions only to owner (rss-bridge)
chmod 700 -R ./

# Give read and execute to others (nginx and php-fpm)
chmod o+rx ./ ./static

# Give read to others (nginx)
chmod o+r -R ./static

Nginx config:

# /etc/nginx/sites-enabled/rss-bridge.conf

server {
    listen 80;
    server_name example.com;
    access_log /var/log/nginx/rss-bridge.access.log;
    error_log /var/log/nginx/rss-bridge.error.log;

    # Intentionally not setting a root folder here
    # autoindex is off by default but feels good to explicitly turn off
    autoindex off;

    # Static content only served here 
    location /static/ {
        alias /var/www/rss-bridge/static/;

    # Pass off to php-fpm only when location is exactly /
    location = / {
        root /var/www/rss-bridge/;
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/rss-bridge.sock;

    # Reduce spam
    location = /favicon.ico {
        access_log off;
        log_not_found off;

    # Reduce spam
    location = /robots.txt {
        access_log off;
        log_not_found off;

PHP FPM pool config:

; /etc/php/8.2/fpm/pool.d/rss-bridge.conf


user = rss-bridge
group = rss-bridge

listen = /run/php/rss-bridge.sock

listen.owner = www-data
listen.group = www-data

pm = static
pm.max_children = 10
pm.max_requests = 500

PHP ini config:

; /etc/php/8.2/fpm/conf.d/30-rss-bridge.ini

max_execution_time = 20
memory_limit = 64M

Restart fpm and nginx:

# Lint and restart php-fpm
php-fpm8.2 -t
systemctl restart php8.2-fpm

# Lint and restart nginx
nginx -t
systemctl restart nginx

How to install from Composer

Install the latest release.

cd /var/www
composer create-project -v --no-dev rss-bridge/rss-bridge

How to install with Caddy

TODO. See https://github.com/RSS-Bridge/rss-bridge/issues/3785

Install from Docker Hub:

Install by downloading the docker image from Docker Hub:

# Create container
docker create --name=rss-bridge --publish 3000:80 rssbridge/rss-bridge

# Start container
docker start rss-bridge

Browse http://localhost:3000/

Install by locally building from Dockerfile

# Build image from Dockerfile
docker build -t rss-bridge .

# Create container
docker create --name rss-bridge --publish 3000:80 rss-bridge

# Start container
docker start rss-bridge

Browse http://localhost:3000/

Install with docker-compose

Create a docker-compose.yml file locally with with the following content:

version: '2'
    image: rssbridge/rss-bridge:latest
      - </local/custom/path>:/config
      - 3000:80
    restart: unless-stopped

Then launch with docker-compose:

docker-compose up

Browse http://localhost:3000/

Other installation methods

Deploy on Scalingo Deploy to Heroku Deploy to Cloudron Run on PikaPods

The Heroku quick deploy currently does not work. It might possibly work if you fork this repo and modify the repository in scalingo.json. See https://github.com/RSS-Bridge/rss-bridge/issues/2688

Learn more in Installation.


How to fix "PHP Fatal error: Uncaught Exception: The FileCache path is not writable"

# Give rssbridge ownership
chown rssbridge:rssbridge -R /var/www/rss-bridge/cache

# Or, give www-data ownership
chown www-data:www-data -R /var/www/rss-bridge/cache

# Or, give everyone write permission
chmod 777 -R /var/www/rss-bridge/cache

# Or last ditch effort (CAREFUL)
rm -rf /var/www/rss-bridge/cache/ && mkdir /var/www/rss-bridge/cache/

How to create a new bridge from scratch

Create the new bridge in e.g. bridges/BearBlogBridge.php:


class BearBlogBridge extends BridgeAbstract
    const NAME = 'BearBlog (bearblog.dev)';

    public function collectData()
        $dom = getSimpleHTMLDOM('https://herman.bearblog.dev/blog/');
        foreach ($dom->find('.blog-posts li') as $li) {
            $a = $li->find('a', 0);
            $this->items[] = [
                'title' => $a->plaintext,
                'uri' => 'https://herman.bearblog.dev' . $a->href,

Learn more in bridge api.

How to enable all bridges

Modify config.ini.php:

enabled_bridges[] = *

How to enable some bridges

enabled_bridges[] = TwitchBridge
enabled_bridges[] = GettrBridge

How to enable debug mode

The debug mode disables the majority of caching operations.

enable_debug_mode = true

How to switch to memcached as cache backend


; Cache backend: file (default), sqlite, memcached, null
type = "memcached"

How to switch to sqlite3 as cache backend

type = "sqlite"

How to disable bridge errors (as feed items)

When a bridge fails, RSS-Bridge will produce a feed with a single item describing the error.

This way, feed readers pick it up and you are notified.

If you don't want this behaviour, switch the error output to http:


; Defines how error messages are returned by RSS-Bridge
; "feed" = As part of the feed (default)
; "http" = As HTTP error message
; "none" = No errors are reported
output = "http"

How to accumulate errors before finally reporting it

Modify report_limit so that an error must occur 3 times before it is reported.

; Defines how often an error must occur before it is reported to the user
report_limit = 3

The report count is reset to 0 each day.

How to password-protect the instance

HTTP basic access authentication:


enable = true
username = "alice"
password = "cat"

Will typically require feed readers to be configured with the credentials.

It may also be possible to manually include the credentials in the URL:


How to create a new output format

See formats/PlaintextFormat.php for an example.

How to run unit tests and linter

These commands require that you have installed the dev dependencies in composer.json.

./vendor/bin/phpcs --standard=phpcs.xml --warning-severity=0 --extensions=php -p ./

How to spawn a minimal development environment

php -S


We are RSS-Bridge community, a group of developers continuing the project initiated by sebsauvage, webmaster of sebsauvage.net, author of Shaarli and ZeroBin.


RSS-Bridge uses caching to prevent services from banning your server for repeatedly updating feeds. The specific cache duration can be different between bridges. Cached files are deleted automatically after 24 hours.

RSS-Bridge allows you to take full control over which bridges are displayed to the user. That way you can host your own RSS-Bridge service with your favorite collection of bridges!

Current maintainers (as of 2023): @dvikan and @Mynacol #2519


Feed item structure

This is the feed item structure that bridges are expected to produce.

    $item = [
        'uri' => 'https://example.com/blog/hello',
        'title' => 'Hello world',
        // Publication date in unix timestamp
        'timestamp' => 1668706254,
        'author' => 'Alice',
        'content' => 'Here be item content',
        'enclosures' => [
        'categories' => [
        // Globally unique id
        'uid' => 'e7147580c8747aad',

Output formats

  • Atom: Atom feed, for use in feed readers
  • Html: Simple HTML page
  • Json: JSON, for consumption by other applications
  • Mrss: MRSS feed, for use in feed readers
  • Plaintext: Raw text, for consumption by other applications
  • Sfeed: Text, TAB separated

Cache backends

  • File
  • SQLite
  • Memcached
  • Array
  • Null


The source code for RSS-Bridge is Public Domain.

RSS-Bridge uses third party libraries with their own license:


Dear so-called "social" websites.

Your catchword is "share", but you don't want us to share. You want to keep us within your walled gardens. That's why you've been removing RSS links from webpages, hiding them deep on your website, or removed feeds entirely, replacing it with crippled or demented proprietary API. FUCK YOU.

You're not social when you hamper sharing by removing feeds. You're happy to have customers creating content for your ecosystem, but you don't want this content out - a content you do not even own. Google Takeout is just a gimmick. We want our data to flow, we want RSS or Atom feeds.

We want to share with friends, using open protocols: RSS, Atom, XMPP, whatever. Because no one wants to have your service with your applications using your API force-feeding them. Friends must be free to choose whatever software and service they want.

We are rebuilding bridges you have willfully destroyed.

Get your shit together: Put RSS/Atom back in.