نصب FreshRSS روی VPS اوبونتو با Apache و PHP
FreshRSS 1.29.1 را روی Ubuntu 24.04 نصب کنید؛ از release tarball و virtual host تا cron برای refresh و تنظیم API اپلیکیشن موبایل با Apache، PHP و MariaDB.
آنچه میسازید
یک RSS reader خودمیزبان، feed readerای است که روی سروری متعلق به شما اجرا میشود؛ بنابراین هیچکس نمیتواند آن را خاموش کند یا محتوایی را که به شما نمایش میدهد تغییر دهد. این راهنما FreshRSS را روی یک Ubuntu 24.04 VPS نصب میکند: Apache در بخش front، PHP در بخش back، MariaDB برای ذخیرهسازی، و یک cron job برای دریافت مقالههای جدید. RSS (really simple syndication) قالب فایلی است که یک سایت منتشر میکند تا نرمافزار بتواند مقالههای آن را بخواند. FreshRSS برنامه PHP است که این فایلها را جمعآوری میکند، مقالهها را نگه میدارد و یک رابط وب بههمراه API (application programming interface) ارائه میدهد که برنامههای تلفن همراه با آن ارتباط برقرار میکنند.
خود فرایند نصب کوتاه است: یک release را از حالت فشرده خارج کنید، یک database بسازید، یک virtual host بنویسید و یک command line installer را اجرا کنید. بیشتر خطاها در مراحل بعدی رخ میدهند؛ یعنی در refresh job، تنظیم encoded slashها برای mobile API و مالکیت فایلها.
FreshRSS 1.29.1 تا July 2026، release فعلی است و به PHP 8.1 یا جدیدتر نیاز دارد. Ubuntu 24.04 همراه با PHP 8.3 عرضه میشود؛ بنابراین packageهای توزیع کافی هستند و به third-party PHP repository نیاز ندارید.
کار را با یک پشته LAMP سالم آغاز کنید
FreshRSS یک برنامه معمولی PHP است؛ بنابراین مانند هر برنامه دیگری به همان زیرساخت پایه نیاز دارد. اگر هنوز این زیرساخت را آماده نکردهاید، ابتدا راهنمای راهاندازی پشته LAMP در Ubuntu 24.04 را دنبال کنید و سپس به این بخش بازگردید. خلاصه:
sudo apt update
sudo apt install -y apache2 mariadb-server php libapache2-mod-php
sudo systemctl enable --now apache2 mariadbsystemctl status apache2 باید active (running) را گزارش کند. اگر Apache راهاندازی نشود، علت معمول این است که فرایند دیگری از قبل پورت 80 را در اختیار گرفته است و sudo ss -ltnp | grep :80 نام آن را نمایش میدهد.
افزونههای PHP موردنیاز FreshRSS
FreshRSS افزونههای libxml، cURL، JSON، PDO_MySQL، PCRE و ctype را الزامی میداند. همچنین به mbstring، iconv، Zlib و ZipArchive نیاز دارد و در سیستمهای 32 بیتی به GMP نیز نیازمند است. در Ubuntu، این افزونهها بهصورت بستههای توزیع ارائه میشوند:
sudo apt install -y php-curl php-mbstring php-xml php-zip php-mysql php-intl php-gmp
sudo systemctl restart apache2با php -m بررسی کنید که PHP واقعاً چه افزونههایی را بارگذاری کرده است. نبودن یک افزونه مانع آغاز نصبکننده نمیشود. این مشکل در صفحه بررسی الزامات، با یک خط قرمز که نام افزونه را نشان میدهد، باعث توقف نصب میشود. کشف مشکل در آن مرحله گیجکننده است؛ بنابراین اکنون آن را بررسی کنید. راهاندازی مجدد Apache اهمیت دارد، زیرا libapache2-mod-php، PHP را درون فرایند Apache نگه میدارد. در نتیجه، وبسرور تا زمان راهاندازی مجدد، افزونهای را که بهتازگی نصب شده است نمیبیند.
دانلود نسخه انتشار
FreshRSS را خارج از web root پیشفرض نصب کنید و Apache را به آن هدایت کنید. جدا نگهداشتن دایرکتوری برنامه از document root باعث میشود فقط پوشه عمومی از طریق HTTP قابل دسترسی باشد.
cd /tmp
curl -fsSLO https://github.com/FreshRSS/FreshRSS/archive/refs/tags/1.29.1.tar.gz
tar xzf 1.29.1.tar.gz
sudo mv FreshRSS-1.29.1 /srv/freshrssاکنون نوبت تنظیم مجوزها است؛ مستندات FreshRSS در این مورد الزامات مشخصی دارد: کاربر web server مالک درخت دایرکتوری باشد، گروه بتواند همه فایلها را بخواند، و گروه بتواند در ./data/ بنویسد.
sudo chown -R www-data:www-data /srv/freshrss
sudo chmod -R g+r /srv/freshrss
sudo chmod -R g+w /srv/freshrss/dataاگر این مرحله را رد کنید، installer هنگام نوشتن پیکربندی با خطا مواجه میشود؛ زیرا PHP با کاربر www-data اجرا میشود و www-data نمیتواند در دایرکتوری متعلق به root بنویسد.
ایجاد پایگاهداده
FreshRSS از SQLite، MariaDB، MySQL و PostgreSQL پشتیبانی میکند. SQLite به هیچ راهاندازیای نیاز ندارد و برای یک نفر با چند صد خوراک مناسب است. هنگامی که چند نفر از یک نمونه استفاده میکنند، MariaDB انتخاب بهتری است؛ زیرا نوشتن همزمان توسط کار بهروزرسانی و رابط وب دیگر بر سر یک قفل فایل واحد رقابت نمیکند.
sudo mariadb -e "CREATE DATABASE freshrss CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
sudo mariadb -e "CREATE USER 'freshrss'@'localhost' IDENTIFIED BY 'ReplaceThisPassword';"
sudo mariadb -e "GRANT ALL PRIVILEGES ON freshrss.* TO 'freshrss'@'localhost';"
sudo mariadb -e "FLUSH PRIVILEGES;"از utf8mb4 استفاده کنید، نه utf8. خوراکها شامل emoji و خطهای نوشتاری غیرلاتین هستند و کدگذاری قدیمی سهبایتی utf8 عنوان مقاله را در نخستین نویسه چهاربایتی کوتاه میکند.
میزبان مجازی Apache
پوشه عمومی p/ است، نه ریشه درخت پوشهها. همه موارد دیگر، از جمله فایل پیکربندی حاوی گذرواژه پایگاه داده، بالاتر از ریشه اسناد قرار دارند؛ بنابراین Apache هرگز آنها را ارائه نمیکند.
<VirtualHost *:80>
ServerName rss.example.com
DocumentRoot /srv/freshrss/p/
<Directory /srv/freshrss/p>
AllowOverride AuthConfig FileInfo Indexes Limit
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/freshrss_error.log
CustomLog ${APACHE_LOG_DIR}/freshrss_access.log combined
AllowEncodedSlashes On
</VirtualHost>آن را با نام /etc/apache2/sites-available/freshrss.conf ذخیره و فعال کنید:
sudo a2enmod rewrite
sudo a2ensite freshrss
sudo a2dissite 000-default
sudo apache2ctl configtest
sudo systemctl reload apache2configtest باید Syntax OK را چاپ کند. AllowEncodedSlashes On اختیاری به نظر میرسد، اما اختیاری نیست: Google Reader API شناسههای feed حاوی %2F را ارسال میکند و بدون این directive، Apache آنها را رد میکند. در نتیجه، همگامسازی برنامههای موبایل انجام نمیشود، در حالی که رابط وب کاملاً کار میکند.
پیش از ورود، HTTPS را فعال کنید
قرار است گذرواژهای را در این سایت وارد کنید؛ بنابراین ابتدا یک گواهی دریافت کنید. یک رکورد A را به سرور اشاره دهید، سپس مراحل راهاندازی Certbot برای Apache در Ubuntu را دنبال کنید و sudo certbot --apache -d rss.example.com را اجرا کنید. Certbot پیکربندی میزبان مجازی برای پورت 443 را بازنویسی میکند و تغییر مسیر را اضافه میکند. نتیجه را با curl -I https://rss.example.com/ بررسی کنید؛ این فرمان باید یک 200 یا تغییر مسیر به صفحه ورود برگرداند.
اجرای نصبکننده از خط فرمان
FreshRSS یک نصبکننده مرورگری دارد، اما نسخه خط فرمان تکرارپذیر است و دقیقاً انتخابهای شما را ثبت میکند.
sudo -u www-data php /srv/freshrss/cli/do-install.php \
--default-user admin --auth-type form --environment production \
--base-url https://rss.example.com --language en --api-enabled \
--db-type mysql --db-host localhost --db-user freshrss \
--db-password 'ReplaceThisPassword' --db-base freshrss
sudo -u www-data php /srv/freshrss/cli/create-user.php \
--user admin --password 'a-long-passphrase' --api-password 'a-different-passphrase'هر دو مورد را با www-data اجرا کنید. اجرای آنها با root باعث میشود فایلهای پیکربندی متعلق به root ایجاد شوند و رابط وب بعداً نتواند هیچ تنظیمی را ذخیره کند. --environment production نیز اهمیت دارد، زیرا تنظیم توسعه، اعلانهای PHP را در صفحه نمایش میدهد.
https://rss.example.com/ را بارگذاری کنید و با admin وارد شوید.
چرا فیدها بهصورت خودکار تازه نمیشوند
تا زمانی که به سیستم دستور ندهید، هیچ فرایندی فیدهای شما را بررسی نمیکند. FreshRSS زمانی بهروزرسانی میشود که مرورگر روی آن باز باشد؛ بنابراین نمونهای که روزی دو بار به آن سر میزنید، مقالههایی را نمایش میدهد که 12 ساعت از انتشارشان گذشته است. راهحل، اسکریپتی است که پروژه برای این کار ارائه میکند، app/actualize_script.php، و باید آن را از طریق cron اجرا کنید.
sudo crontab -u www-data -eیک خط اضافه کنید:
*/20 * * * * php /srv/freshrss/app/actualize_script.php > /tmp/FreshRSS.log 2>&120 دقیقه حداقل زمان منطقی است، زیرا اسکریپت اجازه نمیدهد هیچ فیدی بیش از یک بار در هر 20 دقیقه تازهسازی شود؛ بنابراین زمانبندی کوتاهتر فقط CPU را مصرف میکند. ابتدا آن را بهصورت دستی یک بار اجرا کنید:
sudo -u www-data php /srv/freshrss/app/actualize_script.phpخروجی سالم، نام هر فیدی را که دریافت کرده است نمایش میدهد و بدون خطای PHP پایان مییابد. اگر هیچ خروجیای نمایش داده نشد، کاربر cron اشتباه است و خطای مجوز برای data/ نشان میدهد که مرحله chmod -R g+w رد شده است.
اولین فیدهای خود را اضافه کنید
از دکمه plus در بالای سمت چپ رابط کاربری استفاده کنید، نشانی یک سایت را جایگذاری کنید تا FreshRSS پیوند فید را برای شما پیدا کند. بیشتر سایتها حتی اگر آن را تبلیغ نکنند، همچنان یک فید منتشر میکنند که معمولاً در /feed، /rss یا /atom.xml قرار دارد. دستهها مانند پوشهها هستند و انتقال یک فید بین آنها با کشیدن انجام میشود.
اگر از یک خبرخوان دیگر استفاده میکنید، یک فایل OPML از آن خروجی بگیرید و آن را از صفحه مدیریت اشتراکها وارد کنید. OPML (outline processor markup language) قالب استاندارد فهرست فید است و همه خبرخوانهای قابلاعتماد از آن پشتیبانی میکنند. اولین نوسازی پس از یک import بزرگ کند است، زیرا هر فید یک بار دریافت میشود؛ بنابراین پیش از ارزیابی سرعت، به اولین اجرای cron زمان کافی بدهید.
آن را در تلفن همراه خود بخوانید
FreshRSS از Google Reader API پشتیبانی میکند و تقریباً همه برنامههای RSS از آن پشتیبانی میکنند. دو شرط باید برقرار باشد. در تنظیمات احراز هویت، گزینه «Allow API access» باید فعال باشد؛ پرچم --api-enabled که در بالا تنظیم شد، این کار را انجام داده است. در پروفایل شما، فیلد گذرواژه API باید مقداری داشته باشد. این گذرواژه عمداً از گذرواژه ورود جداست، زیرا احتمال گمشدن تلفن همراه بیشتر است.
به https://rss.example.com/api/ بروید و گزینه «Check full server configuration» را انتخاب کنید. یک پیکربندی سالم، PASS را برمیگرداند. این بخش تقریباً همیشه به دلیل نبود خط AllowEncodedSlashes On با شکست مواجه میشود. در برنامه، نشانی سرور را https://rss.example.com/api/greader.php، نام کاربری را کاربر FreshRSS خود و گذرواژه API را بهعنوان گذرواژه وارد کنید.
جایگزین Docker
اگر ترجیح میدهید PHP و Apache را بهصورت دستی نگهداری نکنید، پروژه یک image رسمی freshrss/freshrss منتشر میکند و یک فایل compose، application و database آن را در کنار هم در اختیار شما قرار میدهد. پیامد معمول این انتخاب چنین است: اجزای کمتری روی host دارید، اما هنگام بروز مشکل باید یک لایه اضافی را اشکالزدایی کنید و برای TLS (امنیت لایه انتقال) همچنان به یک reverse proxy نیاز دارید. اگر این روش برای شما مناسبتر است، مبانی Docker Compose برای یک VPS قالب فایل را توضیح میدهد و خط cron به docker exec --user www-data freshrss php ./app/actualize_script.php تبدیل میشود.
پشتیبانگیری و ارتقا
دو مورد وضعیت شما را حفظ میکنند: پایگاه داده و /srv/freshrss/data/. مورد اول را با sudo mysqldump freshrss > freshrss.sql تخلیه کنید، مورد دوم را کپی کنید و هر دو را در مکانی غیر از این سرور نگه دارید. فهرست اشتراکهای شما نیز هر چند وقت یکبار ارزش خروجی OPML را دارد، زیرا این فایل میتواند تنظیمات مطالعه شما را در هر نرمافزار RSS بازسازی کند.
ارتقا شامل بازکردن یک release جدیدتر روی همان directory و اجرای دوباره فرمانهای مالکیت است. FreshRSS مهاجرتهای پایگاه داده خود را در بارگذاری بعدی صفحه اعمال میکند. ابتدا پشتیبان بگیرید، زیرا مهاجرت ناموفق روی پایگاه دادهای که امکان بازیابی آن را ندارید، وضعیتی غیرقابلبازگشت ایجاد میکند. اجرای یک reader سرویس کمخطری است و اگر در حال بررسی فهرستی از موارد مناسب برای self-hosting هستید، گزینه مناسبی برای شروع به شمار میرود.
FAQ
چرا feedهای من فقط هنگام باز کردن FreshRSS بهروزرسانی میشوند؟
زیرا تا زمانی که زمانبندی ایجاد نکنید، هیچ schedulerای وجود ندارد. FreshRSS feedها را تا زمانی که یک نشست مرورگر باز باشد تازهسازی میکند و پس از بسته شدن تب، کاری انجام نمیدهد. خط cron را برای فراخوانی app/actualize_script.php بهعنوان کاربر www-data اضافه کنید، سپس اسکریپت را یکبار بهصورت دستی اجرا و خروجی آن را بررسی کنید. سکوت خروجی معمولاً به این معناست که cron اسکریپت را با کاربر نادرست اجرا میکند؛ در نتیجه PHP نمیتواند در data/ بنویسد.
چرا برنامه موبایل من نمیتواند متصل شود، اما وبسایت کار میکند؟
Google Reader API اسلشهای رمزگذاریشده (%2F) را در مسیرهای درخواست قرار میدهد و Apache بهصورت پیشفرض آنها را رد میکند. AllowEncodedSlashes On را داخل virtual host اضافه و Apache را reload کنید. برای تأیید اصلاح، https://rss.example.com/api/ را باز کنید و «Check full server configuration» را اجرا کنید؛ این بررسی باید PASS را گزارش کند. همچنین بررسی کنید که گذرواژه API در پروفایل شما تنظیم شده باشد، زیرا این گذرواژه جدا از گذرواژه ورود شماست.
آیا باید از SQLite استفاده کنم یا MariaDB؟
برای یک کاربر، SQLite مناسب است؛ زیرا نصب دیگری لازم ندارد و نیازی به مدیریت گذرواژه نیست. زمانی که بیش از یک نفر روی instance مطالعه میکند، یا تعداد feedها از چند صد مورد بیشتر میشود، از MariaDB استفاده کنید؛ زیرا job تازهسازی و رابط وب همزمان مینویسند و قفل یک فایل واحد به محدودیت تبدیل میشود. جابهجایی بین این دو بعداً از طریق commandهای export و import ممکن است؛ بنابراین این تصمیم دائمی نیست.
نصبکننده هنگام نوشتن پیکربندی خود شکست میخورد. مشکل چیست؟
PHP در Apache با کاربر www-data اجرا میشود و این کاربر نمیتواند در دایرکتوریای که مالک آن root است بنویسد. sudo chown -R www-data:www-data /srv/freshrss و sudo chmod -R g+w /srv/freshrss/data را دوباره اجرا کنید، سپس نصبکننده را مجدداً شروع کنید. اگر command نصب خط فرمان را قبلاً با root اجرا کردهاید، فایلهایی را که در data/ ایجاد کرده است حذف کنید و سپس دوباره تلاش کنید؛ زیرا مشکل واقعی، مالکیت آن فایلهاست.
یک RSS reader خودمیزبان به چه مقدار منابع سرور نیاز دارد؟
مقدار بسیار کمی. اجرای چند صد feed روی یک plan کوچک مناسب است، زیرا بار کاری شامل burstهای کوتاه دریافت HTTP هر 20 دقیقه است و پس از حذف مقالههای قدیمی، اندازه پایگاه داده کوچک باقی میماند. مصرف دیسک با میزان نگهداری مقالهها افزایش مییابد؛ بنابراین بهجای نگهداشتن همهچیز برای همیشه، در تنظیمات بایگانی یک خطمشی purge مقاله تعیین کنید.