ثبّت FreshRSS على VPS بنظام Ubuntu 24.04
ثبّت FreshRSS 1.30.1 على VPS يعمل بـ Ubuntu 24.04 باستخدام Apache وPHP 8.3 وMariaDB، واضبط cron وتعرّف إلى مشكلة الشرطات المائلة في API.
ما الذي ستبنيه
قارئ RSS مستضاف ذاتياً هو قارئ خلاصات يعمل على خادم تملكه، لذلك لا يستطيع أي شخص إيقافه أو تغيير المحتوى الذي يعرضه لك. يضع هذا الدليل FreshRSS على VPS يعمل بنظام Ubuntu 24.04: يتولى Apache الواجهة الأمامية، ويعمل PHP خلفه، وتُستخدم MariaDB لتخزين البيانات، وتُشغَّل مهمة cron واحدة لجلب المقالات الجديدة. RSS، أي Really Simple Syndication، هو تنسيق ملف ينشره الموقع كي تتمكن البرامج من قراءة مقالاته. أما FreshRSS فهو تطبيق PHP الذي يجمع هذه الملفات، ويحفظ المقالات، ويوفر واجهة ويب إضافة إلى API، أي واجهة برمجة تطبيقات، تتصل بها تطبيقات الهاتف.
عملية التثبيت نفسها بسيطة: فك حزمة الإصدار، وإنشاء قاعدة بيانات، وكتابة virtual host واحد، وتشغيل برنامج التثبيت عبر سطر الأوامر، ثم إنشاء الحساب باستخدام cli/create-user.php. معظم العمل التالي يتعلق بالأخطاء الشائعة بعد التثبيت، وهي مهمة التحديث، والشرطات المائلة المشفّرة في API الخاص بتطبيقات الهاتف، وملكية الملفات.
الإصدار FreshRSS 1.30.4، الذي صدر في October 21, 2026، هو الإصدار الحالي في October 29, 2026، ويحتاج إلى PHP 8.1 أو أحدث. يأتي Ubuntu 24.04 مع PHP 8.3، لذلك تكفي حزم التوزيعة ولا تحتاج إلى مستودع PHP تابع لجهة خارجية.
ابدأ من حزمة 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 mariadbيجب أن يعرض systemctl 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، وإلى GMP في النظام ذي البنية 32 bit. في Ubuntu، تتوفر هذه الامتدادات على شكل حزم من التوزيعة:
sudo apt install -y php-curl php-mbstring php-xml php-zip php-mysql php-intl php-gmp
sudo systemctl restart apache2تحقق من الامتدادات التي حمّلها PHP فعلياً باستخدام php -m. لا تمنع الامتدادات المفقودة برنامج التثبيت من البدء. لكنها توقفه في شاشة المتطلبات، حيث يظهر سطر أحمر يذكر اسم الامتداد. اكتشاف المشكلة في هذه المرحلة مربك، لذلك تحقّق منها الآن. إعادة تشغيل Apache مهمة لأن libapache2-mod-php يبقي PHP داخل عملية Apache. لذلك لا يرى خادم الويب الامتداد المثبّت حديثاً حتى يُعاد تشغيله.
تنزيل الإصدار
ثبّت FreshRSS خارج جذر الويب الافتراضي، ووجّه Apache إليه. يضمن فصل مجلد التطبيق عن جذر المستندات أن يكون المجلد العام وحده قابلاً للوصول عبر HTTP.
cd /tmp
curl -fsSLO https://github.com/FreshRSS/FreshRSS/archive/refs/tags/1.30.4.tar.gz
tar xzf 1.30.4.tar.gz
sudo mv FreshRSS-1.30.4 /srv/freshrssطبّق الأذونات الآن. توثيق FreshRSS صارم بشأنها: يملك مستخدم خادم الويب شجرة الملفات، ويمكن للمجموعة قراءة كل ملف، ويمكنها الكتابة إلى ./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إذا تخطيت هذه الخطوة، يفشل برنامج التثبيت أثناء كتابة إعداداته، لأن PHP يعمل بصفة www-data، ولا يستطيع www-data الكتابة في مجلد يملكه root.
إنشاء قاعدة البيانات
يدعم FreshRSS قواعد بيانات SQLite وMariaDB وMySQL وPostgreSQL. يحتاج SQLite إلى الامتداد php-sqlite3، لكنه لا يتطلب إعداد خادم قاعدة بيانات، ويخزّن بيانات كل مستخدم في ملف data/users/_user_/db.sqlite منفصل. لا تؤدي إضافة المستخدمين إلى وضع كتاباتهم في ملف SQLite مشترك واحد؛ يستخدم هذا الدليل MariaDB ضمن حزمة LAMP.
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 القديم ذي الثلاث بايتات تخزين المحارف ذات الأربع بايتات. تؤدي المحارف غير المدعومة إلى حدوث خطأ في وضع MariaDB الصارم الافتراضي؛ ويعتمد الاقتطاع على وضع SQL وخيارات العبارة، مثل IGNORE.
مضيف 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 apache2يجب أن يطبع configtest القيمة Syntax OK. قد يبدو AllowEncodedSlashes On اختيارياً، لكنه ليس كذلك: ترسل Google Reader API معرّفات خلاصات تحتوي على %2F، ومن دون هذا التوجيه يرفض 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 إلى جدولة جلب الخلاصات؛ ومن دون جدولة، استخدم رابط التحديث في قائمة التنقل لجلب المقالات يدوياً. الحل هو البرنامج النصي الذي يوفّره المشروع لهذا الغرض، app/actualize_script.php، وتشغيله من cron.
sudo crontab -u www-data -eأضف سطراً واحداً:
*/20 * * * * php /srv/freshrss/app/actualize_script.php > /tmp/FreshRSS.log 2>&1تُعد مدة عشرين دقيقة جدولة مناسبة، لكن فترة التحديث الخاصة بكل خلاصة تظل مطبّقة؛ والقيمة الافتراضية هي ساعة واحدة، بينما تدعم الخلاصات الفردية فترات تصل إلى 15 دقيقة. شغّله يدوياً مرة أولاً:
sudo -u www-data php /srv/freshrss/app/actualize_script.phpيُظهر الخرج السليم تنفيذ عملية التحديث وينتهي من دون خطأ PHP؛ وتظهر أسماء الخلاصات عند إضافة المقالات أو تحديثها. إذا لم يطبع أي شيء على الإطلاق، فتحقق من خرج أخطاء PHP وسجلات FreshRSS؛ فالصمت وحده لا يحدد أن مستخدم cron هو السبب. يشير ظهور خطأ صلاحيات على data/ إلى ضرورة التحقق من الملكية وصلاحيات الكتابة.
أضف خلاصاتك الأولى
استخدم زر الإضافة في أعلى يسار الواجهة، والصق عنوان الموقع، وسيكتشف FreshRSS رابط الخلاصة نيابةً عنك. ما زالت معظم المواقع تنشر خلاصة حتى عندما لا تعلن عنها، وتكون عادةً على /feed أو /rss أو /atom.xml. الفئات مجلدات، ونقل خلاصة بينها يتم بالسحب.
إذا كنت تنتقل من قارئ آخر، فصدّر منه ملف OPML واستورده من صفحة إدارة الاشتراكات. OPML (outline processor markup language) هو التنسيق القياسي لقوائم الخلاصات، ويدعمه كل قارئ يستحق الانتقال إليه. يكون الاستيراد الكبير بطيئاً عند التحديث الأول لأن كل خلاصة تُجلب مرة واحدة، لذلك اترك مهمة cron الأولى تنتهي قبل تقييم السرعة.
اقرأه على هاتفك
يدعم FreshRSS واجهة Google Reader API، التي تدعمها العديد من تطبيقات RSS. يجب تحقق أمرين. في إعدادات المصادقة، يجب تفعيل الخيار "Allow API access"، وقد فعّلته راية --api-enabled أعلاه. في ملفك الشخصي، يجب أن يحتوي حقل كلمة مرور API على قيمة. وتختلف هذه الكلمة عمداً عن كلمة مرور تسجيل الدخول لأن فقدان الهاتف أسهل.
انتقل إلى https://rss.example.com/api/ لتشغيل فحوصات إعداد الخادم تلقائياً. يعرض الإعداد السليم النتيجة PASS. إذا فشل الفحص، فتحقق من إعداد AllowEncodedSlashes On في المضيف الافتراضي ومن الخطأ المبلّغ عنه. في التطبيق، أدخل عنوان الخادم على أنه https://rss.example.com/api/greader.php، واسم المستخدم على أنه مستخدم FreshRSS، وكلمة مرور API على أنها كلمة المرور.
بديل Docker
إذا كنت تفضّل عدم إدارة PHP وApache يدوياً، ينشر المشروع صورة freshrss/freshrss رسمية، ويوفّر ملف compose واحد التطبيق وقاعدة بياناته معاً. المقابل المعتاد هو عدد أقل من المكوّنات التي تديرها على الخادم، وطبقة إضافية واحدة لتشخيصها عند حدوث عطل، مع استمرار الحاجة إلى Reverse Proxy لتوفير TLS (أمان طبقة النقل). إذا كان هذا الخيار أنسب لك، يشرح دليل أساسيات Docker Compose لخادم VPS تنسيق الملف، ويصبح سطر cron هو docker exec --user www-data freshrss php ./app/actualize_script.php.
النسخ الاحتياطية والترقيات
هناك عنصران يحفظان حالتك: قاعدة البيانات و/srv/freshrss/data/. أنشئ تفريغاً للعنصر الأول باستخدام sudo mysqldump freshrss > freshrss.sql، وانسخ العنصر الثاني، واحتفظ بكليهما في مكان آخر غير هذا الخادم. تستحق قائمة الاشتراكات لديك أيضاً تصديراً دورياً بتنسيق OPML، لأن هذا الملف ينقل قائمة خلاصاتك إلى برامج قراءة أخرى تدعم OPML. لكنه لا يحفظ الإعدادات الخاصة بـFreshRSS، مثل تكرار التحديث وبيانات الاعتماد ووكيل المستخدم وقواعد كشط الويب باستخدام XPath؛ استخدم تصديراً لـSQLite لحفظ هذه الإعدادات أيضاً.
تتضمن الترقية فك حزمة إصدار أحدث فوق الدليل نفسه، ثم إعادة تشغيل أوامر الملكية. اتبع مسار الترقية الخاص بالمشروع من إصدار إلى آخر، وتحقق من FreshRSS بعد كل خطوة. يطبّق FreshRSS عمليات ترحيل قاعدة البيانات الخاصة به عند تحميل الصفحة التالية. أنشئ نسخة احتياطية أولاً، لأن فشل عملية الترحيل في قاعدة بيانات لا يمكنك استعادتها يتركك في وضع لا يمكن إصلاحه. إذا ثبّتَّ البرنامج من حزمة tarball قديمة مثل 1.29.1، فانتقل إلى 1.30.4: تتضمن إصدارات الأمان 1.30.x تدوير معرّف الجلسة عند تغيّر المصادقة، وتفرض حدوداً على عمليات استيراد ZIP، كما يحدّث الإصدار 1.30.4 صور Alpine البديلة لـDocker لمعالجة ثغرات PHP الخطيرة. تُعد خدمة قراءة الخلاصات منخفضة المخاطر عند تشغيلها، وهي مرشح جيد للبدء إذا كنت تعمل على قائمة بما يستحق الاستضافة الذاتية.
FAQ
لماذا لا تُحدَّث خلاصاتي إلا عند فتح FreshRSS؟
لا تؤدي عملية فتح الصفحة إلى جدولة جلب الخلاصات. ومن دون مجدول، استخدم رابط التحديث لتحديثها يدوياً. أضف سطر cron الذي يستدعي app/actualize_script.php باعتباره المستخدم www-data، ثم شغّل البرنامج النصي يدوياً مرة واحدة واقرأ ناتجه. إذا لم يعرض أي ناتج، فتحقق من مخرجات أخطاء PHP وسجلات FreshRSS، ثم تأكد من أن مستخدم cron يملك صلاحية الكتابة في data/.
لا يستطيع تطبيقي على الهاتف الاتصال، مع أن الموقع يعمل. ما السبب؟
تضع Google Reader API شرطات مائلة مُرمَّزة (%2F) داخل مسارات الطلبات، ويرفضها Apache افتراضياً. أضف AllowEncodedSlashes On داخل المضيف الافتراضي، ثم أعد تحميل Apache. أكّد إصلاح المشكلة بفتح https://rss.example.com/api/، حيث يفترض أن يعرض فحص الإعداد التلقائي PASS. تحقق أيضاً من ضبط كلمة مرور API في ملفك الشخصي، لأنها منفصلة عن كلمة مرور تسجيل الدخول.
هل أستخدم SQLite أم MariaDB؟
يتطلب SQLite الامتداد php-sqlite3، لكنه لا يحتاج إلى خادم قاعدة بيانات أو كلمة مرور لقاعدة البيانات لإدارتها. يحصل كل مستخدم على ملف قاعدة بيانات SQLite منفصل، لذلك لا تؤدي إضافة مستخدم ثانٍ إلى تنافس على ملف مشترك واحد، ولا تتطلب MariaDB. استخدم MariaDB إذا أردت استخدام خادم قاعدة البيانات في حزمة LAMP لديك. ويمكن الانتقال بينهما لاحقاً باستخدام أوامر التصدير والاستيراد، لذلك ليس هذا قراراً نهائياً.
يفشل برنامج التثبيت عند كتابة إعداداته. ما المشكلة؟
يعمل PHP باسم المستخدم www-data ضمن Apache، ولا يستطيع هذا المستخدم الكتابة في دليل يملكه root. أعد تشغيل sudo chown -R www-data:www-data /srv/freshrss وsudo chmod -R g+w /srv/freshrss/data، ثم ابدأ برنامج التثبيت مرة أخرى. إذا سبق أن شغّلت برنامج التثبيت عبر سطر الأوامر باسم root، فصحّح ملكية الملفات التي أنشأها ضمن data/ قبل إعادة المحاولة.
ما موارد الخادم التي يحتاج إليها قارئ RSS مستضاف ذاتياً؟
يحتاج إلى موارد قليلة جداً. صُمّم FreshRSS للعمل على عتاد متواضع، لكن استهلاك الموارد يعتمد على خلاصاتك وأحجام المقالات وإعدادات الاحتفاظ. يزداد حجم القرص مع مدة الاحتفاظ، لذلك عيّن سياسة لحذف المقالات في إعدادات الأرشفة بدلاً من الاحتفاظ بكل شيء إلى الأبد.