fedi feed router is a self-hosted tool for routing content from RSS/Atom feeds to the fediverse.
Find a file
2025-08-08 21:54:22 +02:00
.github/workflows Fresh Laravel + Sail install 2025-06-29 08:50:03 +02:00
backend Remove previous onboarding implementation 2025-08-08 21:54:22 +02:00
docker Fix encryption issue in tests 2025-08-04 21:58:51 +02:00
frontend Clean up root dir 2025-08-03 21:11:19 +02:00
.dockerignore Fix compose issues 2025-07-03 21:16:57 +02:00
.editorconfig Fresh Laravel + Sail install 2025-06-29 08:50:03 +02:00
.gitattributes Fresh Laravel + Sail install 2025-06-29 08:50:03 +02:00
.gitignore Ignore claude 2025-08-04 22:00:01 +02:00
Jenkinsfile Add tests. 2025-08-02 03:48:06 +02:00
README.md Fix logo path 2025-08-07 21:28:56 +02:00

Fedi Feed Router

FFR Logo

ffr is a self-hosted tool for routing content from RSS/Atom feeds to the fediverse.

It watches feeds, matches entries based on keywords or rules, and publishes them to platforms like Lemmy, Mastodon, or anything ActivityPub-compatible.

Features

  • Keyword-based routing from any RSS/Atom feed
  • Publish to Lemmy, Mastodon, or other fediverse services
  • YAML or JSON route configs
  • CLI and/or daemon mode
  • Self-hosted, privacy-first, no SaaS dependencies

Docker Deployment

Building the Image

docker build -t your-registry/lemmy-poster:latest .
docker push your-registry/lemmy-poster:latest

Docker Compose

Create a docker-compose.yml file:

services:
  app-web:
    image: your-registry/lemmy-poster:latest
    command: ["web"]
    ports:
      - "8000:8000"
    environment:
      - DB_DATABASE=${DB_DATABASE}
      - DB_USERNAME=${DB_USERNAME}
      - DB_PASSWORD=${DB_PASSWORD}
      - LEMMY_INSTANCE=${LEMMY_INSTANCE}
      - LEMMY_USERNAME=${LEMMY_USERNAME}
      - LEMMY_PASSWORD=${LEMMY_PASSWORD}
      - LEMMY_COMMUNITY=${LEMMY_COMMUNITY}
    depends_on:
      - mysql
    volumes:
      - storage_data:/var/www/html/storage/app
    restart: unless-stopped

  app-queue:
    image: your-registry/lemmy-poster:latest
    command: ["queue"]
    environment:
      - DB_DATABASE=${DB_DATABASE}
      - DB_USERNAME=${DB_USERNAME}
      - DB_PASSWORD=${DB_PASSWORD}
      - LEMMY_INSTANCE=${LEMMY_INSTANCE}
      - LEMMY_USERNAME=${LEMMY_USERNAME}
      - LEMMY_PASSWORD=${LEMMY_PASSWORD}
      - LEMMY_COMMUNITY=${LEMMY_COMMUNITY}
    depends_on:
      - mysql
    volumes:
      - storage_data:/var/www/html/storage/app
    restart: unless-stopped

  mysql:
    image: mysql:8.0
    command: --host-cache-size=0 --innodb-use-native-aio=0 --sql-mode=STRICT_TRANS_TABLES,NO_ZERO_DATE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION --log-error-verbosity=1
    environment:
      - MYSQL_DATABASE=${DB_DATABASE}
      - MYSQL_USER=${DB_USERNAME}
      - MYSQL_PASSWORD=${DB_PASSWORD}
      - MYSQL_ROOT_PASSWORD=${DB_PASSWORD}
      - TZ=UTC
    volumes:
      - mysql_data:/var/lib/mysql
    restart: unless-stopped

volumes:
  mysql_data:
  storage_data:

Environment Variables

Create a .env file with:

# Database Settings
DB_DATABASE=lemmy_poster
DB_USERNAME=lemmy_user
DB_PASSWORD=your-password

# Lemmy Settings
LEMMY_INSTANCE=your-lemmy-instance.com
LEMMY_USERNAME=your-lemmy-username
LEMMY_PASSWORD=your-lemmy-password
LEMMY_COMMUNITY=your-target-community

Deployment

  1. Build and push the image to your registry
  2. Copy the docker-compose.yml to your server
  3. Create the .env file with your environment variables
  4. Run: docker compose up -d

The application will automatically:

  • Wait for the database to be ready
  • Run database migrations on first startup
  • Start the queue worker after migrations complete
  • Handle race conditions between web and queue containers

Initial Setup

After deployment, the article refresh will run every hour. To trigger the initial article fetch manually:

docker compose exec app-web php artisan article:refresh

The application will then automatically:

  • Fetch new articles every hour
  • Publish valid articles every 5 minutes
  • Sync community posts every 10 minutes

The web interface will be available on port 8000.

Architecture

The application uses a multi-container setup:

  • app-web: Serves the Laravel web interface and handles HTTP requests
  • app-queue: Processes background jobs (article fetching, Lemmy posting)
  • mysql: Database storage for articles, logs, and application data

Both app containers use the same Docker image but with different commands (web or queue). Environment variables are passed from your .env file to configure database access and Lemmy integration.

Development Setup

For local development with Podman:

Prerequisites

  • Podman and podman-compose installed
  • Git

Quick Start

  1. Clone and start the development environment:

    git clone <repository-url>
    cd ffr
    ./docker/dev/podman/start-dev.sh
    
  2. Access the application:

Development Commands

Load Sail-compatible aliases:

source docker/dev/podman/podman-sail-alias.sh

Useful commands:

# Run tests
ffr-test

# Execute artisan commands
ffr-artisan migrate
ffr-artisan tinker

# View application logs
ffr-logs

# Open container shell
ffr-shell

# Stop environment
podman-compose -f docker/dev/podman/docker-compose.yml down

Run tests:

podman-compose -f docker/dev/podman/docker-compose.yml exec app bash -c "cd backend && XDEBUG_MODE=coverage php artisan test --coverage-html=coverage-report"

Development Features

  • Hot reload: Vite automatically reloads frontend changes
  • Database: Pre-configured MySQL with migrations and seeders
  • Redis: Configured for caching, sessions, and queues
  • Laravel Horizon: Available for queue monitoring
  • No configuration needed: Development environment uses preset configuration