Note: While MediaRSS is primarily designed and tested for audio files (MP3, M4A, M4B, etc.), video files should also work. However, video support is not the primary focus and may have limitations (especially with regard to performance) with certain formats.
- Docker
- A server or machine to host the application
- Basic understanding of Docker volumes for data persistence
- Media files organized in one or more directories on your host machine
- (Recommended) A domain name and Cloudflare account for secure remote access (see Securing the Admin Dashboard)
If you're running this on a Synology NAS, follow these specific instructions:
-
Install Docker from the Synology Package Center if you haven't already.
-
Create a shared folder for the database files:
- Open Control Panel → Shared Folder
- Create a new shared folder named
docker-data(or your preferred name) - Inside this folder, create a directory called
mediarss
-
Note your media locations:
- Synology typically stores media files in
/volume1/[shared-folder-name] - You can mount any number of media directories from your Synology
- Synology typically stores media files in
-
Open Docker in Synology DSM:
- Go to "Registry" and search for the mediarss image
- Download the image
- Go to "Container" and launch using the image
-
When setting up the container in the Synology Docker UI:
-
In the "Advanced Settings" → "Volume" tab:
- Add a volume mount for the database:
- Mount path:
/data - Local path:
/volume1/docker-data/mediarss
- Mount path:
- Add a volume mount for artwork (to persist uploaded feed images):
- Mount path:
/app/data/artwork - Local path:
/volume1/docker-data/mediarss/artwork
- Mount path:
- Add your media volume mounts (add as many as you need):
- Mount path:
/media/[your-name](e.g.,/media/shows,/media/personal, etc.) - Local path:
/volume1/[your-folder] - Check "Read-only" if you only need to serve existing files
- Uncheck "Read-only" if you want to upload media via the admin dashboard
- Mount path:
- Add a volume mount for the database:
-
In the "Port Settings" tab:
- Local Port: 22050 (or your preferred port)
- Container Port: 22050 (or whatever you set PORT to in the env settings)
-
In the "Environment" tab:
- Add the standard environment variables as needed
- For multiple media paths, specify them in MEDIA_PATHS:
- Variable: MEDIA_PATHS
- Value:
shows:/media/shows,personal:/media/personal - Format:
name:path,name:path(comma-separated, each with a name and path)
-
The rest of the standard instructions apply for managing the container.
For the easiest setup, use the provided NAS setup script:
- Copy
scripts/nas-setup.shto your NAS - Edit the configuration section at the top of the script
- Run it:
chmod +x nas-setup.sh
./nas-setup.shThe script will pull the latest image, set up the container with your media directories, and configure automatic restarts.
- Pull the Docker image:
docker pull [your-image-name]- Create directories for persistent storage and ensure your media directories exist:
# Create directories for database and artwork storage
mkdir -p /path/to/your/data
mkdir -p /path/to/your/data/artwork
# Your media directories should already exist- Run the container:
docker run -d \
--name mediarss \
-p 22050:22050 \
-v /path/to/your/data:/data \
-v /path/to/your/data/artwork:/app/data/artwork \
-v /path/to/audiobooks:/media/audiobooks:ro \
-v /path/to/audio-series:/media/audio-series:ro \
-e MEDIA_PATHS=audiobooks:/media/audiobooks,audio-series:/media/audio-series \
[your-image-name]Note on volume permissions:
- The
:roflag makes media volumes read-only, which is recommended for security if you only need to serve existing files. - To enable media uploads, mount volumes read/write by removing the
:roflag:This allows uploading new media files through the admin dashboard.-v /path/to/audiobooks:/media/audiobooks \
The application requires these volume mounts:
-
Database Volume (
/data):- Purpose: Stores SQLite databases
- Mount point:
/data - Example:
-v /path/to/your/data:/data
-
Artwork Volume (
/app/data/artwork):- Purpose: Stores uploaded feed artwork images
- Mount point:
/app/data/artwork - Example:
-v /path/to/your/data/artwork:/app/data/artwork - Important: Without this mount, uploaded artwork will be lost on container restart
-
Media Volumes (any number allowed):
- Purpose: Access to your audio files
- Mount point pattern:
/media/[your-name] - Examples:
-v /path/to/audiobooks:/media/audiobooks:ro-v /path/to/audio-series:/media/audio-series:ro
- Mount read-only (
:ro) if you only need to serve existing files - For media uploads: Mount read/write (without
:ro) to enable uploading files via the admin dashboard - Name the mount points anything that makes sense for your use case
You can organize your media directories however you prefer. Here's an example structure for audiobooks and audio series:
/media/audiobooks/
├── fiction/
│ ├── Harry Potter Series/
│ └── Lord of the Rings/
└── non-fiction/
├── Atomic Habits/
└── Deep Work/
/media/audio-series/
├── podcasts/
│ ├── show1/
│ └── show2/
└── courses/
├── course1/
└── course2/
The following environment variables can be configured:
PORT: Server port (default: 22050)NODE_ENV: Environment mode (production,development, ortest)DATABASE_PATH: Path to the main SQLite database (default: ./data/sqlite.db)CACHE_DATABASE_PATH: Path to the cache SQLite database (default: ./data/cache.db)MEDIA_PATHS: Named media roots in formatname:path,name:path- Example:
shows:/media/shows,personal:/media/personal,other:/media/other - Each media root has a name (used in URLs) and a path (filesystem location)
- Names must be unique - duplicate names are not allowed
- Names should be URL-safe (alphanumeric, hyphens, underscores)
- Example:
MediaRSS has two types of routes:
- Public routes (
/feed/*,/media/*,/art/*) - These are accessed by RSS readers and podcast apps. They use secret tokens in URLs for access control. - Admin routes (
/) - The dashboard for managing feeds. This should be protected.
Since RSS readers need direct access to feed URLs without authentication prompts, we recommend using Cloudflare Tunnel to secure the admin dashboard rather than app-level authentication.
- Free HTTPS - Automatic SSL certificates, no configuration needed
- No port forwarding - Outbound-only connection, your router stays locked down
- Hidden IP - Your home IP address is never exposed
- Access policies - Add authentication at the edge (email OTP, SSO, etc.)
- Works with any DNS - You don't need to move your domain to Cloudflare
-
Create a free Cloudflare account and add your domain (you can use the free plan).
-
Create a tunnel in the Zero Trust dashboard:
- Go to Networks → Tunnels → Create a tunnel
- Name it (e.g., "mediarss")
- Choose Docker as the connector
- Copy the tunnel token
-
Run cloudflared alongside MediaRSS on your NAS/server:
docker run -d \ --name cloudflared \ --restart unless-stopped \ --network host \ cloudflare/cloudflared:latest \ tunnel run --token YOUR_TUNNEL_TOKEN
Note: The
--network hostflag is required so that cloudflared can reach MediaRSS vialocalhost. Without it,localhostwould refer to the cloudflared container itself, not your NAS. -
Configure the public hostname in the tunnel settings:
- Hostname:
media.yourdomain.com(a domain name you control) - Service:
http://localhost:22050(or your MediaRSS port)
- Hostname:
-
Add an Access policy to protect the admin dashboard:
- Go to Access → Applications → Add an application
- Choose "Self-hosted"
- Set the domain to
media.yourdomain.com - Set the path to
/admin(just the admin pages) - Add an authentication method (email OTP is easiest)
- Important: Don't protect
/feed/*,/media/*, or/art/*paths
If your domain's DNS is managed elsewhere (not Cloudflare), you can still use Cloudflare Tunnel with a CNAME record:
- Complete steps 1-4 above
- Find your tunnel's hostname in the Cloudflare dashboard - it looks like:
a1b2c3d4-e5f6-7890-abcd-ef1234567890.cfargotunnel.com - At your DNS provider, create a CNAME record:
media.yourdomain.com CNAME <tunnel-uuid>.cfargotunnel.com
Note: This only works for subdomains (e.g., media.yourdomain.com), not the
root domain.
If you only access MediaRSS from your local network and don't need remote access, you can skip Cloudflare Tunnel entirely. The token-based URLs for feeds provide sufficient security for trusted networks.
The application stores persistent data in two locations:
Databases (in /data):
- Main database:
/data/sqlite.db - Cache database:
/data/cache.db
Uploaded Artwork (in /app/data/artwork):
- Feed cover images uploaded through the admin dashboard
To ensure your data persists between container restarts and updates, you
must mount volumes to both /data and /app/data/artwork as shown in the
run command above.
To backup your data, simply copy the files from your mounted data directory. For example:
# Stop the container before backup
docker stop mediarss
# Backup the databases and artwork
cp /path/to/your/data/sqlite.db /path/to/backup/sqlite.db
cp /path/to/your/data/cache.db /path/to/backup/cache.db
cp -r /path/to/your/data/artwork /path/to/backup/artwork
# Restart the container
docker start mediarssTo restore from backup:
# Stop the container
docker stop mediarss
# Restore the databases and artwork
cp /path/to/backup/sqlite.db /path/to/your/data/sqlite.db
cp /path/to/backup/cache.db /path/to/your/data/cache.db
cp -r /path/to/backup/artwork /path/to/your/data/artwork
# Restart the container
docker start mediarssTo upgrade to a new version:
# Pull the new image
docker pull [your-image-name]
# Stop the current container
docker stop mediarss
# Remove the old container
docker rm mediarss
# Run the new container (using the same data directory and media mount)
# Note: Remove :ro from media volumes if you need to upload media files
docker run -d \
--name mediarss \
-p 22050:22050 \
-v /path/to/your/data:/data \
-v /path/to/your/data/artwork:/app/data/artwork \
-v /path/to/audiobooks:/media/audiobooks:ro \
-v /path/to/audio-series:/media/audio-series:ro \
-e MEDIA_PATHS=audiobooks:/media/audiobooks,audio-series:/media/audio-series \
[your-image-name]Your data will be preserved as long as you use the same volume mount points.
Audiobookshelf is a fully featured audio media server. It doesn't support private RSS feeds and it's a little too much for what I want, so I built my own thing. But you might like it.





