SSD Nodes Learn Hosting plans →
Panduan Matt ConnorOleh Matt Connor · Diperbarui 2026-08-07

Instal FreshRSS di VPS Ubuntu 24.04

Pasang FreshRSS 1.29.1 di VPS Ubuntu 24.04 dengan Apache, PHP 8.3, dan MariaDB, lalu atur virtual host, cron refresh, serta API aplikasi seluler.

Yang Anda bangun

Pembaca RSS yang di-host sendiri adalah pembaca feed yang berjalan di server milik Anda, sehingga tidak ada pihak lain yang dapat mematikannya atau mengubah konten yang ditampilkan. Panduan ini memasang FreshRSS pada VPS Ubuntu 24.04: Apache di bagian depan, PHP di belakangnya, MariaDB untuk penyimpanan, dan satu cron job untuk mengambil artikel baru. RSS (really simple syndication) adalah format file yang diterbitkan situs agar perangkat lunak dapat membaca artikelnya. FreshRSS adalah aplikasi PHP yang mengumpulkan file tersebut, menyimpan artikel, serta menyediakan antarmuka web dan API (application programming interface) yang digunakan aplikasi ponsel.

Proses instalasinya singkat: ekstrak sebuah release, buat database, tulis satu virtual host, lalu jalankan satu command line installer. Sebagian besar pekerjaan di bawah ini berkaitan dengan hal-hal yang sering salah setelah instalasi, yaitu refresh job, encoded slashes untuk API seluler, dan kepemilikan file.

FreshRSS 1.29.1 adalah release terbaru per Juli 2026, dan memerlukan PHP 8.1 atau yang lebih baru. Ubuntu 24.04 menyediakan PHP 8.3, sehingga package dari distribusi sudah mencukupi dan Anda tidak memerlukan repository PHP pihak ketiga.

Mulai dari LAMP stack yang berfungsi

FreshRSS adalah aplikasi PHP biasa, sehingga memerlukan fondasi yang sama seperti aplikasi PHP lainnya. Jika Anda belum menyiapkan fondasi tersebut, ikuti penyiapan LAMP stack untuk Ubuntu 24.04 terlebih dahulu, lalu kembali ke sini. Ringkasnya:

sudo apt update
sudo apt install -y apache2 mariadb-server php libapache2-mod-php
sudo systemctl enable --now apache2 mariadb

systemctl status apache2 harus menampilkan active (running). Jika Apache tidak dapat dijalankan, penyebab yang umum adalah proses lain sudah menggunakan port 80, dan sudo ss -ltnp | grep :80 menampilkan proses tersebut.

Ekstensi PHP yang diperlukan FreshRSS

FreshRSS menganggap libxml, cURL, JSON, PDO_MySQL, PCRE, dan ctype sebagai ekstensi wajib. FreshRSS juga memerlukan mbstring, iconv, Zlib, dan ZipArchive, serta GMP pada sistem 32 bit. Di Ubuntu, ekstensi tersebut tersedia sebagai paket distribusi:

sudo apt install -y php-curl php-mbstring php-xml php-zip php-mysql php-intl php-gmp
sudo systemctl restart apache2

Periksa ekstensi yang benar-benar dimuat PHP dengan php -m. Ekstensi yang hilang tidak mencegah installer berjalan. Installer akan berhenti pada layar persyaratan dan menampilkan baris merah yang menyebutkan ekstensi tersebut. Menemukan masalah di tahap ini dapat membingungkan, jadi lakukan pemeriksaan sekarang. Restart Apache penting karena libapache2-mod-php menjalankan PHP di dalam proses Apache. Dengan demikian, web server tidak akan melihat ekstensi yang baru diinstal sebelum Apache direstart.

Unduh rilis

Instal FreshRSS di luar root web default, lalu arahkan Apache ke sana. Dengan memisahkan direktori aplikasi dari document root, hanya folder publik yang dapat diakses melalui 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

Berikutnya, atur izin akses sesuai ketentuan ketat dalam dokumentasi FreshRSS: pengguna web server menjadi pemilik seluruh hierarki direktori, grup dapat membaca setiap file, dan grup dapat menulis ke ./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

Jika langkah ini dilewati, installer gagal saat menulis konfigurasinya karena PHP berjalan sebagai www-data dan www-data tidak dapat menulis ke direktori yang dimiliki oleh root.

Buat database

FreshRSS mendukung SQLite, MariaDB, MySQL, dan PostgreSQL. SQLite tidak memerlukan penyiapan dan cocok untuk satu orang dengan beberapa ratus feed. MariaDB merupakan pilihan yang lebih baik jika beberapa orang menggunakan instance yang sama, karena penulisan secara bersamaan dari tugas refresh dan antarmuka web tidak lagi bersaing untuk mendapatkan satu file lock.

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;"

Gunakan utf8mb4, bukan utf8. Feed dapat berisi emoji dan skrip non-Latin, sedangkan encoding utf8 lama dengan tiga byte akan memotong judul artikel pada karakter pertama yang menggunakan empat byte.

Virtual host Apache

Direktori publik adalah p/, bukan direktori teratas dalam hierarki. Semua yang lain, termasuk file konfigurasi yang menyimpan kata sandi database Anda, berada di atas document root sehingga Apache tidak akan pernah menyajikannya.

<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>

Simpan sebagai /etc/apache2/sites-available/freshrss.conf, lalu aktifkan:

sudo a2enmod rewrite
sudo a2ensite freshrss
sudo a2dissite 000-default
sudo apache2ctl configtest
sudo systemctl reload apache2

configtest harus menampilkan Syntax OK. AllowEncodedSlashes On tampak opsional, tetapi sebenarnya tidak. Google Reader API mengirimkan pengenal feed yang berisi %2F. Tanpa directive ini, Apache menolaknya sehingga aplikasi seluler gagal melakukan sinkronisasi, sementara antarmuka web tetap berfungsi dengan sempurna.

Tambahkan HTTPS sebelum login

Anda akan memasukkan kata sandi ke situs ini, jadi dapatkan sertifikat terlebih dahulu. Arahkan A record ke server, lalu ikuti penyiapan Certbot untuk Apache di Ubuntu dan jalankan sudo certbot --apache -d rss.example.com. Certbot menulis ulang virtual host untuk port 443 dan menambahkan pengalihan. Konfirmasikan dengan curl -I https://rss.example.com/, yang seharusnya mengembalikan 200 atau pengalihan ke halaman login.

Jalankan installer dari command line

FreshRSS memiliki installer berbasis browser, tetapi versi command line dapat dijalankan berulang kali dan mencatat pilihan Anda secara tepat.

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'

Jalankan keduanya sebagai www-data. Jika dijalankan sebagai root, installer akan membuat file konfigurasi yang dimiliki root. Akibatnya, antarmuka web tidak dapat menyimpan pengaturan apa pun di kemudian hari. --environment production juga penting karena pengaturan pengembangan menampilkan notifikasi PHP pada halaman.

Muat https://rss.example.com/ dan login sebagai admin.

Mengapa feed tidak diperbarui sendiri

Tidak ada proses yang memeriksa feed sampai Anda mengaturnya. FreshRSS memperbarui feed saat browser sedang terbuka pada halaman tersebut. Akibatnya, instance yang Anda kunjungi dua kali sehari menampilkan artikel yang sudah kedaluwarsa selama dua belas jam. Solusinya adalah skrip yang disediakan project untuk keperluan ini, app/actualize_script.php, yang dijalankan melalui cron.

sudo crontab -u www-data -e

Tambahkan satu baris:

*/20 * * * * php /srv/freshrss/app/actualize_script.php > /tmp/FreshRSS.log 2>&1

Dua puluh menit adalah interval minimum yang wajar. Skrip menolak memperbarui satu feed lebih sering daripada sekali setiap dua puluh menit. Jadwal yang lebih rapat hanya memboroskan CPU. Jalankan skrip sekali secara manual terlebih dahulu:

sudo -u www-data php /srv/freshrss/app/actualize_script.php

Output yang normal mencantumkan setiap feed yang berhasil diambil dan berakhir tanpa error PHP. Jika tidak menampilkan apa pun, berarti pengguna cron salah. Jika muncul error izin pada data/, berarti langkah chmod -R g+w dilewati.

Tambahkan feed pertama Anda

Gunakan tombol plus di kiri atas antarmuka, tempelkan alamat situs, dan FreshRSS akan menemukan tautan feed untuk Anda. Sebagian besar situs tetap menerbitkan feed meskipun tidak menampilkannya secara jelas, biasanya di /feed, /rss, atau /atom.xml. Kategori berfungsi sebagai folder, dan Anda dapat memindahkan feed antar-kategori dengan menyeretnya.

Jika Anda menggunakan reader lain, ekspor file OPML dari sana, lalu impor file tersebut pada halaman pengelolaan langganan. OPML (outline processor markup language) adalah format standar untuk daftar feed, dan setiap reader yang layak ditinggalkan mendukungnya. Impor dalam jumlah besar akan lambat saat refresh pertama karena setiap feed diambil satu kali. Jadi, tunggu cron berjalan pertama kali sebelum menilai kecepatannya.

Baca di ponsel

FreshRSS mendukung Google Reader API, yang didukung oleh hampir semua aplikasi RSS. Dua hal harus terpenuhi. Pada pengaturan autentikasi, "Allow API access" harus aktif. Flag --api-enabled di atas sudah mengaktifkannya. Pada profil Anda, kolom kata sandi API harus berisi nilai. Kata sandi ini sengaja dipisahkan dari kata sandi login karena ponsel lebih mudah hilang.

Buka https://rss.example.com/api/, lalu pilih "Check full server configuration". Konfigurasi yang berfungsi mengembalikan PASS. Kegagalan pada tahap ini hampir selalu disebabkan oleh baris AllowEncodedSlashes On yang belum ada. Di aplikasi, masukkan alamat server sebagai https://rss.example.com/api/greader.php, nama pengguna sebagai pengguna FreshRSS Anda, dan kata sandi API sebagai kata sandi.

Alternatif Docker

Jika Anda tidak ingin memelihara PHP dan Apache secara manual, proyek ini menyediakan image freshrss/freshrss resmi, dan satu file compose menyediakan aplikasi beserta database-nya. Konsekuensinya sama seperti biasa: lebih sedikit komponen yang perlu dikelola pada host, tetapi ada satu lapisan tambahan yang harus di-debug saat terjadi masalah. Reverse proxy tetap diperlukan untuk TLS (transport layer security). Jika pendekatan ini lebih sesuai bagi Anda, dasar-dasar Docker Compose untuk VPS menjelaskan format file tersebut, dan baris cron-nya menjadi docker exec --user www-data freshrss php ./app/actualize_script.php.

Cadangan dan upgrade

Dua hal menyimpan state Anda: database dan /srv/freshrss/data/. Buat dump database dengan sudo mysqldump freshrss > freshrss.sql, salin /srv/freshrss/data/, lalu simpan keduanya di lokasi selain server ini. Daftar subscription Anda juga sebaiknya sesekali diekspor ke format OPML, karena file tersebut dapat membangun ulang konfigurasi bacaan Anda pada perangkat lunak RSS apa pun.

Upgrade dilakukan dengan mengekstrak release yang lebih baru ke direktori yang sama, lalu menjalankan kembali perintah ownership. FreshRSS menerapkan migrasi database-nya sendiri saat halaman berikutnya dimuat. Buat cadangan terlebih dahulu, karena migrasi yang gagal pada database yang tidak dapat dipulihkan akan menempatkan Anda dalam kondisi yang tidak dapat dipulihkan. Reader adalah service berisiko rendah untuk dijalankan dan kandidat yang baik untuk dicoba terlebih dahulu jika Anda sedang meninjau daftar hal yang layak di-self-host.

FAQ

Mengapa feed saya hanya diperbarui saat saya membuka FreshRSS?

Karena belum ada scheduler sampai Anda membuatnya. FreshRSS memperbarui feed saat sesi browser terbuka dan tidak melakukan apa pun saat tab ditutup. Tambahkan baris cron yang memanggil app/actualize_script.php sebagai pengguna www-data, lalu jalankan skrip tersebut secara manual sekali dan baca outputnya. Tidak adanya output biasanya berarti cron menjalankannya sebagai pengguna yang salah, sehingga PHP tidak dapat menulis ke data/.

Mengapa aplikasi seluler saya tidak dapat terhubung, tetapi situs web berfungsi?

Google Reader API menempatkan slash yang dienkode (%2F) di dalam path permintaan, dan Apache menolaknya secara default. Tambahkan AllowEncodedSlashes On di dalam virtual host, lalu muat ulang Apache. Konfirmasikan perbaikannya dengan membuka https://rss.example.com/api/ dan menjalankan "Check full server configuration", yang seharusnya melaporkan PASS. Periksa juga apakah kata sandi API telah ditetapkan di profil Anda, karena kata sandi tersebut terpisah dari kata sandi login.

Sebaiknya saya menggunakan SQLite atau MariaDB?

Gunakan SQLite untuk satu pengguna karena tidak ada yang perlu diinstal dan tidak ada kata sandi yang perlu dikelola. Gunakan MariaDB jika lebih dari satu orang membaca pada instance tersebut, atau jika jumlah feed melebihi beberapa ratus, karena tugas pembaruan dan antarmuka web menulis secara bersamaan dan satu file lock menjadi batasnya. Anda dapat berpindah di antara keduanya nanti melalui perintah ekspor dan impor, jadi ini bukan keputusan permanen.

Penginstal gagal saat menulis konfigurasinya. Apa masalahnya?

PHP berjalan sebagai www-data di bawah Apache, dan pengguna tersebut tidak dapat menulis ke direktori milik root. Jalankan kembali sudo chown -R www-data:www-data /srv/freshrss dan sudo chmod -R g+w /srv/freshrss/data, lalu mulai penginstal lagi. Jika Anda sudah menjalankan penginstal baris perintah sebagai root, hapus file yang dibuatnya di bawah data/ sebelum mencoba lagi, karena kepemilikan file tersebut adalah masalah sebenarnya.

Berapa banyak sumber daya server yang dibutuhkan pembaca RSS yang di-host sendiri?

Sangat sedikit. Beberapa ratus feed pada paket kecil sudah memadai, karena bebannya berupa lonjakan singkat pengambilan HTTP setiap dua puluh menit dan ukuran database tetap kecil setelah artikel lama dihapus. Penggunaan disk bertambah sesuai retensi, jadi tetapkan kebijakan penghapusan artikel di pengaturan pengarsipan daripada menyimpan semuanya selamanya.