Deploying FreshRSS
Introduction
FreshRSS is a powerful, self-hosted RSS feed aggregator that allows you to stay up-to-date with your favorite websites and blogs in one convenient location. Built with PHP and MySQL/PostgreSQL support, FreshRSS provides a modern, responsive web interface for managing and reading your RSS feeds efficiently.
Deploying FreshRSS on Klutch.sh gives you a reliable, scalable platform for your RSS aggregation needs. This guide will walk you through deploying FreshRSS using a Dockerfile, configuring persistent storage for your feeds and data, setting up environment variables, and implementing production best practices. Whether you’re setting up FreshRSS for personal use or deploying it for a team, this comprehensive tutorial covers everything you need to know.
Why Deploy FreshRSS on Klutch.sh?
- Automatic Dockerfile Detection: Klutch.sh automatically detects and uses your Dockerfile when present in the root directory
- Built with Nixpacks: Leverage Nixpacks for efficient builds with customizable runtime and buildtime environment variables
- Persistent Storage: Attach volumes to preserve your feed data, user preferences, and configurations across deployments
- Secure by Default: Use environment variables for sensitive data like database credentials and API keys
- Seamless GitHub Integration: Connect your GitHub repository for automated deployments
- HTTP/TCP Traffic Support: Configure traffic routing based on your application needs
Prerequisites
Before you begin, ensure you have:
- A Klutch.sh account (sign up here)
- A GitHub repository for your FreshRSS deployment
- Basic knowledge of Docker and RSS concepts
- (Optional) A database instance (MySQL or PostgreSQL) for production deployments
Project Structure
Create a repository with the following structure:
freshrss-docker/├── Dockerfile├── .dockerignore├── config/│ └── config.php (optional)└── README.mdThis minimal structure allows Klutch.sh to automatically detect and build your FreshRSS application using the Dockerfile.
Step 1: Create Your Dockerfile
FreshRSS provides official Docker images that make deployment straightforward. Create a Dockerfile in the root of your repository:
Basic Dockerfile
For a quick start with SQLite (suitable for personal use):
FROM freshrss/freshrss:latest
# Set the working directoryWORKDIR /var/www/FreshRSS
# Expose the default FreshRSS portEXPOSE 80
# The official image already includes the startup command# FreshRSS will be available on port 80Production Dockerfile with MySQL/PostgreSQL
For production deployments with external database support:
FROM freshrss/freshrss:latest
# Install additional dependencies if neededRUN apt-get update && apt-get install -y \ curl \ && rm -rf /var/lib/apt/lists/*
# Set the working directoryWORKDIR /var/www/FreshRSS
# Create a healthcheck to monitor application statusHEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \ CMD curl -f http://localhost:80/ || exit 1
# Expose the default FreshRSS portEXPOSE 80
# The entrypoint is inherited from the base imageAdvanced Dockerfile with Custom Configuration
For advanced setups requiring custom configurations:
FROM freshrss/freshrss:latest
# Set environment for ApacheENV APACHE_RUN_USER www-dataENV APACHE_RUN_GROUP www-dataENV APACHE_LOG_DIR /var/log/apache2
# Install additional tools for troubleshootingRUN apt-get update && apt-get install -y \ vim \ curl \ wget \ net-tools \ && rm -rf /var/lib/apt/lists/*
# Copy custom configuration if you have one# COPY config/config.php /var/www/FreshRSS/data/config.php
# Set proper permissionsRUN chown -R www-data:www-data /var/www/FreshRSS/data
WORKDIR /var/www/FreshRSS
# Health checkHEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \ CMD curl -f http://localhost:80/api/greader.php || exit 1
EXPOSE 80Step 2: Configure Environment Variables
FreshRSS requires several environment variables for optimal configuration. Set these in the Klutch.sh dashboard under your app’s environment settings.
Basic Configuration (SQLite)
For quick testing with SQLite:
# Application settingsCRON_MIN=*/15TZ=America/New_York
# Admin credentials (for initial setup)ADMIN_EMAIL=admin@example.comADMIN_PASSWORD=secure_password_hereADMIN_API_PASSWORD=api_password_hereProduction Configuration (MySQL)
For production deployments with MySQL:
# Database configurationDB_TYPE=mysqlDB_HOST=mysql.example.comDB_PORT=3306DB_NAME=freshrssDB_USER=freshrss_userDB_PASSWORD=your_secure_password
# Application settingsCRON_MIN=*/15TZ=America/New_YorkBASE_URL=https://example-app.klutch.sh
# Admin credentialsADMIN_EMAIL=admin@example.comADMIN_PASSWORD=secure_password_hereADMIN_API_PASSWORD=api_password_here
# Security settingsTRUSTED_PROXY=10.0.0.0/8Production Configuration (PostgreSQL)
For production deployments with PostgreSQL:
# Database configurationDB_TYPE=pgsqlDB_HOST=postgres.example.comDB_PORT=5432DB_NAME=freshrssDB_USER=freshrss_userDB_PASSWORD=your_secure_password
# Application settingsCRON_MIN=*/15TZ=America/New_YorkBASE_URL=https://example-app.klutch.sh
# Admin credentialsADMIN_EMAIL=admin@example.comADMIN_PASSWORD=secure_password_hereADMIN_API_PASSWORD=api_password_here
# Performance tuningPHP_MEMORY_LIMIT=256MMAX_EXECUTION_TIME=300Important Security Note: Never commit sensitive credentials to your repository. Always use Klutch.sh’s environment variables feature and mark them as secrets in the dashboard.
Step 3: Set Up Persistent Storage
FreshRSS requires persistent storage to maintain your feed data, user preferences, and configurations across deployments.
- Navigate to your app settings in the Klutch.sh dashboard at klutch.sh/app
- Go to the “Volumes” section
- Click “Add Volume” and configure:
- Mount Path:
/var/www/FreshRSS/data - Size: At least 5GB for basic usage, scale based on number of feeds
- Mount Path:
- Feed subscriptions and article data
- User accounts and preferences
- Configuration files
- Cache and temporary files
- SQLite database (if using SQLite)
- Mount Path:
/var/www/FreshRSS/extensions - Size: 1GB
- Regularly back up your
/var/www/FreshRSS/datavolume - Store backups in a separate location or cloud storage
- Test restoration procedures periodically
- Consider automated backup scripts for production environments
Configure Persistent Volumes
In the Klutch.sh dashboard, create and attach a persistent volume:
This volume will store:
Additional Volume for Extensions (Optional)
If you plan to use FreshRSS extensions:
Volume Backup Recommendations
Step 4: Deploy to Klutch.sh
Now that you have your Dockerfile and configurations ready, deploy FreshRSS to Klutch.sh.
- Log in to klutch.sh/app
- Click “Create New App” or navigate to your project
- Connect your GitHub repository
- Klutch.sh will automatically detect the Dockerfile in your repository root
- Traffic Type: Select HTTP (FreshRSS is a web application)
- Internal Port: Set to 80 (FreshRSS’s default port)
- Environment Variables: Add all the variables from Step 2
- Persistent Volumes: Attach the volume(s) configured in Step 3
- Review your configuration settings
- Click “Deploy” to start the build process
- Klutch.sh will:
- Clone your repository
- Detect the Dockerfile automatically
- Build the Docker image
- Deploy the container with your configurations
- Provision persistent storage
- Watch the build logs in real-time
- The deployment typically takes 2-5 minutes
- Once complete, you’ll receive a URL like
https://example-app.klutch.sh
Push Your Repository
# Initialize git repository (if not already done)git init
# Add your filesgit add Dockerfile .dockerignore README.md
# Commit your changesgit commit -m "Initial FreshRSS Dockerfile setup"
# Push to GitHubgit remote add origin https://github.com/your-username/freshrss-docker.gitgit branch -M maingit push -u origin mainCreate App in Klutch.sh Dashboard
Configure App Settings
Deploy the Application
Monitor Deployment
Step 5: Initial Setup and Configuration
After deployment, complete the FreshRSS setup.
- Language Selection: Choose your preferred language
- System Check: FreshRSS will verify all requirements are met
- Database Configuration:
- If using environment variables, these should auto-populate
- Verify database connection is successful
- Admin Account: Create your administrator account
- Installation: Complete the setup process
- Log in with your admin credentials
- Click “Subscription Management”
- Add RSS/Atom feeds by URL
- Organize feeds into categories
- Configure update intervals and display preferences
- Check the “System” → “About” page
- Look for the last update time
- Feeds should update based on your
CRON_MINsetting (default: every 15 minutes)
Access FreshRSS
Navigate to your deployed application URL (e.g., https://example-app.klutch.sh)
Complete Initial Setup
If this is your first deployment:
Add Your First Feeds
Configure Auto-Update (Important)
FreshRSS needs to periodically fetch new articles. The CRON_MIN environment variable handles this automatically in the official Docker image.
To verify it’s working:
Step 6: Database Setup (Production)
For production deployments, use an external database instead of SQLite.
MySQL Setup
Create a dedicated MySQL database and user:
CREATE DATABASE freshrss CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;CREATE USER 'freshrss_user'@'%' IDENTIFIED BY 'your_secure_password';GRANT ALL PRIVILEGES ON freshrss.* TO 'freshrss_user'@'%';FLUSH PRIVILEGES;Then set these environment variables in Klutch.sh:
DB_TYPE=mysqlDB_HOST=your-mysql-hostDB_NAME=freshrssDB_USER=freshrss_userDB_PASSWORD=your_secure_passwordPostgreSQL Setup
Create a dedicated PostgreSQL database and user:
CREATE DATABASE freshrss;CREATE USER freshrss_user WITH PASSWORD 'your_secure_password';GRANT ALL PRIVILEGES ON DATABASE freshrss TO freshrss_user;Then set these environment variables in Klutch.sh:
DB_TYPE=pgsqlDB_HOST=your-postgres-hostDB_NAME=freshrssDB_USER=freshrss_userDB_PASSWORD=your_secure_passwordDatabase Backup Strategy
Implement regular backups:
For MySQL:
# Use -p without password to prompt securely (recommended)mysqldump -h $DB_HOST -u $DB_USER -p $DB_NAME > freshrss-backup-$(date +%Y%m%d).sql
# Or use a credentials file for automationmysqldump --defaults-extra-file=/path/to/.my.cnf $DB_NAME > freshrss-backup-$(date +%Y%m%d).sqlFor PostgreSQL:
# Use PGPASSWORD environment variable or .pgpass file for secure authenticationpg_dump -h $DB_HOST -U $DB_USER $DB_NAME > freshrss-backup-$(date +%Y%m%d).sqlStore backups securely and test restoration procedures regularly.
Step 7: Advanced Configuration
Customize FreshRSS for optimal performance and features.
- Enable API in settings
- Generate an API password
- Use the API endpoint:
https://example-app.klutch.sh/api/greader.php - Compatible apps include: Reeder, FeedMe, News+, and many others
- Clone extensions to a local directory
- Add them to your repository in an
extensions/folder - Update your Dockerfile to copy extensions:
- Reddit Image
- YouTube
- Tumblr GDPR
- Fever API
- Add theme files to your repository
- Copy them in your Dockerfile:
API Access
FreshRSS provides a Google Reader-compatible API for mobile apps:
Extensions and Customization
Add FreshRSS extensions for additional functionality:
COPY extensions/ /var/www/FreshRSS/extensions/RUN chown -R www-data:www-data /var/www/FreshRSS/extensionsPopular extensions include:
Performance Tuning
Optimize FreshRSS for larger feed collections:
Environment Variables:
PHP_MEMORY_LIMIT=512MMAX_EXECUTION_TIME=300OPCACHE_ENABLE=1Dockerfile additions:
# Enable and configure OPcacheRUN echo "opcache.enable=1" >> /usr/local/etc/php/conf.d/opcache.ini && \ echo "opcache.memory_consumption=128" >> /usr/local/etc/php/conf.d/opcache.ini && \ echo "opcache.max_accelerated_files=10000" >> /usr/local/etc/php/conf.d/opcache.iniCustom Themes
Apply custom themes to personalize FreshRSS:
COPY themes/ /var/www/FreshRSS/data/themes/RUN chown -R www-data:www-data /var/www/FreshRSS/data/themesStep 8: Security Best Practices
Secure your FreshRSS deployment for production use.
- Strong Passwords: Use complex passwords for admin accounts
- HTTPS Only: Klutch.sh provides automatic HTTPS for all deployments
- Regular Updates: Keep FreshRSS updated by rebuilding with the latest image
- API Security: Use separate API passwords from your login password
- Secret Management: Store all sensitive data in Klutch.sh environment variables
- Network Security: Use private networking for database connections when possible
- Database Credentials: Rotate database passwords periodically
- Access Logs: Monitor access logs for suspicious activity
- Automated Backups: Schedule regular backups of volumes and database
- Off-site Storage: Store backups in a separate location from your deployment
- Test Restores: Regularly test your backup restoration process
- Version Control: Keep your Dockerfile and configurations in version control
Authentication and Access Control
Environment Security
Backup and Recovery
Security Headers
Add security headers via Apache configuration (create a custom config):
Header always set X-Frame-Options "SAMEORIGIN"Header always set X-Content-Type-Options "nosniff"Header always set X-XSS-Protection "1; mode=block"Header always set Referrer-Policy "strict-origin-when-cross-origin"Step 9: Monitoring and Maintenance
Keep your FreshRSS deployment healthy and performant.
- CPU Usage: Should remain under 50% for normal operations
- Memory Usage: Depends on feed count; typically 128-512MB
- Disk Usage: Monitor volume usage, especially with many feeds
- Network Traffic: Track bandwidth usage for feed fetching
- Check “System” → “About” for last update time
- Monitor feed update success rates
- Review error logs at
/var/www/FreshRSS/data/users/_/log.txt - Track database size growth
- Feed Cleanup: Remove inactive or broken feeds
- Article Purging: Configure retention policies for old articles
- Database Optimization: Run optimization queries monthly
- Log Rotation: Clean up old log files
- Extension Updates: Keep extensions updated
- Check cron job is running (
CRON_MINenvironment variable) - Verify network connectivity to feed sources
- Review logs for specific error messages
- Verify database credentials in environment variables
- Check network connectivity to database host
- Ensure database server is running and accessible
- Increase PHP memory limit
- Optimize database indexes
- Reduce feed update frequency
- Consider using PostgreSQL instead of SQLite
- Ensure proper ownership:
chown -R www-data:www-data /var/www/FreshRSS/data - Check volume mount paths match configuration
Health Monitoring
Monitor key metrics in Klutch.sh dashboard:
Application Monitoring
Within FreshRSS:
Maintenance Tasks
Regular maintenance ensures optimal performance:
Troubleshooting Common Issues
Feed Update Failures:
Database Connection Errors:
Performance Issues:
Volume Permission Issues:
Step 10: Scaling and Optimization
Grow your FreshRSS deployment as your needs expand.
- In Klutch.sh dashboard, adjust instance size
- Increase memory for larger feed collections
- Add more CPU for faster feed processing
- Expand volume size as article database grows
- Use PostgreSQL: Better performance than MySQL for read-heavy workloads
- Enable Connection Pooling: Reduce database connection overhead
- Index Optimization: Ensure proper indexes on frequently queried columns
- Query Caching: Enable database query caching
- Prioritize Feeds: Update important feeds more frequently
- Remove Dead Feeds: Regularly audit and remove inactive feeds
- Category Organization: Group related feeds for easier management
- Selective Updates: Update different feed groups at different intervals
- OPcache: Enable PHP OPcache for better performance
- Static Assets: FreshRSS automatically caches static assets
- Database Queries: Configure query result caching
- HTTP Caching: Set appropriate cache headers
Vertical Scaling
Increase resources for your application:
Database Optimization
For large deployments (100+ feeds):
Feed Management Strategy
Optimize feed collection:
Caching Strategy
Implement effective caching:
Using Nixpacks Customization
Since Klutch.sh uses Nixpacks for builds, you can customize the build and runtime behavior.
Custom Start Command
If you need to modify the default start command, use runtime environment variables:
# Set custom start command via NixpacksNIXPACKS_START_CMD="apache2-foreground"Custom Build Command
For build-time customizations:
# Custom build commandNIXPACKS_BUILD_CMD="apt-get update && apt-get install -y custom-package"PHP Configuration
Customize PHP settings via environment variables:
PHP_MEMORY_LIMIT=512MPHP_MAX_EXECUTION_TIME=300PHP_UPLOAD_MAX_FILESIZE=50MPHP_POST_MAX_SIZE=50MMigrating from Existing FreshRSS Installation
If you’re migrating from an existing FreshRSS installation:
- Navigate to “System” → “Data management”
- Export your OPML file (contains feed subscriptions)
- Export starred articles if needed
- Backup your database
- Deploy FreshRSS on Klutch.sh following this guide
- Complete initial setup
- Import OPML file via “Subscription management” → “Import/Export”
- For database migration:
- Export from old database:
mysqldump ... - Import to new database:
mysql ... < backup.sql
- Export from old database:
- Copy custom extensions or themes if used
- Check all feeds are present and updating
- Verify user accounts and preferences
- Test starred articles and read/unread status
- Validate custom categories and filters
Export Your Data
From your existing installation:
Import to Klutch.sh Deployment
Verify Migration
Local Development with Docker Compose
For local testing before deploying to Klutch.sh, use Docker Compose:
version: '3.8'
services: freshrss: build: . ports: - "8080:80" environment: - CRON_MIN=*/15 - TZ=America/New_York - DB_TYPE=mysql - DB_HOST=db - DB_NAME=freshrss - DB_USER=freshrss - DB_PASSWORD=<your-secure-db-password> volumes: - freshrss-data:/var/www/FreshRSS/data depends_on: - db
db: image: mysql:8 environment: - MYSQL_ROOT_PASSWORD=<your-secure-root-password> - MYSQL_DATABASE=freshrss - MYSQL_USER=freshrss - MYSQL_PASSWORD=<your-secure-db-password> volumes: - mysql-data:/var/lib/mysql
volumes: freshrss-data: mysql-data:Run locally with:
docker-compose up -dAccess at http://localhost:8080
Note: Docker Compose is not supported by Klutch.sh for deployment. Use this only for local development and testing.
Troubleshooting Guide
Common issues and solutions:
- Ensure Dockerfile is in the repository root
- Check filename is exactly
Dockerfile(case-sensitive) - Verify file is committed and pushed to GitHub
- Verify internal port is set to 80 in Klutch.sh dashboard
- Ensure traffic type is set to HTTP
- Check container logs for binding errors
- Verify environment variables are set correctly
- Check database host is accessible from Klutch.sh
- Ensure database user has proper permissions
- Test connection credentials separately
- Verify volume mount path is
/var/www/FreshRSS/data - Check volume is attached in Klutch.sh dashboard
- Ensure proper permissions on mounted directory
- Check
CRON_MINenvironment variable is set - Verify no errors in FreshRSS logs
- Test manual feed update in the UI
- Ensure server can access external feed URLs
- Increase PHP memory limit
- Switch from SQLite to MySQL/PostgreSQL
- Enable OPcache in PHP configuration
- Reduce number of feeds or increase update interval
- Scale up instance size in Klutch.sh
Dockerfile Not Detected
Problem: Klutch.sh doesn’t detect your Dockerfile
Solution:
Port Configuration Issues
Problem: Application not accessible after deployment
Solution:
Database Connection Failures
Problem: Cannot connect to database
Solution:
Volume Mount Issues
Problem: Data not persisting between deployments
Solution:
Feed Update Problems
Problem: Feeds not updating automatically
Solution:
Performance Issues
Problem: Slow application performance
Solution:
Example Production Deployment
Complete example for a production FreshRSS deployment:
Dockerfile:
FROM freshrss/freshrss:1.23.1
RUN apt-get update && apt-get install -y \ curl \ vim \ && rm -rf /var/lib/apt/lists/*
WORKDIR /var/www/FreshRSS
RUN echo "opcache.enable=1" >> /usr/local/etc/php/conf.d/opcache.ini && \ echo "opcache.memory_consumption=256" >> /usr/local/etc/php/conf.d/opcache.ini
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \ CMD curl -f http://localhost:80/api/greader.php || exit 1
EXPOSE 80Environment Variables:
DB_TYPE=mysqlDB_HOST=mysql.production.klutch.shDB_PORT=3306DB_NAME=freshrss_prodDB_USER=freshrss_userDB_PASSWORD=<secret>
CRON_MIN=*/10TZ=America/New_YorkBASE_URL=https://rss.example.com
ADMIN_EMAIL=admin@example.comADMIN_PASSWORD=<secret>ADMIN_API_PASSWORD=<secret>
PHP_MEMORY_LIMIT=512MMAX_EXECUTION_TIME=300
TRUSTED_PROXY=10.0.0.0/8Volume Configuration:
- Mount Path:
/var/www/FreshRSS/data - Size: 20GB
Traffic Configuration:
- Type: HTTP
- Internal Port: 80
Additional Resources
- FreshRSS GitHub Repository
- FreshRSS Official Documentation
- FreshRSS Docker Hub
- Klutch.sh Quick Start Guide
- Klutch.sh Volumes Guide
- Klutch.sh Apps Documentation
- Klutch.sh Custom Domains
Conclusion
Deploying FreshRSS on Klutch.sh with a Dockerfile provides a robust, scalable solution for RSS feed aggregation. By following this guide, you’ve learned how to:
- Create an optimized Dockerfile for FreshRSS
- Configure environment variables and secrets securely
- Set up persistent storage for long-term data retention
- Deploy using Klutch.sh’s automatic Dockerfile detection
- Implement security best practices
- Monitor and maintain your deployment
- Troubleshoot common issues
- Scale your deployment as needs grow
FreshRSS on Klutch.sh offers the perfect balance of self-hosting control with the convenience of managed infrastructure. Your RSS feeds are now centralized, secure, and accessible from anywhere with automatic HTTPS, persistent storage, and easy scaling capabilities.
For additional help or questions, refer to the FreshRSS community resources and Klutch.sh documentation linked above.