SSD Nodes Learn Hosting plans →
Guías Matt ConnorPor Matt Connor

Instalar FreshRSS en un VPS con Ubuntu 24.04

Instale FreshRSS 1.30.1 en Ubuntu 24.04 con Apache, PHP 8.3 y MariaDB. Incluye host virtual, cron de actualización y API para la aplicación móvil.

Lo que está construyendo

Un lector de RSS autohospedado es un lector de feeds que se ejecuta en un servidor de su propiedad, por lo que nadie puede cerrarlo ni cambiar lo que le muestra. Esta guía instala FreshRSS en un VPS con Ubuntu 24.04: Apache al frente, PHP detrás, MariaDB para el almacenamiento y una tarea cron que obtiene nuevos artículos. RSS (Really Simple Syndication) es el formato de archivo que publica un sitio para que el software pueda leer sus artículos. FreshRSS es la aplicación PHP que recopila esos archivos, guarda los artículos y le ofrece una interfaz web además de una API (interfaz de programación de aplicaciones) que utilizan las aplicaciones móviles.

La instalación en sí es pequeña: descomprima una versión, cree una base de datos, escriba un host virtual, ejecute el instalador de línea de comandos y luego cree la cuenta con cli/create-user.php. La mayor parte del trabajo a continuación es la parte que la gente suele hacer mal después: la tarea de actualización, las barras diagonales codificadas para la API móvil y la propiedad de los archivos.

FreshRSS 1.30.4, publicado el 21 de octubre de 2026, es la versión actual a fecha de 29 de octubre de 2026, y requiere PHP 8.1 o superior. Ubuntu 24.04 incluye PHP 8.3, por lo que los paquetes de la distribución son suficientes y no necesita un repositorio de PHP de terceros.

Comenzar con una pila LAMP operativa

FreshRSS es una aplicación PHP estándar, por lo que necesita la misma base que cualquier otra. Si todavía no ha configurado esa base, siga primero la configuración de la pila LAMP para Ubuntu 24.04 y vuelva aquí. En resumen:

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

systemctl status apache2 debería mostrar active (running). Si Apache no se inicia, la causa habitual es que otro proceso ya está utilizando el puerto 80; sudo ss -ltnp | grep :80 muestra cuál es.

Extensiones de PHP que necesita FreshRSS

FreshRSS considera obligatorias las extensiones libxml, cURL, JSON, PDO_MySQL, PCRE y ctype. También necesita mbstring, iconv, Zlib y ZipArchive, además de GMP en un sistema de 32 bits. En Ubuntu se instalan como paquetes de la distribución:

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

Compruebe qué extensiones ha cargado realmente PHP con php -m. Si falta una extensión, el instalador no deja de iniciarse. Se detiene en la pantalla de requisitos y muestra una línea roja con el nombre de la extensión. Es un lugar confuso para descubrir el problema, por lo que debe comprobarlo ahora. Reiniciar Apache es importante porque libapache2-mod-php mantiene PHP dentro del proceso de Apache. Por eso, una extensión recién instalada no está disponible para el servidor web hasta que se reinicia.

Descargar la versión

Instale FreshRSS fuera de la raíz web predeterminada y apunte Apache hacia ella. Mantener el directorio de la aplicación separado de la raíz del documento garantiza que solo la carpeta pública sea accesible mediante 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

Ahora los permisos, sobre los cuales la documentación de FreshRSS es estricta: el usuario del servidor web debe ser el propietario del árbol, el grupo debe poder leer todos los archivos y el grupo debe tener permisos de escritura en ./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

Si omite este paso, el instalador fallará al intentar escribir su configuración, ya que PHP se ejecuta como www-data y www-data no puede escribir en un directorio cuyo propietario es root.

Crear la base de datos

FreshRSS es compatible con SQLite, MariaDB, MySQL y PostgreSQL. SQLite requiere la extensión php-sqlite3, pero no necesita configurar un servidor de base de datos y almacena los datos de cada usuario en un archivo data/users/_user_/db.sqlite independiente. Añadir usuarios no combina sus escrituras en un único archivo SQLite compartido; esta guía utiliza MariaDB como parte de la pila 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;"

Utilice utf8mb4 y no utf8. Los feeds contienen emojis y alfabetos no latinos, y la codificación antigua de tres bytes utf8 no puede almacenar caracteres de cuatro bytes. Los caracteres no admitidos provocan un error bajo el modo estricto predeterminado de MariaDB; el truncamiento depende del modo SQL y de las opciones de sentencia como IGNORE.

El host virtual de Apache

El directorio público es p/, no la raíz del árbol. Todo lo demás, incluido el archivo de configuración que contiene la contraseña de la base de datos, se encuentra por encima de la raíz de documentos, donde Apache nunca lo servirá.

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

Guárdalo como /etc/apache2/sites-available/freshrss.conf y actívalo:

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

configtest debería mostrar Syntax OK. AllowEncodedSlashes On parece opcional, pero no lo es: la API de Google Reader envía identificadores de feeds que contienen %2F y, sin esta directiva, Apache los rechaza. Por eso las aplicaciones móviles no pueden sincronizarse, mientras que la interfaz web funciona correctamente.

Añade HTTPS antes de iniciar sesión

Vas a escribir una contraseña en este sitio, así que obtén primero un certificado. Apunta un registro A al servidor, sigue la configuración de Certbot para Apache en Ubuntu y ejecuta sudo certbot --apache -d rss.example.com. Certbot reescribe el host virtual para el puerto 443 y añade la redirección. Confírmalo con curl -I https://rss.example.com/, que debería devolver un 200 o redirigir a la página de inicio de sesión.

Ejecute el instalador desde la línea de comandos

FreshRSS tiene un instalador en el navegador, pero la versión de línea de comandos se puede repetir y deja un registro exacto de las opciones seleccionadas.

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'

Ejecute ambos como www-data. Si los ejecuta como root, se crean archivos de configuración propiedad de root y la interfaz web no puede guardar ninguna configuración posteriormente. --environment production también es importante, porque la configuración de desarrollo muestra avisos de PHP en la página.

Cargue https://rss.example.com/ e inicie sesión como admin.

Por qué los feeds no se actualizan por sí solos

Nada consulta sus feeds hasta que usted lo indica. Abrir FreshRSS no programa la obtención de feeds; sin un planificador, utilice el enlace de actualización en el menú de navegación para obtener artículos manualmente. La solución es el script que el proyecto distribuye para esto, app/actualize_script.php, ejecutado desde cron.

sudo crontab -u www-data -e

Añada una línea:

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

Veinte minutos es una programación razonable, pero el intervalo de actualización de cada feed sigue aplicándose: el valor predeterminado es una hora, y los feeds individuales admiten intervalos desde quince minutos. Ejecútelo primero una vez manualmente:

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

Una salida correcta informa sobre la ejecución de la actualización y termina sin errores de PHP; los nombres de los feeds aparecen cuando se añaden o actualizan artículos. Si no imprime nada, revise la salida de errores de PHP y los registros de FreshRSS; el silencio por sí solo no identifica al usuario de cron como la causa. Un error de permisos en data/ requiere comprobar la propiedad y los permisos de escritura.

Agrega tus primeros feeds

Usa el botón de suma situado en la parte superior izquierda de la interfaz, pega la dirección de un sitio y FreshRSS buscará el enlace del feed. La mayoría de los sitios todavía publican uno aunque no lo anuncien, normalmente en /feed, /rss o /atom.xml. Las categorías son carpetas y mover un feed entre ellas se hace mediante arrastrar y soltar.

Si vienes de otro lector, exporta allí un archivo OPML e impórtalo desde la página de administración de suscripciones. OPML (outline processor markup language) es el formato estándar para las listas de feeds, y todos los lectores que merece la pena usar admiten este formato. Una importación grande es lenta durante la primera actualización porque se obtiene cada feed una vez. Espera a que se ejecute el primer cron antes de evaluar la velocidad.

Léalo en su teléfono

FreshRSS utiliza la API de Google Reader, la cual es compatible con muchas aplicaciones de RSS. Deben cumplirse dos condiciones. En la configuración de autenticación, la opción "Allow API access" debe estar activada, lo cual ya se configuró con el flag --api-enabled anterior. En su perfil, el campo de contraseña de la API debe contener un valor; este es distinto a su contraseña de inicio de sesión por seguridad, ya que un teléfono es un dispositivo que se pierde con facilidad.

Visite https://rss.example.com/api/ para ejecutar las comprobaciones de configuración del servidor de forma automática. Una instalación correcta devuelve PASS. Si la comprobación falla, revise el ajuste AllowEncodedSlashes On del host virtual y el error reportado. En la aplicación, introduzca la dirección del servidor como https://rss.example.com/api/greader.php, el nombre de usuario como su usuario de FreshRSS y la contraseña de la API como contraseña.

La alternativa con Docker

Si prefiere no mantener PHP y Apache manualmente, el proyecto publica una imagen oficial de freshrss/freshrss y un archivo de compose le proporciona la aplicación y su base de datos juntas. La contrapartida es la habitual: menos componentes que mantener en el host, una capa adicional que depurar cuando algo falla y la necesidad de usar un proxy inverso para TLS (seguridad de la capa de transporte). Si esta opción se adapta mejor a sus necesidades, los conceptos básicos de Docker Compose para un VPS explican el formato del archivo, y la línea de cron se convierte en docker exec --user www-data freshrss php ./app/actualize_script.php.

Copias de seguridad y actualizaciones

Dos elementos mantienen su estado: la base de datos y /srv/freshrss/data/. Realice un volcado de la primera con sudo mysqldump freshrss > freshrss.sql, copie el segundo y almacene ambos en un lugar distinto a este servidor. Su lista de suscripciones también merece una exportación OPML ocasional, ya que ese archivo transfiere su lista de feeds a otros lectores compatibles con OPML. No conserva los ajustes específicos de FreshRSS como la frecuencia de actualización, credenciales, user agent o reglas de scraping web XPath; utilice una exportación de SQLite para preservar también esos datos.

Actualizar consiste en descomprimir una versión más reciente sobre el mismo directorio y volver a ejecutar los comandos de propiedad. Siga la ruta de actualización versión por versión del proyecto y verifique FreshRSS después de cada paso. FreshRSS aplica sus propias migraciones de base de datos al cargar la página siguiente. Realice una copia de seguridad primero, ya que una migración fallida en una base de datos que no puede restaurar es una situación irrecuperable. Si instaló desde un tarball antiguo como 1.29.1, pase a 1.30.4: las versiones de seguridad 1.30.x incluyen la rotación de ID de sesión en los cambios de autenticación y límites en las importaciones ZIP, mientras que la 1.30.4 también actualiza las imágenes alternativas de Docker Alpine ante vulnerabilidades graves de PHP. Un lector es un servicio de bajo riesgo y un buen primer candidato si está trabajando en una lista de lo que merece la pena autohospedar.

FAQ

¿Por qué mis feeds solo se actualizan cuando abro FreshRSS?

Abrir la página no programa la obtención de feeds; sin un programador, utilice el enlace de actualización para refrescar manualmente. Añada la línea de cron que llama a app/actualize_script.php como el usuario www-data, luego ejecute el script manualmente una vez y lea su salida. Si no muestra nada, revise la salida de errores de PHP y los registros de FreshRSS, y verifique que el usuario de cron tenga permisos de escritura en data/.

Mi aplicación móvil no puede conectarse, pero el sitio web funciona. ¿Por qué?

La API de Google Reader coloca barras inclinadas codificadas (%2F) dentro de las rutas de las peticiones, y Apache las rechaza de forma predeterminada. Añada AllowEncodedSlashes On dentro del virtual host y recargue Apache. Confirme la corrección abriendo https://rss.example.com/api/, donde la comprobación automática de configuración debería informar PASS. Compruebe también que la contraseña de la API esté configurada en su perfil, ya que es distinta a su contraseña de inicio de sesión.

¿Debo usar SQLite o MariaDB?

SQLite necesita la extensión php-sqlite3, pero no requiere un servidor de base de datos ni una contraseña de base de datos que gestionar. Cada usuario obtiene un archivo de base de datos SQLite independiente, por lo que añadir un segundo usuario no crea conflictos en un archivo compartido ni requiere MariaDB. Use MariaDB si desea utilizar el servidor de base de datos en su stack LAMP. Es posible migrar entre ambos más adelante mediante los comandos de exportación e importación, por lo que no es una decisión permanente.

El instalador falla al escribir su configuración. ¿Qué ocurre?

PHP se ejecuta como www-data bajo Apache, y ese usuario no puede escribir en un directorio propiedad de root. Vuelva a ejecutar sudo chown -R www-data:www-data /srv/freshrss y sudo chmod -R g+w /srv/freshrss/data, luego inicie el instalador de nuevo. Si ya ejecutó el instalador de línea de comandos como root, corrija la propiedad de los archivos que creó bajo data/ antes de reintentar.

¿Qué potencia de servidor necesita un lector de RSS autohospedado?

Muy poca. FreshRSS está diseñado para ejecutarse en hardware modesto, pero el uso de recursos depende de sus feeds, el tamaño de los artículos y los ajustes de retención. El disco crece con la retención, así que establezca una política de purga de artículos en los ajustes de archivado en lugar de conservarlo todo indefinidamente.

¿Te resultó útil este artículo?